mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[fineoffsetweatherstation] Add support for the new GW2001 weather station (#13283)
* [fineoffsetweatherstation] add support for the new GW2001 weather station with its WH90 sensor * [fineoffsetweatherstation] add missing channel labels * [fineoffsetweatherstation] remove redundant translations * [fineoffsetweatherstation] add test data + fix for WH90 * [fineoffsetweatherstation] fix wrong size for `CMD_READ_RAIN` Signed-off-by: Andreas Berger <andreas@berger-freelancer.com>
This commit is contained in:
parent
a2e0d23297
commit
4331c5f3ed
@ -23,7 +23,7 @@ This binding works offline by [implementing the wire protocol](https://osswww.ec
|
||||
|
||||
## Supported Things
|
||||
|
||||
- `weatherstation`: A Fine Offset gateway device with the ThingTypeUID `fineoffsetweatherstation:weatherstation` wich supports the [wire protocol](https://osswww.ecowitt.net/uploads/20210716/WN1900%20GW1000,1100%20WH2680,2650%20telenet%20v1.6.0%20.pdf) e.g.:
|
||||
- `weatherstation`: A Fine Offset gateway device with the ThingTypeUID `fineoffsetweatherstation:weatherstation` which supports the [wire protocol](https://osswww.ecowitt.net/uploads/20220407/WN1900%20GW1000,1100%20WH2680,2650%20telenet%20v1.6.4.pdf) e.g.:
|
||||
- HP2550
|
||||
- HP3500
|
||||
- GW1000
|
||||
@ -31,6 +31,7 @@ This binding works offline by [implementing the wire protocol](https://osswww.ec
|
||||
- GW1002
|
||||
- GW1003
|
||||
- GW1100
|
||||
- GW2001
|
||||
- WN1900
|
||||
- WN1910
|
||||
- WH2350
|
||||
@ -42,6 +43,7 @@ This binding works offline by [implementing the wire protocol](https://osswww.ec
|
||||
- WH2900
|
||||
- WH2950
|
||||
- WS980 ELV (tested)
|
||||
- WittBoy (tested)
|
||||
- `sensor`: A Fine Offset sensor which is connected to the bridge with the ThingTypeUID `fineoffsetweatherstation:sensor`.
|
||||
Since the gateway collects all the sensor data and harmonizes them, the sensor thing itself will only hold information about the signal and battery status.
|
||||
This is a list of sensors supported by the protocol:
|
||||
@ -60,7 +62,7 @@ This binding works offline by [implementing the wire protocol](https://osswww.ec
|
||||
- WH65 - 7-in-1 weather station for wind speed & direction, solar radiation & light, temperature, humidity and rainfall
|
||||
- WH68 - 4-in-1 weather station - Solar-powered sensor for wind speed & direction, solar radiation & light
|
||||
- WH80 - 6-in-1 weather station - Ultrasonic sensor for wind speed & direction, solar radiation & light, temperature & humidity
|
||||
- WH90 - A new weather station
|
||||
- WH90 - 7-in-1 weather station - Ultrasonic sensor for wind speed & direction, solar radiation & light, temperature, humidity and haptic rainfall Sensor
|
||||
|
||||
### Unsupported Devices
|
||||
|
||||
@ -263,6 +265,13 @@ Valid sensors:
|
||||
| leaf-wetness-channel-6 | Number:Dimensionless | R | Leaf Moisture Channel 6 |
|
||||
| leaf-wetness-channel-7 | Number:Dimensionless | R | Leaf Moisture Channel 7 |
|
||||
| leaf-wetness-channel-8 | Number:Dimensionless | R | Leaf Moisture Channel 8 |
|
||||
| piezo-rain-rate | Number:VolumetricFlowRate | R | Piezo - Rainfall Rate |
|
||||
| piezo-rain-event | Number:Length | R | Piezo - Amount of Rainfall At the last Rain |
|
||||
| piezo-rain-hour | Number:Length | R | Piezo - Rainfall Current Hour |
|
||||
| piezo-rain-day | Number:Length | R | Piezo - Rainfall Today |
|
||||
| piezo-rain-week | Number:Length | R | Piezo - Rainfall this Week |
|
||||
| piezo-rain-month | Number:Length | R | Piezo - Rainfall this Month |
|
||||
| piezo-rain-year | Number:Length | R | Piezo - Rainfall this Year |
|
||||
|
||||
### `sensor` Channels
|
||||
|
||||
|
@ -26,11 +26,6 @@
|
||||
<name>openHAB Add-ons :: Bundles :: Fine Offset Weather Station</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-csv</artifactId>
|
||||
<version>1.9.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
|
@ -26,7 +26,6 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -200,7 +199,7 @@ public class FineOffsetGatewayDiscoveryService extends AbstractDiscoveryService
|
||||
for (Protocol protocol : Protocol.values()) {
|
||||
try (GatewayQueryService gatewayQueryService = protocol.getGatewayQueryService(config, null,
|
||||
conversionContext)) {
|
||||
List<MeasuredValue> result = gatewayQueryService.getMeasuredValues();
|
||||
Collection<MeasuredValue> result = gatewayQueryService.getMeasuredValues();
|
||||
logger.trace("found {} measured values via protocol {}", result.size(), protocol);
|
||||
if (!result.isEmpty()) {
|
||||
return protocol;
|
||||
|
@ -231,7 +231,17 @@ public enum Command {
|
||||
/**
|
||||
* write back rain reset time
|
||||
*/
|
||||
CMD_WRITE_RSTRAIN_TIME((byte) 0x56, 1);
|
||||
CMD_WRITE_RSTRAIN_TIME((byte) 0x56, 1),
|
||||
|
||||
/**
|
||||
* read rain data including piezo (wh90)
|
||||
*/
|
||||
CMD_READ_RAIN((byte) 0x57, 2),
|
||||
|
||||
/**
|
||||
* write rain data
|
||||
*/
|
||||
CMD_WRITE_RAIN((byte) 0x58, 1);
|
||||
|
||||
private final byte code;
|
||||
private final int sizeBytes;
|
||||
|
@ -0,0 +1,344 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.fineoffsetweatherstation.internal.domain;
|
||||
|
||||
import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_MAX_WIND_SPEED;
|
||||
import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_MOISTURE;
|
||||
import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_UV_INDEX;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.MeasuredValue;
|
||||
import org.openhab.core.thing.DefaultSystemChannelTypeProvider;
|
||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* The measurands of supported by the gateway.
|
||||
*
|
||||
* @author Andreas Berger - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum Measurand {
|
||||
|
||||
INTEMP("temperature-indoor", 0x01, "Indoor Temperature", MeasureType.TEMPERATURE,
|
||||
DefaultSystemChannelTypeProvider.SYSTEM_CHANNEL_TYPE_UID_INDOOR_TEMPERATURE),
|
||||
|
||||
OUTTEMP("temperature-outdoor", 0x02, "Outdoor Temperature", MeasureType.TEMPERATURE,
|
||||
DefaultSystemChannelTypeProvider.SYSTEM_CHANNEL_TYPE_UID_OUTDOOR_TEMPERATURE),
|
||||
|
||||
DEWPOINT("temperature-dew-point", 0x03, "Dew point", MeasureType.TEMPERATURE),
|
||||
|
||||
WINDCHILL("temperature-wind-chill", 0x04, "Wind chill", MeasureType.TEMPERATURE),
|
||||
|
||||
HEATINDEX("temperature-heat-index", 0x05, "Heat index", MeasureType.TEMPERATURE),
|
||||
|
||||
INHUMI("humidity-indoor", 0x06, "Indoor Humidity", MeasureType.PERCENTAGE),
|
||||
|
||||
OUTHUMI("humidity-outdoor", 0x07, "Outdoor Humidity", MeasureType.PERCENTAGE,
|
||||
DefaultSystemChannelTypeProvider.SYSTEM_CHANNEL_TYPE_UID_ATMOSPHERIC_HUMIDITY),
|
||||
|
||||
ABSBARO("pressure-absolute", 0x08, "Absolutely pressure", MeasureType.PRESSURE),
|
||||
|
||||
RELBARO("pressure-relative", 0x09, "Relative pressure", MeasureType.PRESSURE,
|
||||
DefaultSystemChannelTypeProvider.SYSTEM_CHANNEL_TYPE_UID_BAROMETRIC_PRESSURE),
|
||||
|
||||
WINDDIRECTION("direction-wind", 0x0A, "Wind Direction", MeasureType.DEGREE,
|
||||
DefaultSystemChannelTypeProvider.SYSTEM_CHANNEL_TYPE_UID_WIND_DIRECTION),
|
||||
|
||||
WINDSPEED("speed-wind", 0x0B, "Wind Speed", MeasureType.SPEED,
|
||||
DefaultSystemChannelTypeProvider.SYSTEM_CHANNEL_TYPE_UID_WIND_SPEED),
|
||||
|
||||
GUSTSPEED("speed-gust", 0x0C, "Gust Speed", MeasureType.SPEED,
|
||||
DefaultSystemChannelTypeProvider.SYSTEM_CHANNEL_TYPE_UID_WIND_SPEED),
|
||||
|
||||
RAINEVENT("rain-event", 0x0D, "Rain Event", MeasureType.HEIGHT,
|
||||
new ParserCustomization(ParserCustomizationType.ELV, MeasureType.HEIGHT_BIG)),
|
||||
|
||||
RAINRATE("rain-rate", 0x0E, "Rain Rate", MeasureType.HEIGHT_PER_HOUR,
|
||||
new ParserCustomization(ParserCustomizationType.ELV, MeasureType.HEIGHT_PER_HOUR_BIG)),
|
||||
|
||||
RAINHOUR("rain-hour", 0x0F, "Rain hour", MeasureType.HEIGHT,
|
||||
new ParserCustomization(ParserCustomizationType.ELV, MeasureType.HEIGHT_BIG)),
|
||||
|
||||
RAINDAY("rain-day", 0x10, "Rain Day", MeasureType.HEIGHT,
|
||||
new ParserCustomization(ParserCustomizationType.ELV, MeasureType.HEIGHT_BIG),
|
||||
new ParserCustomization(ParserCustomizationType.RAIN_READING, MeasureType.HEIGHT_BIG)),
|
||||
|
||||
RAINWEEK("rain-week", 0x11, "Rain Week", MeasureType.HEIGHT,
|
||||
new ParserCustomization(ParserCustomizationType.ELV, MeasureType.HEIGHT_BIG),
|
||||
new ParserCustomization(ParserCustomizationType.RAIN_READING, MeasureType.HEIGHT_BIG)),
|
||||
|
||||
RAINMONTH("rain-month", 0x12, "Rain Month", MeasureType.HEIGHT_BIG),
|
||||
|
||||
RAINYEAR("rain-year", 0x13, "Rain Year", MeasureType.HEIGHT_BIG),
|
||||
|
||||
RAINTOTALS("rain-total", 0x14, "Rain Totals", MeasureType.HEIGHT_BIG),
|
||||
|
||||
LIGHT("illumination", 0x15, "Light", MeasureType.LUX),
|
||||
|
||||
UV("irradiation-uv", 0x16, "UV", MeasureType.MILLIWATT_PER_SQUARE_METRE),
|
||||
|
||||
UVI("uv-index", 0x17, "UV index", MeasureType.BYTE, CHANNEL_TYPE_UV_INDEX),
|
||||
|
||||
TIME("time", 0x18, "Date and time", MeasureType.DATE_TIME2),
|
||||
|
||||
DAYLWINDMAX("wind-max-day", 0X19, "Day max wind", MeasureType.SPEED, CHANNEL_TYPE_MAX_WIND_SPEED),
|
||||
|
||||
TEMPX("temperature-channel", new int[] { 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21 }, "Temperature",
|
||||
MeasureType.TEMPERATURE),
|
||||
|
||||
HUMIX("humidity-channel", new int[] { 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29 }, "Humidity",
|
||||
MeasureType.PERCENTAGE),
|
||||
|
||||
SOILTEMPX("temperature-soil-channel",
|
||||
new int[] { 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3B, 0x3D, 0x3F, 0x41, 0x43, 0x45, 0x47,
|
||||
0x49 },
|
||||
"Soil Temperature", MeasureType.TEMPERATURE),
|
||||
|
||||
SOILMOISTUREX("moisture-soil-channel",
|
||||
new int[] { 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 0x40, 0x42, 0x44, 0x46, 0x48,
|
||||
0x4A },
|
||||
"Soil Moisture", MeasureType.PERCENTAGE, CHANNEL_TYPE_MOISTURE),
|
||||
|
||||
// will no longer be used
|
||||
// skip battery-level, since it is read via Command.CMD_READ_SENSOR_ID_NEW
|
||||
LOWBATT(0x4C, new Skip(1)),
|
||||
|
||||
PM25_24HAVGX("air-quality-24-hour-average-channel", new int[] { 0x4D, 0x4E, 0x4F, 0x50 },
|
||||
"PM2.5 Air Quality 24 hour average", MeasureType.PM25),
|
||||
|
||||
PM25_CHX("air-quality-channel", new int[] { 0x2A, 0x51, 0x52, 0x53 }, "PM2.5 Air Quality", MeasureType.PM25),
|
||||
|
||||
LEAK_CHX("water-leak-channel", new int[] { 0x58, 0x59, 0x5A, 0x5B }, "Leak", MeasureType.WATER_LEAK_DETECTION),
|
||||
|
||||
// `LIGHTNING` is the name in the spec, so we keep it here as it
|
||||
LIGHTNING("lightning-distance", 0x60, "lightning distance 1~40KM", MeasureType.LIGHTNING_DISTANCE),
|
||||
|
||||
LIGHTNING_TIME("lightning-time", 0x61, "lightning happened time", MeasureType.LIGHTNING_TIME),
|
||||
|
||||
// `LIGHTNING_POWER` is the name in the spec, so we keep it here as it
|
||||
LIGHTNING_POWER("lightning-counter", 0x62, "lightning counter for the day", MeasureType.LIGHTNING_COUNTER),
|
||||
|
||||
TF_USRX("temperature-external-channel", new int[] { 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A },
|
||||
"Soil or Water temperature", MeasureType.TEMPERATURE),
|
||||
|
||||
ITEM_SENSOR_CO2(0x70,
|
||||
new MeasurandParser("sensor-co2-temperature", "Temperature (CO₂-Sensor)", MeasureType.TEMPERATURE),
|
||||
new MeasurandParser("sensor-co2-humidity", "Humidity (CO₂-Sensor)", MeasureType.PERCENTAGE),
|
||||
new MeasurandParser("sensor-co2-pm10", "PM10 Air Quality (CO₂-Sensor)", MeasureType.PM10),
|
||||
new MeasurandParser("sensor-co2-pm10-24-hour-average", "PM10 Air Quality 24 hour average (CO₂-Sensor)",
|
||||
MeasureType.PM10),
|
||||
new MeasurandParser("sensor-co2-pm25", "PM2.5 Air Quality (CO₂-Sensor)", MeasureType.PM25),
|
||||
new MeasurandParser("sensor-co2-pm25-24-hour-average", "PM2.5 Air Quality 24 hour average (CO₂-Sensor)",
|
||||
MeasureType.PM25),
|
||||
new MeasurandParser("sensor-co2-co2", "CO₂", MeasureType.CO2),
|
||||
new MeasurandParser("sensor-co2-co2-24-hour-average", "CO₂ 24 hour average", MeasureType.CO2),
|
||||
// skip battery-level, since it is read via Command.CMD_READ_SENSOR_ID_NEW
|
||||
new Skip(1)),
|
||||
|
||||
LEAF_WETNESS_CHX("leaf-wetness-channel", new int[] { 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79 },
|
||||
"Leaf Moisture", MeasureType.PERCENTAGE, CHANNEL_TYPE_MOISTURE),
|
||||
|
||||
PIEZO_RAIN_RATE("piezo-rain-rate", 0x80, "Rain Rate", MeasureType.HEIGHT_PER_HOUR),
|
||||
|
||||
PIEZO_EVENT_RAIN("piezo-rain-event", 0x81, "Rain Event", MeasureType.HEIGHT),
|
||||
|
||||
PIEZO_HOURLY_RAIN("piezo-rain-hour", 0x82, "Rain hour", MeasureType.HEIGHT),
|
||||
|
||||
PIEZO_DAILY_RAIN("piezo-rain-day", 0x83, "Rain Day", MeasureType.HEIGHT_BIG),
|
||||
|
||||
PIEZO_WEEKLY_RAIN("piezo-rain-week", 0x84, "Rain Week", MeasureType.HEIGHT_BIG),
|
||||
|
||||
PIEZO_MONTHLY_RAIN("piezo-rain-month", 0x85, "Rain Month", MeasureType.HEIGHT_BIG),
|
||||
|
||||
PIEZO_YEARLY_RAIN("piezo-rain-year", 0x86, "Rain Year", MeasureType.HEIGHT_BIG),
|
||||
|
||||
PIEZO_GAIN10(0x87, new Skip(2)),
|
||||
|
||||
RST_RAIN_TIME(0x88, new Skip(3)),
|
||||
|
||||
;
|
||||
|
||||
private static final Map<Byte, SingleChannelMeasurand> MEASURANDS = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (Measurand measurand : values()) {
|
||||
for (int i = 0; i < measurand.codes.length; i++) {
|
||||
int code = measurand.codes[i];
|
||||
// if we get more than one code this measurand has multiple channels
|
||||
Integer channel = measurand.codes.length == 1 ? null : i + 1;
|
||||
MEASURANDS.put((byte) code, new SingleChannelMeasurand(measurand, channel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final int[] codes;
|
||||
private final Parser[] parsers;
|
||||
|
||||
Measurand(String channelId, int code, String name, MeasureType measureType, ParserCustomization... customizations) {
|
||||
this(channelId, code, name, measureType, null, customizations);
|
||||
}
|
||||
|
||||
Measurand(String channelId, int[] codes, String name, MeasureType measureType,
|
||||
ParserCustomization... customizations) {
|
||||
this(channelId, codes, name, measureType, null, customizations);
|
||||
}
|
||||
|
||||
Measurand(String channelId, int code, String name, MeasureType measureType, @Nullable ChannelTypeUID channelTypeUID,
|
||||
ParserCustomization... customizations) {
|
||||
this(code, new MeasurandParser(channelId, name, measureType, channelTypeUID, customizations));
|
||||
}
|
||||
|
||||
Measurand(String channelId, int[] codes, String name, MeasureType measureType,
|
||||
@Nullable ChannelTypeUID channelTypeUID, ParserCustomization... customizations) {
|
||||
this(codes, new MeasurandParser(channelId, name, measureType, channelTypeUID, customizations));
|
||||
}
|
||||
|
||||
Measurand(int code, Parser... parsers) {
|
||||
this(new int[] { code }, parsers);
|
||||
}
|
||||
|
||||
Measurand(int[] codes, Parser... parsers) {
|
||||
this.codes = codes;
|
||||
this.parsers = parsers;
|
||||
}
|
||||
|
||||
public static @Nullable SingleChannelMeasurand getByCode(byte code) {
|
||||
return MEASURANDS.get(code);
|
||||
}
|
||||
|
||||
private int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel, ConversionContext context,
|
||||
@Nullable ParserCustomizationType customizationType, List<MeasuredValue> result) {
|
||||
int subOffset = 0;
|
||||
for (Parser parser : parsers) {
|
||||
subOffset += parser.extractMeasuredValues(data, offset + subOffset, channel, context, customizationType,
|
||||
result);
|
||||
}
|
||||
return subOffset;
|
||||
}
|
||||
|
||||
private interface Parser {
|
||||
int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel, ConversionContext context,
|
||||
@Nullable ParserCustomizationType customizationType, List<MeasuredValue> result);
|
||||
}
|
||||
|
||||
private static class Skip implements Parser {
|
||||
private final int skip;
|
||||
|
||||
public Skip(int skip) {
|
||||
this.skip = skip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel, ConversionContext context,
|
||||
@Nullable ParserCustomizationType customizationType, List<MeasuredValue> result) {
|
||||
return skip;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ParserCustomizationType {
|
||||
ELV,
|
||||
RAIN_READING
|
||||
}
|
||||
|
||||
private static class ParserCustomization {
|
||||
|
||||
private final ParserCustomizationType type;
|
||||
private final MeasureType measureType;
|
||||
|
||||
public ParserCustomization(ParserCustomizationType type, MeasureType measureType) {
|
||||
this.type = type;
|
||||
this.measureType = measureType;
|
||||
}
|
||||
|
||||
public ParserCustomizationType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public MeasureType getMeasureType() {
|
||||
return measureType;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SingleChannelMeasurand {
|
||||
private final Measurand measurand;
|
||||
private final @Nullable Integer channel;
|
||||
|
||||
public SingleChannelMeasurand(Measurand measurand, @Nullable Integer channel) {
|
||||
this.measurand = measurand;
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public int extractMeasuredValues(byte[] data, int offset, ConversionContext context,
|
||||
@Nullable ParserCustomizationType customizationType, List<MeasuredValue> result) {
|
||||
return measurand.extractMeasuredValues(data, offset, channel, context, customizationType, result);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MeasurandParser implements Parser {
|
||||
private final String name;
|
||||
private final String channelPrefix;
|
||||
private final MeasureType measureType;
|
||||
|
||||
private final @Nullable Map<ParserCustomizationType, ParserCustomization> customizations;
|
||||
private final @Nullable ChannelTypeUID channelTypeUID;
|
||||
|
||||
MeasurandParser(String channelPrefix, String name, MeasureType measureType,
|
||||
ParserCustomization... customizations) {
|
||||
this(channelPrefix, name, measureType, null, customizations);
|
||||
}
|
||||
|
||||
MeasurandParser(String channelPrefix, String name, MeasureType measureType,
|
||||
@Nullable ChannelTypeUID channelTypeUID, ParserCustomization... customizations) {
|
||||
this.channelPrefix = channelPrefix;
|
||||
this.name = name;
|
||||
this.measureType = measureType;
|
||||
this.channelTypeUID = channelTypeUID;
|
||||
if (customizations.length == 0) {
|
||||
this.customizations = null;
|
||||
} else {
|
||||
|
||||
this.customizations = Collections.unmodifiableMap(
|
||||
Arrays.stream(customizations).collect(Collectors.toMap(ParserCustomization::getType,
|
||||
customization -> customization, (a, b) -> b, HashMap::new)));
|
||||
}
|
||||
}
|
||||
|
||||
public int extractMeasuredValues(byte[] data, int offset, @Nullable Integer channel, ConversionContext context,
|
||||
@Nullable ParserCustomizationType customizationType, List<MeasuredValue> result) {
|
||||
MeasureType measureType = getMeasureType(customizationType);
|
||||
State state = measureType.toState(data, offset, context);
|
||||
if (state != null) {
|
||||
ChannelTypeUID channelType = channelTypeUID == null ? measureType.getChannelTypeId() : channelTypeUID;
|
||||
result.add(new MeasuredValue(measureType, channelPrefix, channel, channelType, state, name));
|
||||
}
|
||||
return measureType.getByteSize();
|
||||
}
|
||||
|
||||
public MeasureType getMeasureType(@Nullable ParserCustomizationType customizationType) {
|
||||
if (customizationType == null)
|
||||
return measureType;
|
||||
return Optional.ofNullable(customizations).map(m -> m.get(customizationType))
|
||||
.map(ParserCustomization::getMeasureType).orElse(measureType);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,171 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.fineoffsetweatherstation.internal.domain;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.MeasuredValue;
|
||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* Holds all the measurands supported by the gateway.
|
||||
*
|
||||
* @author Andreas Berger - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Measurands {
|
||||
|
||||
private static final Map<Protocol, Measurands> INSTANCES = new HashMap<>();
|
||||
private final Map<Byte, List<Parser>> parsersPerCode = new HashMap<>();
|
||||
|
||||
private Measurands(Protocol protocol) {
|
||||
try (InputStream data = Measurands.class.getResourceAsStream("/measurands.csv")) {
|
||||
if (data == null) {
|
||||
throw new IllegalStateException("Missing measurands.csv");
|
||||
}
|
||||
CSVFormat csvFormat = CSVFormat.Builder.create().setHeader().setSkipHeaderRecord(true).build();
|
||||
CSVParser.parse(new InputStreamReader(data), csvFormat).forEach(row -> {
|
||||
|
||||
byte code = Byte.valueOf(row.get("Code").replace("0x", ""), 16);
|
||||
Optional<Integer> skip = Optional.ofNullable(row.get("Skip")).filter(Predicate.not(String::isBlank))
|
||||
.map(Integer::valueOf);
|
||||
int index = Optional.ofNullable(row.get("Index")).filter(Predicate.not(String::isBlank))
|
||||
.map(Integer::valueOf).orElse(0);
|
||||
|
||||
Parser parser;
|
||||
if (skip.isPresent()) {
|
||||
parser = new Skip(skip.get(), index);
|
||||
} else {
|
||||
String name = row.get("Name");
|
||||
String channel = row.get("Channel");
|
||||
|
||||
ChannelTypeUID channelType = Optional.ofNullable(row.get("ChannelType"))
|
||||
.filter(Predicate.not(String::isBlank)).map(s -> {
|
||||
if (s.contains(":")) {
|
||||
return new ChannelTypeUID(s);
|
||||
} else {
|
||||
return new ChannelTypeUID(FineOffsetWeatherStationBindingConstants.BINDING_ID, s);
|
||||
}
|
||||
}).orElse(null);
|
||||
String measurandString = protocol == Protocol.DEFAULT ? row.get("MeasureType_DEFAULT")
|
||||
: Optional.ofNullable(row.get("MeasureType_" + protocol.name()))
|
||||
.filter(Predicate.not(String::isBlank))
|
||||
.orElseGet(() -> row.get("MeasureType_DEFAULT"));
|
||||
parser = new MeasurandParser(channel, name, MeasureType.valueOf(measurandString), index,
|
||||
channelType);
|
||||
}
|
||||
|
||||
List<Parser> parsers = parsersPerCode.computeIfAbsent(code, aByte -> new ArrayList<>());
|
||||
// noinspection ConstantConditions
|
||||
if (parsers != null) {
|
||||
parsers.add(parser);
|
||||
}
|
||||
});
|
||||
for (List<Parser> parsers : parsersPerCode.values()) {
|
||||
parsers.sort(Comparator.comparing(Parser::getIndex));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed to read measurands.csv", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Measurands getInstance(Protocol protocol) {
|
||||
synchronized (INSTANCES) {
|
||||
return Objects.requireNonNull(INSTANCES.computeIfAbsent(protocol, Measurands::new));
|
||||
}
|
||||
}
|
||||
|
||||
private abstract static class Parser {
|
||||
private final int index;
|
||||
|
||||
public Parser(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public abstract int extractMeasuredValues(byte[] data, int offset, ConversionContext context,
|
||||
List<MeasuredValue> result);
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Skip extends Parser {
|
||||
private final int skip;
|
||||
|
||||
public Skip(int skip, int index) {
|
||||
super(index);
|
||||
this.skip = skip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int extractMeasuredValues(byte[] data, int offset, ConversionContext context,
|
||||
List<MeasuredValue> result) {
|
||||
return skip;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MeasurandParser extends Parser {
|
||||
private final String name;
|
||||
private final String channelId;
|
||||
private final MeasureType measureType;
|
||||
private final @Nullable ChannelTypeUID channelTypeUID;
|
||||
|
||||
MeasurandParser(String channelId, String name, MeasureType measureType, int index,
|
||||
@Nullable ChannelTypeUID channelTypeUID) {
|
||||
super(index);
|
||||
this.channelId = channelId;
|
||||
this.name = name;
|
||||
this.measureType = measureType;
|
||||
this.channelTypeUID = channelTypeUID == null ? measureType.getChannelTypeId() : channelTypeUID;
|
||||
}
|
||||
|
||||
public int extractMeasuredValues(byte[] data, int offset, ConversionContext context,
|
||||
List<MeasuredValue> result) {
|
||||
State state = measureType.toState(data, offset, context);
|
||||
if (state != null) {
|
||||
result.add(new MeasuredValue(measureType, channelId, channelTypeUID, state, name));
|
||||
}
|
||||
return measureType.getByteSize();
|
||||
}
|
||||
}
|
||||
|
||||
public int extractMeasuredValues(byte code, byte[] data, int offset, ConversionContext context,
|
||||
List<MeasuredValue> result) {
|
||||
List<Parser> parsers = parsersPerCode.get(code);
|
||||
if (parsers == null) {
|
||||
throw new IllegalArgumentException("No measurement for code 0x" + Integer.toHexString(code) + " defined");
|
||||
}
|
||||
int subOffset = 0;
|
||||
for (Parser parser : parsers) {
|
||||
subOffset += parser.extractMeasuredValues(data, offset + subOffset, context, result);
|
||||
}
|
||||
return subOffset;
|
||||
}
|
||||
}
|
@ -27,13 +27,20 @@ import org.openhab.binding.fineoffsetweatherstation.internal.service.GatewayQuer
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum Protocol {
|
||||
DEFAULT(FineOffsetGatewayQueryService::new),
|
||||
ELV(ELVGatewayQueryService::new);
|
||||
DEFAULT(FineOffsetGatewayQueryService::new, null),
|
||||
ELV(ELVGatewayQueryService::new, Measurand.ParserCustomizationType.ELV);
|
||||
|
||||
private final GatewayQueryServiceFactory queryServiceFactory;
|
||||
private final Measurand.@Nullable ParserCustomizationType parserCustomizationType;
|
||||
|
||||
Protocol(GatewayQueryServiceFactory queryServiceFactory) {
|
||||
Protocol(GatewayQueryServiceFactory queryServiceFactory,
|
||||
Measurand.@Nullable ParserCustomizationType parserCustomizationType) {
|
||||
this.queryServiceFactory = queryServiceFactory;
|
||||
this.parserCustomizationType = parserCustomizationType;
|
||||
}
|
||||
|
||||
public Measurand.@Nullable ParserCustomizationType getParserCustomizationType() {
|
||||
return parserCustomizationType;
|
||||
}
|
||||
|
||||
public GatewayQueryService getGatewayQueryService(FineOffsetGatewayConfiguration config,
|
||||
|
@ -26,26 +26,32 @@ import org.openhab.core.types.State;
|
||||
@NonNullByDefault
|
||||
public class MeasuredValue {
|
||||
private final MeasureType measureType;
|
||||
private final String channelId;
|
||||
private final String channelPrefix;
|
||||
private final @Nullable Integer channelNumber;
|
||||
private final @Nullable ChannelTypeUID channelTypeUID;
|
||||
private final State state;
|
||||
private final String debugName;
|
||||
|
||||
public MeasuredValue(MeasureType measureType, String channelId, @Nullable ChannelTypeUID channelTypeUID,
|
||||
State state, String debugName) {
|
||||
public MeasuredValue(MeasureType measureType, String channelPrefix, @Nullable Integer channelNumber,
|
||||
@Nullable ChannelTypeUID channelTypeUID, State state, String debugName) {
|
||||
this.measureType = measureType;
|
||||
this.channelId = channelId;
|
||||
this.channelPrefix = channelPrefix;
|
||||
this.channelNumber = channelNumber;
|
||||
this.channelTypeUID = channelTypeUID;
|
||||
this.state = state;
|
||||
this.debugName = debugName;
|
||||
}
|
||||
|
||||
public MeasureType getMeasureType() {
|
||||
return measureType;
|
||||
public String getChannelId() {
|
||||
return channelNumber == null ? channelPrefix : (channelPrefix + "-" + channelNumber);
|
||||
}
|
||||
|
||||
public String getChannelId() {
|
||||
return channelId;
|
||||
public String getChannelPrefix() {
|
||||
return channelPrefix;
|
||||
}
|
||||
|
||||
public @Nullable Integer getChannelNumber() {
|
||||
return channelNumber;
|
||||
}
|
||||
|
||||
public @Nullable ChannelTypeUID getChannelTypeUID() {
|
||||
@ -62,7 +68,7 @@ public class MeasuredValue {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MeasuredValue{" + "measureType=" + measureType + ", channelId='" + channelId + '\''
|
||||
return "MeasuredValue{" + "measureType=" + measureType + ", channelId='" + getChannelId() + '\''
|
||||
+ ", channelTypeUID=" + channelTypeUID + ", state=" + state + ", debugName='" + debugName + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWe
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -30,7 +31,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetGatewayConfiguration;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetSensorConfiguration;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.discovery.FineOffsetGatewayDiscoveryService;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.ConversionContext;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.SensorGatewayBinding;
|
||||
@ -156,7 +156,7 @@ public class FineOffsetGatewayHandler extends BaseBridgeHandler {
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
List<MeasuredValue> data = query(GatewayQueryService::getMeasuredValues);
|
||||
Collection<MeasuredValue> data = query(GatewayQueryService::getMeasuredValues);
|
||||
if (data == null) {
|
||||
getThing().getChannels().forEach(c -> updateState(c.getUID(), UnDefType.UNDEF));
|
||||
return;
|
||||
@ -189,15 +189,14 @@ public class FineOffsetGatewayHandler extends BaseBridgeHandler {
|
||||
}
|
||||
ChannelBuilder builder = ChannelBuilder.create(new ChannelUID(thing.getUID(), measuredValue.getChannelId()))
|
||||
.withKind(ChannelKind.STATE).withType(channelTypeId);
|
||||
String channelKey = "thing-type." + FineOffsetWeatherStationBindingConstants.BINDING_ID + "."
|
||||
+ THING_TYPE_GATEWAY.getId() + ".channel." + measuredValue.getChannelId();
|
||||
String channelKey = THING_TYPE_GATEWAY.getId() + ".dynamic-channel." + measuredValue.getChannelPrefix();
|
||||
String label = translationProvider.getText(bundle, channelKey + ".label", measuredValue.getDebugName(),
|
||||
localeProvider.getLocale());
|
||||
localeProvider.getLocale(), measuredValue.getChannelNumber());
|
||||
if (label != null) {
|
||||
builder.withLabel(label);
|
||||
}
|
||||
String description = translationProvider.getText(bundle, channelKey + ".description", null,
|
||||
localeProvider.getLocale());
|
||||
localeProvider.getLocale(), measuredValue.getChannelNumber());
|
||||
if (description != null) {
|
||||
builder.withDescription(description);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.Sen
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
@ -31,8 +32,6 @@ import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
import tech.units.indriya.unit.Units;
|
||||
|
||||
/**
|
||||
* The {@link FineOffsetSensorHandler} keeps track of the signal and battery of the sensor attached to the gateway.
|
||||
*
|
||||
|
@ -27,7 +27,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.Utils;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.ConversionContext;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Measurands;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Measurand;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.SensorGatewayBinding;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.BatteryStatus;
|
||||
@ -174,17 +174,25 @@ public class FineOffsetDataParser {
|
||||
if (protocol == Protocol.ELV) {
|
||||
idx++; // at index 5 there is an additional Byte being set to 0x04
|
||||
}
|
||||
return readMeasuredValues(data, idx, context, protocol.getParserCustomizationType());
|
||||
}
|
||||
|
||||
List<MeasuredValue> getRainData(byte[] data, ConversionContext context) {
|
||||
return readMeasuredValues(data, 5, context, Measurand.ParserCustomizationType.RAIN_READING);
|
||||
}
|
||||
|
||||
private List<MeasuredValue> readMeasuredValues(byte[] data, int idx, ConversionContext context,
|
||||
Measurand.@Nullable ParserCustomizationType protocol) {
|
||||
var size = toUInt16(data, 3);
|
||||
List<MeasuredValue> result = new ArrayList<>();
|
||||
Measurands measurands = Measurands.getInstance(protocol);
|
||||
while (idx < size) {
|
||||
byte code = data[idx++];
|
||||
try {
|
||||
idx += measurands.extractMeasuredValues(code, data, idx, context, result);
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.warn("", e);
|
||||
Measurand.SingleChannelMeasurand measurand = Measurand.getByCode(code);
|
||||
if (measurand == null) {
|
||||
logger.warn("failed to get measurand 0x{}", Integer.toHexString(code));
|
||||
return result;
|
||||
}
|
||||
idx += measurand.extractMeasuredValues(data, idx, context, protocol, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -12,7 +12,8 @@
|
||||
*/
|
||||
package org.openhab.binding.fineoffsetweatherstation.internal.service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -86,12 +87,26 @@ public class FineOffsetGatewayQueryService extends GatewayQueryService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MeasuredValue> getMeasuredValues() {
|
||||
public Collection<MeasuredValue> getMeasuredValues() {
|
||||
Map<String, MeasuredValue> valuePerChannel = new LinkedHashMap<>();
|
||||
|
||||
byte[] data = executeCommand(Command.CMD_GW1000_LIVEDATA);
|
||||
if (data == null) {
|
||||
return Collections.emptyList();
|
||||
if (data != null) {
|
||||
List<MeasuredValue> measuredValues = fineOffsetDataParser.getMeasuredValues(data, conversionContext);
|
||||
for (MeasuredValue measuredValue : measuredValues) {
|
||||
valuePerChannel.put(measuredValue.getChannelId(), measuredValue);
|
||||
}
|
||||
}
|
||||
return fineOffsetDataParser.getMeasuredValues(data, conversionContext);
|
||||
|
||||
data = executeCommand(Command.CMD_READ_RAIN);
|
||||
if (data != null) {
|
||||
List<MeasuredValue> measuredRainValues = fineOffsetDataParser.getRainData(data, conversionContext);
|
||||
for (MeasuredValue measuredValue : measuredRainValues) {
|
||||
valuePerChannel.put(measuredValue.getChannelId(), measuredValue);
|
||||
}
|
||||
}
|
||||
|
||||
return valuePerChannel.values();
|
||||
}
|
||||
|
||||
protected byte @Nullable [] executeCommand(Command command) {
|
||||
|
@ -16,7 +16,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.Socket;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
@ -63,7 +63,7 @@ public abstract class GatewayQueryService implements AutoCloseable {
|
||||
@Nullable
|
||||
public abstract SystemInfo fetchSystemInfo();
|
||||
|
||||
public abstract List<MeasuredValue> getMeasuredValues();
|
||||
public abstract Collection<MeasuredValue> getMeasuredValues();
|
||||
|
||||
public GatewayQueryService(FineOffsetGatewayConfiguration config,
|
||||
@Nullable ThingStatusListener thingStatusListener) {
|
||||
|
@ -76,119 +76,63 @@ thing.sensor.WH68.description = Solar-powered Sensor for Wind Speed & Direction,
|
||||
thing.sensor.WH80.label = Weather Station - outdoor unit
|
||||
thing.sensor.WH80.description = Ultrasonic Sensor for Wind Speed & Direction, Solar Radiation & Light, Temperature & Humidity
|
||||
thing.sensor.WH90.label = Weather Station - outdoor unit
|
||||
thing.sensor.WH90.description = Ultrasonic sensor for wind speed & direction, solar radiation & light, temperature, humidity and haptic rainfall Sensor
|
||||
|
||||
# channels
|
||||
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-indoor.label = Indoor Temperature
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-outdoor.label = Outdoor Temperature
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-dew-point.label = Dew Point
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-wind-chill.label = Perceived Temperature
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-heat-index.label = Heat Index
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.humidity-indoor.label = Humidity Inside
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.humidity-outdoor.label = Humidity Outside
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.pressure-absolute.label = Absolute Pressure
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.pressure-relative.label = Relative Pressure
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.direction-wind.label = Wind Direction
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.speed-wind.label = Wind Speed
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.speed-gust.label = Gust Speed
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.rain-event.label = Amount of Rainfall At the last Rain
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.rain-rate.label = Rainfall Rate
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.rain-hour.label = Rainfall Current Hour
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.rain-day.label = Rainfall Today
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.rain-week.label = Rainfall this Week
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.rain-month.label = Rainfall this Month
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.rain-year.label = Rainfall this Year
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.rain-total.label = Rainfall Total
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.illumination.label = Light Intensity
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.irradiation-uv.label = UV Irradiation
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.uv-index.label = UV Index
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.time.label = Date and Time
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.wind-max-day.label = Maximum Wind Speed Today
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-channel-1.label = Temperature Channel 1
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-channel-2.label = Temperature Channel 2
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-channel-3.label = Temperature Channel 3
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-channel-4.label = Temperature Channel 4
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-channel-5.label = Temperature Channel 5
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-channel-6.label = Temperature Channel 6
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-channel-7.label = Temperature Channel 7
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-channel-8.label = Temperature Channel 8
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.humidity-channel-1.label = Humidity Channel 1
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.humidity-channel-2.label = Humidity Channel 2
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.humidity-channel-3.label = Humidity Channel 3
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.humidity-channel-4.label = Humidity Channel 4
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.humidity-channel-5.label = Humidity Channel 5
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.humidity-channel-6.label = Humidity Channel 6
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.humidity-channel-7.label = Humidity Channel 7
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.humidity-channel-8.label = Humidity Channel 8
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-1.label = Soil Temperature Channel 1
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-2.label = Soil Temperature Channel 2
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-3.label = Soil Temperature Channel 3
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-4.label = Soil Temperature Channel 4
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-5.label = Soil Temperature Channel 5
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-6.label = Soil Temperature Channel 6
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-7.label = Soil Temperature Channel 7
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-8.label = Soil Temperature Channel 8
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-9.label = Soil Temperature Channel 9
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-10.label = Soil Temperature Channel 10
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-11.label = Soil Temperature Channel 11
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-12.label = Soil Temperature Channel 12
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-13.label = Soil Temperature Channel 13
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-14.label = Soil Temperature Channel 14
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-15.label = Soil Temperature Channel 15
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-soil-channel-16.label = Soil Temperature Channel 16
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-1.label = Soil Moisture Channel 1
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-2.label = Soil Moisture Channel 2
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-3.label = Soil Moisture Channel 3
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-4.label = soil Moisture Channel 4
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-5.label = Soil Moisture Channel 5
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-6.label = Soil Moisture Channel 6
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-7.label = Soil Moisture Channel 7
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-8.label = Soil Moisture Channel 8
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-9.label = Soil Moisture Channel 9
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-10.label = Soil Moisture Channel 10
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-11.label = Soil Moisture Channel 11
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-12.label = Soil Moisture Channel 12
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-13.label = soil Moisture Channel 13
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-14.label = Soil Moisture Channel 14
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-15.label = Soil Moisture Channel 15
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.moisture-soil-channel-16.label = Soil Moisture Channel 16
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.air-quality-24-hour-average-channel-1.label = PM2.5 Air Quality 24 Hour Average Channel 1
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.air-quality-24-hour-average-channel-2.label = PM2.5 Air Quality 24 Hour Average Channel 2
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.air-quality-24-hour-average-channel-3.label = PM2.5 Air Quality 24 Hour Average Channel 3
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.air-quality-24-hour-average-channel-4.label = PM2.5 Air Quality 24 Hour Average Channel 4
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.air-quality-channel-1.label = PM2.5 Air Quality Channel 1
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.air-quality-channel-2.label = PM2.5 Air Quality Channel 2
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.air-quality-channel-3.label = PM2.5 Air Quality Channel 3
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.air-quality-channel-4.label = PM2.5 Air Quality Channel 4
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.water-leak-channel-1.label = Water Leak Detection Channel 1
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.water-leak-channel-2.label = Water Leak Detection Channel 2
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.water-leak-channel-3.label = Water Leak Detection Channel 3
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.water-leak-channel-4.label = Water Leak Detection Channel 4
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.lightning-distance.label = Lightning Distance
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.lightning-time.label = Time of last Lightning Strike
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.lightning-counter.label = Lightning Strikes Today
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-external-channel-1.label = External Temperature Sensor Channel 1
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-external-channel-2.label = External Temperature Sensor Channel 2
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-external-channel-3.label = External Temperature Sensor Channel 3
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-external-channel-4.label = External Temperature Sensor Channel 4
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-external-channel-5.label = External Temperature Sensor Channel 5
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-external-channel-6.label = External Temperature Sensor Channel 6
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-external-channel-7.label = External Temperature Sensor Channel 7
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.temperature-external-channel-8.label = External Temperature Sensor Channel 8
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.sensor-co2-temperature.label = Temperature (CO2-Sensor)
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.sensor-co2-humidity.label = Humidity (CO2-Sensor)
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.sensor-co2-pm10.label = PM10 Air Quality (CO2-Sensor)
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.sensor-co2-pm10-24-hour-average.label = PM10 Air Quality 24 Hour Average (CO2-Sensor)
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.sensor-co2-pm25.label = PM2.5 Air Quality (CO2-Sensor)
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.sensor-co2-pm25-24-hour-average.label = PM2.5 Air Quality 24 Hour Average (CO2-Sensor)
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.sensor-co2-co2.label = CO2
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.sensor-co2-co2-24-hour-average.label = CO2 24 Hour Average
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.leaf-wetness-channel-1.label = Leaf Moisture Channel 1
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.leaf-wetness-channel-2.label = Leaf Moisture Channel 2
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.leaf-wetness-channel-3.label = Leaf Moisture Channel 3
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.leaf-wetness-channel-4.label = Leaf Moisture Channel 4
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.leaf-wetness-channel-5.label = Leaf Moisture Channel 5
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.leaf-wetness-channel-6.label = Leaf Moisture Channel 6
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.leaf-wetness-channel-7.label = Leaf Moisture Channel 7
|
||||
thing-type.fineoffsetweatherstation.gateway.channel.leaf-wetness-channel-8.label = Leaf Moisture Channel 8
|
||||
thing-type.fineoffsetweatherstation.sensor.channel.batteryVoltage.label = Battery Voltage
|
||||
|
||||
# dynamic channels
|
||||
|
||||
gateway.dynamic-channel.temperature-indoor.label = Indoor Temperature
|
||||
gateway.dynamic-channel.temperature-outdoor.label = Outdoor Temperature
|
||||
gateway.dynamic-channel.temperature-dew-point.label = Dew Point
|
||||
gateway.dynamic-channel.temperature-wind-chill.label = Perceived Temperature
|
||||
gateway.dynamic-channel.temperature-heat-index.label = Heat Index
|
||||
gateway.dynamic-channel.humidity-indoor.label = Humidity Inside
|
||||
gateway.dynamic-channel.humidity-outdoor.label = Humidity Outside
|
||||
gateway.dynamic-channel.pressure-absolute.label = Absolute Pressure
|
||||
gateway.dynamic-channel.pressure-relative.label = Relative Pressure
|
||||
gateway.dynamic-channel.direction-wind.label = Wind Direction
|
||||
gateway.dynamic-channel.speed-wind.label = Wind Speed
|
||||
gateway.dynamic-channel.speed-gust.label = Gust Speed
|
||||
gateway.dynamic-channel.rain-event.label = Amount of Rainfall At the last Rain
|
||||
gateway.dynamic-channel.rain-rate.label = Rainfall Rate
|
||||
gateway.dynamic-channel.rain-hour.label = Rainfall Current Hour
|
||||
gateway.dynamic-channel.rain-day.label = Rainfall Today
|
||||
gateway.dynamic-channel.rain-week.label = Rainfall this Week
|
||||
gateway.dynamic-channel.rain-month.label = Rainfall this Month
|
||||
gateway.dynamic-channel.rain-year.label = Rainfall this Year
|
||||
gateway.dynamic-channel.rain-total.label = Rainfall Total
|
||||
gateway.dynamic-channel.illumination.label = Light Intensity
|
||||
gateway.dynamic-channel.irradiation-uv.label = UV Irradiation
|
||||
gateway.dynamic-channel.uv-index.label = UV Index
|
||||
gateway.dynamic-channel.time.label = Date and Time
|
||||
gateway.dynamic-channel.wind-max-day.label = Maximum Wind Speed Today
|
||||
gateway.dynamic-channel.temperature-channel.label = Temperature Channel {0}
|
||||
gateway.dynamic-channel.humidity-channel.label = Humidity Channel {0}
|
||||
gateway.dynamic-channel.temperature-soil-channel.label = Soil Temperature Channel {0}
|
||||
gateway.dynamic-channel.moisture-soil-channel.label = Soil Moisture Channel {0}
|
||||
gateway.dynamic-channel.air-quality-24-hour-average-channel.label = PM2.5 Air Quality 24 Hour Average Channel {0}
|
||||
gateway.dynamic-channel.air-quality-channel.label = PM2.5 Air Quality Channel {0}
|
||||
gateway.dynamic-channel.water-leak-channel.label = Water Leak Detection Channel {0}
|
||||
gateway.dynamic-channel.lightning-distance.label = Lightning Distance
|
||||
gateway.dynamic-channel.lightning-time.label = Time of last Lightning Strike
|
||||
gateway.dynamic-channel.lightning-counter.label = Lightning Strikes Today
|
||||
gateway.dynamic-channel.temperature-external-channel.label = External Temperature Sensor Channel {0}
|
||||
gateway.dynamic-channel.sensor-co2-temperature.label = Temperature (CO2-Sensor)
|
||||
gateway.dynamic-channel.sensor-co2-humidity.label = Humidity (CO2-Sensor)
|
||||
gateway.dynamic-channel.sensor-co2-pm10.label = PM10 Air Quality (CO2-Sensor)
|
||||
gateway.dynamic-channel.sensor-co2-pm10-24-hour-average.label = PM10 Air Quality 24 Hour Average (CO2-Sensor)
|
||||
gateway.dynamic-channel.sensor-co2-pm25.label = PM2.5 Air Quality (CO2-Sensor)
|
||||
gateway.dynamic-channel.sensor-co2-pm25-24-hour-average.label = PM2.5 Air Quality 24 Hour Average (CO2-Sensor)
|
||||
gateway.dynamic-channel.sensor-co2-co2.label = CO2
|
||||
gateway.dynamic-channel.sensor-co2-co2-24-hour-average.label = CO2 24 Hour Average
|
||||
gateway.dynamic-channel.leaf-wetness-channel.label = Leaf Moisture Channel {0}
|
||||
gateway.dynamic-channel.piezo-rain-rate.label = Rain Rate
|
||||
gateway.dynamic-channel.piezo-rain-event.label = Rain Event
|
||||
gateway.dynamic-channel.piezo-rain-hour.label = Rain hour
|
||||
gateway.dynamic-channel.piezo-rain-day.label = Rain Day
|
||||
gateway.dynamic-channel.piezo-rain-week.label = Rain Week
|
||||
gateway.dynamic-channel.piezo-rain-month.label = Rain Month
|
||||
gateway.dynamic-channel.piezo-rain-year.label = Rain Year
|
||||
|
@ -1,115 +0,0 @@
|
||||
ManufacturerName,Name,Channel,Code,Index,Skip,ChannelType,MeasureType_DEFAULT,MeasureType_ELV
|
||||
INTEMP,Indoor Temperature,temperature-indoor,0x1,,,system:indoor-temperature,TEMPERATURE,
|
||||
OUTTEMP,Outdoor Temperature,temperature-outdoor,0x2,,,system:outdoor-temperature,TEMPERATURE,
|
||||
DEWPOINT,Dew point,temperature-dew-point,0x3,,,,TEMPERATURE,
|
||||
WINDCHILL,Wind chill,temperature-wind-chill,0x4,,,,TEMPERATURE,
|
||||
HEATINDEX,Heat index,temperature-heat-index,0x5,,,,TEMPERATURE,
|
||||
INHUMI,Indoor Humidity,humidity-indoor,0x6,,,,PERCENTAGE,
|
||||
OUTHUMI,Outdoor Humidity,humidity-outdoor,0x7,,,system:atmospheric-humidity,PERCENTAGE,
|
||||
ABSBARO,Absolutely pressure,pressure-absolute,0x8,,,,PRESSURE,
|
||||
RELBARO,Relative pressure,pressure-relative,0x9,,,system:barometric-pressure,PRESSURE,
|
||||
WINDDIRECTION,Wind Direction,direction-wind,0xa,,,system:wind-direction,DEGREE,
|
||||
WINDSPEED,Wind Speed,speed-wind,0xb,,,system:wind-speed,SPEED,
|
||||
GUSTSPEED,Gust Speed,speed-gust,0xc,,,system:wind-speed,SPEED,
|
||||
RAINEVENT,Rain Event,rain-event,0xd,,,,HEIGHT,HEIGHT_BIG
|
||||
RAINRATE,Rain Rate,rain-rate,0xe,,,,HEIGHT_PER_HOUR,HEIGHT_PER_HOUR_BIG
|
||||
RAINHOUR,Rain hour,rain-hour,0xf,,,,HEIGHT,HEIGHT_BIG
|
||||
RAINDAY,Rain Day,rain-day,0x10,,,,HEIGHT,HEIGHT_BIG
|
||||
RAINWEEK,Rain Week,rain-week,0x11,,,,HEIGHT,HEIGHT_BIG
|
||||
RAINMONTH,Rain Month,rain-month,0x12,,,,HEIGHT_BIG,
|
||||
RAINYEAR,Rain Year,rain-year,0x13,,,,HEIGHT_BIG,
|
||||
RAINTOTALS,Rain Totals,rain-total,0x14,,,,HEIGHT_BIG,
|
||||
LIGHT,Light,illumination,0x15,,,,LUX,
|
||||
UV,UV,irradiation-uv,0x16,,,,MILLIWATT_PER_SQUARE_METRE,
|
||||
UVI,UV index,uv-index,0x17,,,uv-index,BYTE,
|
||||
TIME,Date and time,time,0x18,,,,DATE_TIME2,
|
||||
DAYLWINDMAX,Day max wind,wind-max-day,0x19,,,max-wind-speed,SPEED,
|
||||
TEMP1,Temperature 1,temperature-channel-1,0x1a,,,,TEMPERATURE,
|
||||
TEMP2,Temperature 2,temperature-channel-2,0x1b,,,,TEMPERATURE,
|
||||
TEMP3,Temperature 3,temperature-channel-3,0x1c,,,,TEMPERATURE,
|
||||
TEMP4,Temperature 4,temperature-channel-4,0x1d,,,,TEMPERATURE,
|
||||
TEMP5,Temperature 5,temperature-channel-5,0x1e,,,,TEMPERATURE,
|
||||
TEMP6,Temperature 6,temperature-channel-6,0x1f,,,,TEMPERATURE,
|
||||
TEMP7,Temperature 7,temperature-channel-7,0x20,,,,TEMPERATURE,
|
||||
TEMP8,Temperature 8,temperature-channel-8,0x21,,,,TEMPERATURE,
|
||||
HUMI1,Humidity 1,humidity-channel-1,0x22,,,,PERCENTAGE,
|
||||
HUMI2,Humidity 2,humidity-channel-2,0x23,,,,PERCENTAGE,
|
||||
HUMI3,Humidity 3,humidity-channel-3,0x24,,,,PERCENTAGE,
|
||||
HUMI4,Humidity 4,humidity-channel-4,0x25,,,,PERCENTAGE,
|
||||
HUMI5,Humidity 5,humidity-channel-5,0x26,,,,PERCENTAGE,
|
||||
HUMI6,Humidity 6,humidity-channel-6,0x27,,,,PERCENTAGE,
|
||||
HUMI7,Humidity 7,humidity-channel-7,0x28,,,,PERCENTAGE,
|
||||
HUMI8,Humidity 8,humidity-channel-8,0x29,,,,PERCENTAGE,
|
||||
SOILTEMP1,Soil Temperature 1,temperature-soil-channel-1,0x2b,,,,TEMPERATURE,
|
||||
SOILTEMP2,Soil Temperature 2,temperature-soil-channel-2,0x2d,,,,TEMPERATURE,
|
||||
SOILTEMP3,Soil Temperature 3,temperature-soil-channel-3,0x2f,,,,TEMPERATURE,
|
||||
SOILTEMP4,Soil Temperature 4,temperature-soil-channel-4,0x31,,,,TEMPERATURE,
|
||||
SOILTEMP5,Soil Temperature 5,temperature-soil-channel-5,0x33,,,,TEMPERATURE,
|
||||
SOILTEMP6,Soil Temperature 6,temperature-soil-channel-6,0x35,,,,TEMPERATURE,
|
||||
SOILTEMP7,Soil Temperature 7,temperature-soil-channel-7,0x37,,,,TEMPERATURE,
|
||||
SOILTEMP8,Soil Temperature 8,temperature-soil-channel-8,0x39,,,,TEMPERATURE,
|
||||
SOILTEMP9,Soil Temperature 9,temperature-soil-channel-9,0x3b,,,,TEMPERATURE,
|
||||
SOILTEMP10,Soil Temperature 10,temperature-soil-channel-10,0x3d,,,,TEMPERATURE,
|
||||
SOILTEMP11,Soil Temperature 11,temperature-soil-channel-11,0x3f,,,,TEMPERATURE,
|
||||
SOILTEMP12,Soil Temperature 12,temperature-soil-channel-12,0x41,,,,TEMPERATURE,
|
||||
SOILTEMP13,Soil Temperature 13,temperature-soil-channel-13,0x43,,,,TEMPERATURE,
|
||||
SOILTEMP14,Soil Temperature 14,temperature-soil-channel-14,0x45,,,,TEMPERATURE,
|
||||
SOILTEMP15,Soil Temperature 15,temperature-soil-channel-15,0x47,,,,TEMPERATURE,
|
||||
SOILTEMP16,Soil Temperature 16,temperature-soil-channel-16,0x49,,,,TEMPERATURE,
|
||||
SOILMOISTURE1,Soil Moisture 1,moisture-soil-channel-1,0x2c,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE2,Soil Moisture 2,moisture-soil-channel-2,0x2e,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE3,Soil Moisture 3,moisture-soil-channel-3,0x30,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE4,Soil Moisture 4,moisture-soil-channel-4,0x32,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE5,Soil Moisture 5,moisture-soil-channel-5,0x34,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE6,Soil Moisture 6,moisture-soil-channel-6,0x36,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE7,Soil Moisture 7,moisture-soil-channel-7,0x38,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE8,Soil Moisture 8,moisture-soil-channel-8,0x3a,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE9,Soil Moisture 9,moisture-soil-channel-9,0x3c,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE10,Soil Moisture 10,moisture-soil-channel-10,0x3e,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE11,Soil Moisture 11,moisture-soil-channel-11,0x40,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE12,Soil Moisture 12,moisture-soil-channel-12,0x42,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE13,Soil Moisture 13,moisture-soil-channel-13,0x44,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE14,Soil Moisture 14,moisture-soil-channel-14,0x46,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE15,Soil Moisture 15,moisture-soil-channel-15,0x48,,,moisture,PERCENTAGE,
|
||||
SOILMOISTURE16,Soil Moisture 16,moisture-soil-channel-16,0x4a,,,moisture,PERCENTAGE,
|
||||
LOWBATT,Low Battery,,0x4c,,1,,,
|
||||
PM25_24HAVG1,PM2.5 Air Quality 24 hour average channel 1,air-quality-24-hour-average-channel-1,0x4d,,,,PM25,
|
||||
PM25_24HAVG2,PM2.5 Air Quality 24 hour average channel 2,air-quality-24-hour-average-channel-2,0x4e,,,,PM25,
|
||||
PM25_24HAVG3,PM2.5 Air Quality 24 hour average channel 3,air-quality-24-hour-average-channel-3,0x4f,,,,PM25,
|
||||
PM25_24HAVG4,PM2.5 Air Quality 24 hour average channel 4,air-quality-24-hour-average-channel-4,0x50,,,,PM25,
|
||||
PM25_CH1,PM2.5 Air Quality channel 1,air-quality-channel-1,0x2a,,,,PM25,
|
||||
PM25_CH2,PM2.5 Air Quality channel 2,air-quality-channel-2,0x51,,,,PM25,
|
||||
PM25_CH3,PM2.5 Air Quality channel 3,air-quality-channel-3,0x52,,,,PM25,
|
||||
PM25_CH4,PM2.5 Air Quality channel 4,air-quality-channel-4,0x53,,,,PM25,
|
||||
LEAK_CH1,Leak channel 1,water-leak-channel-1,0x58,,,,WATER_LEAK_DETECTION,
|
||||
LEAK_CH2,Leak channel 2,water-leak-channel-2,0x59,,,,WATER_LEAK_DETECTION,
|
||||
LEAK_CH3,Leak channel 3,water-leak-channel-3,0x5a,,,,WATER_LEAK_DETECTION,
|
||||
LEAK_CH4,Leak channel 4,water-leak-channel-4,0x5b,,,,WATER_LEAK_DETECTION,
|
||||
LIGHTNING,lightning distance 1~40KM,lightning-distance,0x60,,,,LIGHTNING_DISTANCE,
|
||||
LIGHTNING_TIME,lightning happened time,lightning-time,0x61,,,,LIGHTNING_TIME,
|
||||
LIGHTNING_POWER,lightning counter for the day,lightning-counter,0x62,,,,LIGHTNING_COUNTER,
|
||||
TF_USR1,Soil or Water temperature channel 1,temperature-external-channel-1,0x63,,,,TEMPERATURE,
|
||||
TF_USR2,Soil or Water temperature channel 2,temperature-external-channel-2,0x64,,,,TEMPERATURE,
|
||||
TF_USR3,Soil or Water temperature channel 3,temperature-external-channel-3,0x65,,,,TEMPERATURE,
|
||||
TF_USR4,Soil or Water temperature channel 4,temperature-external-channel-4,0x66,,,,TEMPERATURE,
|
||||
TF_USR5,Soil or Water temperature channel 5,temperature-external-channel-5,0x67,,,,TEMPERATURE,
|
||||
TF_USR6,Soil or Water temperature channel 6,temperature-external-channel-6,0x68,,,,TEMPERATURE,
|
||||
TF_USR7,Soil or Water temperature channel 7,temperature-external-channel-7,0x69,,,,TEMPERATURE,
|
||||
TF_USR8,Soil or Water temperature channel 8,temperature-external-channel-8,0x6a,,,,TEMPERATURE,
|
||||
ITEM_SENSOR_CO2,Temperature (CO₂-Sensor),sensor-co2-temperature,0x70,0,,,TEMPERATURE,
|
||||
ITEM_SENSOR_CO2,Humidity (CO₂-Sensor),sensor-co2-humidity,0x70,1,,,PERCENTAGE,
|
||||
ITEM_SENSOR_CO2,PM10 Air Quality (CO₂-Sensor),sensor-co2-pm10,0x70,2,,,PM10,
|
||||
ITEM_SENSOR_CO2,PM10 Air Quality 24 hour average (CO₂-Sensor),sensor-co2-pm10-24-hour-average,0x70,3,,,PM10,
|
||||
ITEM_SENSOR_CO2,PM2.5 Air Quality (CO₂-Sensor),sensor-co2-pm25,0x70,4,,,PM25,
|
||||
ITEM_SENSOR_CO2,PM2.5 Air Quality 24 hour average (CO₂-Sensor),sensor-co2-pm25-24-hour-average,0x70,5,,,PM25,
|
||||
ITEM_SENSOR_CO2,CO₂,sensor-co2-co2,0x70,6,,,CO2,
|
||||
ITEM_SENSOR_CO2,CO₂ 24 hour average,sensor-co2-co2-24-hour-average,0x70,7,,,CO2,
|
||||
ITEM_SENSOR_CO2,Battery Level,,0x70,8,1,,,
|
||||
ITEM_LEAF_WETNESS_CH1,Leaf Moisture channel 1,leaf-wetness-channel-1,0x72,,,moisture,PERCENTAGE,
|
||||
ITEM_LEAF_WETNESS_CH2,Leaf Moisture channel 2,leaf-wetness-channel-2,0x73,,,moisture,PERCENTAGE,
|
||||
ITEM_LEAF_WETNESS_CH3,Leaf Moisture channel 3,leaf-wetness-channel-3,0x74,,,moisture,PERCENTAGE,
|
||||
ITEM_LEAF_WETNESS_CH4,Leaf Moisture channel 4,leaf-wetness-channel-4,0x75,,,moisture,PERCENTAGE,
|
||||
ITEM_LEAF_WETNESS_CH5,Leaf Moisture channel 5,leaf-wetness-channel-5,0x76,,,moisture,PERCENTAGE,
|
||||
ITEM_LEAF_WETNESS_CH6,Leaf Moisture channel 6,leaf-wetness-channel-6,0x77,,,moisture,PERCENTAGE,
|
||||
ITEM_LEAF_WETNESS_CH7,Leaf Moisture channel 7,leaf-wetness-channel-7,0x78,,,moisture,PERCENTAGE,
|
||||
ITEM_LEAF_WETNESS_CH8,Leaf Moisture channel 8,leaf-wetness-channel-8,0x79,,,moisture,PERCENTAGE,
|
|
@ -20,6 +20,7 @@ import org.assertj.core.groups.Tuple;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Command;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.ConversionContext;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol;
|
||||
import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.MeasuredValue;
|
||||
@ -74,6 +75,34 @@ class FineOffsetDataParserTest {
|
||||
new Tuple("irradiation-uv", "215.3 mW/m²"), new Tuple("uv-index", "5"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRainData() {
|
||||
byte[] data = Hex
|
||||
.decode("FFFF5700290E000010000000001100000024120000003113000005030D00000F0064880000017A017B0030");
|
||||
List<MeasuredValue> measuredValues = new FineOffsetDataParser(Protocol.DEFAULT).getRainData(data,
|
||||
new ConversionContext(ZoneOffset.UTC));
|
||||
Assertions.assertThat(measuredValues)
|
||||
.extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
|
||||
.containsExactly(new Tuple("rain-rate", "0 mm/h"), new Tuple("rain-day", "0 mm"),
|
||||
new Tuple("rain-week", "3.6 mm"), new Tuple("rain-month", "4.9 mm"),
|
||||
new Tuple("rain-year", "128.3 mm"), new Tuple("rain-event", "0 mm"),
|
||||
new Tuple("rain-hour", "10 mm"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRainDataW90() {
|
||||
byte[] data = Hex.decode(
|
||||
"FFFF5700398000008300000009840000000985000000C786000000C7810000870064006400640064006400640064006400640064880900007A02BF");
|
||||
Assertions.assertThat(Command.CMD_READ_RAIN.isResponseValid(data)).isTrue();
|
||||
List<MeasuredValue> measuredValues = new FineOffsetDataParser(Protocol.DEFAULT).getRainData(data,
|
||||
new ConversionContext(ZoneOffset.UTC));
|
||||
Assertions.assertThat(measuredValues)
|
||||
.extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
|
||||
.containsExactly(new Tuple("piezo-rain-rate", "0 mm/h"), new Tuple("piezo-rain-day", "0.9 mm"),
|
||||
new Tuple("piezo-rain-week", "0.9 mm"), new Tuple("piezo-rain-month", "19.9 mm"),
|
||||
new Tuple("piezo-rain-year", "19.9 mm"), new Tuple("piezo-rain-event", "0 mm"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFirmware() {
|
||||
byte[] data = Hex.decode("FFFF501511456173795765617468657256312E362E3400");
|
||||
|
Loading…
Reference in New Issue
Block a user