[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:
Andreas Berger 2022-08-31 15:27:18 +02:00 committed by GitHub
parent a2e0d23297
commit 4331c5f3ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 519 additions and 441 deletions

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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 + '\'' + '}';
}
}

View File

@ -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);
}

View File

@ -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.
*

View File

@ -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;
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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

View File

@ -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,
1 ManufacturerName Name Channel Code Index Skip ChannelType MeasureType_DEFAULT MeasureType_ELV
2 INTEMP Indoor Temperature temperature-indoor 0x1 system:indoor-temperature TEMPERATURE
3 OUTTEMP Outdoor Temperature temperature-outdoor 0x2 system:outdoor-temperature TEMPERATURE
4 DEWPOINT Dew point temperature-dew-point 0x3 TEMPERATURE
5 WINDCHILL Wind chill temperature-wind-chill 0x4 TEMPERATURE
6 HEATINDEX Heat index temperature-heat-index 0x5 TEMPERATURE
7 INHUMI Indoor Humidity humidity-indoor 0x6 PERCENTAGE
8 OUTHUMI Outdoor Humidity humidity-outdoor 0x7 system:atmospheric-humidity PERCENTAGE
9 ABSBARO Absolutely pressure pressure-absolute 0x8 PRESSURE
10 RELBARO Relative pressure pressure-relative 0x9 system:barometric-pressure PRESSURE
11 WINDDIRECTION Wind Direction direction-wind 0xa system:wind-direction DEGREE
12 WINDSPEED Wind Speed speed-wind 0xb system:wind-speed SPEED
13 GUSTSPEED Gust Speed speed-gust 0xc system:wind-speed SPEED
14 RAINEVENT Rain Event rain-event 0xd HEIGHT HEIGHT_BIG
15 RAINRATE Rain Rate rain-rate 0xe HEIGHT_PER_HOUR HEIGHT_PER_HOUR_BIG
16 RAINHOUR Rain hour rain-hour 0xf HEIGHT HEIGHT_BIG
17 RAINDAY Rain Day rain-day 0x10 HEIGHT HEIGHT_BIG
18 RAINWEEK Rain Week rain-week 0x11 HEIGHT HEIGHT_BIG
19 RAINMONTH Rain Month rain-month 0x12 HEIGHT_BIG
20 RAINYEAR Rain Year rain-year 0x13 HEIGHT_BIG
21 RAINTOTALS Rain Totals rain-total 0x14 HEIGHT_BIG
22 LIGHT Light illumination 0x15 LUX
23 UV UV irradiation-uv 0x16 MILLIWATT_PER_SQUARE_METRE
24 UVI UV index uv-index 0x17 uv-index BYTE
25 TIME Date and time time 0x18 DATE_TIME2
26 DAYLWINDMAX Day max wind wind-max-day 0x19 max-wind-speed SPEED
27 TEMP1 Temperature 1 temperature-channel-1 0x1a TEMPERATURE
28 TEMP2 Temperature 2 temperature-channel-2 0x1b TEMPERATURE
29 TEMP3 Temperature 3 temperature-channel-3 0x1c TEMPERATURE
30 TEMP4 Temperature 4 temperature-channel-4 0x1d TEMPERATURE
31 TEMP5 Temperature 5 temperature-channel-5 0x1e TEMPERATURE
32 TEMP6 Temperature 6 temperature-channel-6 0x1f TEMPERATURE
33 TEMP7 Temperature 7 temperature-channel-7 0x20 TEMPERATURE
34 TEMP8 Temperature 8 temperature-channel-8 0x21 TEMPERATURE
35 HUMI1 Humidity 1 humidity-channel-1 0x22 PERCENTAGE
36 HUMI2 Humidity 2 humidity-channel-2 0x23 PERCENTAGE
37 HUMI3 Humidity 3 humidity-channel-3 0x24 PERCENTAGE
38 HUMI4 Humidity 4 humidity-channel-4 0x25 PERCENTAGE
39 HUMI5 Humidity 5 humidity-channel-5 0x26 PERCENTAGE
40 HUMI6 Humidity 6 humidity-channel-6 0x27 PERCENTAGE
41 HUMI7 Humidity 7 humidity-channel-7 0x28 PERCENTAGE
42 HUMI8 Humidity 8 humidity-channel-8 0x29 PERCENTAGE
43 SOILTEMP1 Soil Temperature 1 temperature-soil-channel-1 0x2b TEMPERATURE
44 SOILTEMP2 Soil Temperature 2 temperature-soil-channel-2 0x2d TEMPERATURE
45 SOILTEMP3 Soil Temperature 3 temperature-soil-channel-3 0x2f TEMPERATURE
46 SOILTEMP4 Soil Temperature 4 temperature-soil-channel-4 0x31 TEMPERATURE
47 SOILTEMP5 Soil Temperature 5 temperature-soil-channel-5 0x33 TEMPERATURE
48 SOILTEMP6 Soil Temperature 6 temperature-soil-channel-6 0x35 TEMPERATURE
49 SOILTEMP7 Soil Temperature 7 temperature-soil-channel-7 0x37 TEMPERATURE
50 SOILTEMP8 Soil Temperature 8 temperature-soil-channel-8 0x39 TEMPERATURE
51 SOILTEMP9 Soil Temperature 9 temperature-soil-channel-9 0x3b TEMPERATURE
52 SOILTEMP10 Soil Temperature 10 temperature-soil-channel-10 0x3d TEMPERATURE
53 SOILTEMP11 Soil Temperature 11 temperature-soil-channel-11 0x3f TEMPERATURE
54 SOILTEMP12 Soil Temperature 12 temperature-soil-channel-12 0x41 TEMPERATURE
55 SOILTEMP13 Soil Temperature 13 temperature-soil-channel-13 0x43 TEMPERATURE
56 SOILTEMP14 Soil Temperature 14 temperature-soil-channel-14 0x45 TEMPERATURE
57 SOILTEMP15 Soil Temperature 15 temperature-soil-channel-15 0x47 TEMPERATURE
58 SOILTEMP16 Soil Temperature 16 temperature-soil-channel-16 0x49 TEMPERATURE
59 SOILMOISTURE1 Soil Moisture 1 moisture-soil-channel-1 0x2c moisture PERCENTAGE
60 SOILMOISTURE2 Soil Moisture 2 moisture-soil-channel-2 0x2e moisture PERCENTAGE
61 SOILMOISTURE3 Soil Moisture 3 moisture-soil-channel-3 0x30 moisture PERCENTAGE
62 SOILMOISTURE4 Soil Moisture 4 moisture-soil-channel-4 0x32 moisture PERCENTAGE
63 SOILMOISTURE5 Soil Moisture 5 moisture-soil-channel-5 0x34 moisture PERCENTAGE
64 SOILMOISTURE6 Soil Moisture 6 moisture-soil-channel-6 0x36 moisture PERCENTAGE
65 SOILMOISTURE7 Soil Moisture 7 moisture-soil-channel-7 0x38 moisture PERCENTAGE
66 SOILMOISTURE8 Soil Moisture 8 moisture-soil-channel-8 0x3a moisture PERCENTAGE
67 SOILMOISTURE9 Soil Moisture 9 moisture-soil-channel-9 0x3c moisture PERCENTAGE
68 SOILMOISTURE10 Soil Moisture 10 moisture-soil-channel-10 0x3e moisture PERCENTAGE
69 SOILMOISTURE11 Soil Moisture 11 moisture-soil-channel-11 0x40 moisture PERCENTAGE
70 SOILMOISTURE12 Soil Moisture 12 moisture-soil-channel-12 0x42 moisture PERCENTAGE
71 SOILMOISTURE13 Soil Moisture 13 moisture-soil-channel-13 0x44 moisture PERCENTAGE
72 SOILMOISTURE14 Soil Moisture 14 moisture-soil-channel-14 0x46 moisture PERCENTAGE
73 SOILMOISTURE15 Soil Moisture 15 moisture-soil-channel-15 0x48 moisture PERCENTAGE
74 SOILMOISTURE16 Soil Moisture 16 moisture-soil-channel-16 0x4a moisture PERCENTAGE
75 LOWBATT Low Battery 0x4c 1
76 PM25_24HAVG1 PM2.5 Air Quality 24 hour average channel 1 air-quality-24-hour-average-channel-1 0x4d PM25
77 PM25_24HAVG2 PM2.5 Air Quality 24 hour average channel 2 air-quality-24-hour-average-channel-2 0x4e PM25
78 PM25_24HAVG3 PM2.5 Air Quality 24 hour average channel 3 air-quality-24-hour-average-channel-3 0x4f PM25
79 PM25_24HAVG4 PM2.5 Air Quality 24 hour average channel 4 air-quality-24-hour-average-channel-4 0x50 PM25
80 PM25_CH1 PM2.5 Air Quality channel 1 air-quality-channel-1 0x2a PM25
81 PM25_CH2 PM2.5 Air Quality channel 2 air-quality-channel-2 0x51 PM25
82 PM25_CH3 PM2.5 Air Quality channel 3 air-quality-channel-3 0x52 PM25
83 PM25_CH4 PM2.5 Air Quality channel 4 air-quality-channel-4 0x53 PM25
84 LEAK_CH1 Leak channel 1 water-leak-channel-1 0x58 WATER_LEAK_DETECTION
85 LEAK_CH2 Leak channel 2 water-leak-channel-2 0x59 WATER_LEAK_DETECTION
86 LEAK_CH3 Leak channel 3 water-leak-channel-3 0x5a WATER_LEAK_DETECTION
87 LEAK_CH4 Leak channel 4 water-leak-channel-4 0x5b WATER_LEAK_DETECTION
88 LIGHTNING lightning distance 1~40KM lightning-distance 0x60 LIGHTNING_DISTANCE
89 LIGHTNING_TIME lightning happened time lightning-time 0x61 LIGHTNING_TIME
90 LIGHTNING_POWER lightning counter for the day lightning-counter 0x62 LIGHTNING_COUNTER
91 TF_USR1 Soil or Water temperature channel 1 temperature-external-channel-1 0x63 TEMPERATURE
92 TF_USR2 Soil or Water temperature channel 2 temperature-external-channel-2 0x64 TEMPERATURE
93 TF_USR3 Soil or Water temperature channel 3 temperature-external-channel-3 0x65 TEMPERATURE
94 TF_USR4 Soil or Water temperature channel 4 temperature-external-channel-4 0x66 TEMPERATURE
95 TF_USR5 Soil or Water temperature channel 5 temperature-external-channel-5 0x67 TEMPERATURE
96 TF_USR6 Soil or Water temperature channel 6 temperature-external-channel-6 0x68 TEMPERATURE
97 TF_USR7 Soil or Water temperature channel 7 temperature-external-channel-7 0x69 TEMPERATURE
98 TF_USR8 Soil or Water temperature channel 8 temperature-external-channel-8 0x6a TEMPERATURE
99 ITEM_SENSOR_CO2 Temperature (CO₂-Sensor) sensor-co2-temperature 0x70 0 TEMPERATURE
100 ITEM_SENSOR_CO2 Humidity (CO₂-Sensor) sensor-co2-humidity 0x70 1 PERCENTAGE
101 ITEM_SENSOR_CO2 PM10 Air Quality (CO₂-Sensor) sensor-co2-pm10 0x70 2 PM10
102 ITEM_SENSOR_CO2 PM10 Air Quality 24 hour average (CO₂-Sensor) sensor-co2-pm10-24-hour-average 0x70 3 PM10
103 ITEM_SENSOR_CO2 PM2.5 Air Quality (CO₂-Sensor) sensor-co2-pm25 0x70 4 PM25
104 ITEM_SENSOR_CO2 PM2.5 Air Quality 24 hour average (CO₂-Sensor) sensor-co2-pm25-24-hour-average 0x70 5 PM25
105 ITEM_SENSOR_CO2 CO₂ sensor-co2-co2 0x70 6 CO2
106 ITEM_SENSOR_CO2 CO₂ 24 hour average sensor-co2-co2-24-hour-average 0x70 7 CO2
107 ITEM_SENSOR_CO2 Battery Level 0x70 8 1
108 ITEM_LEAF_WETNESS_CH1 Leaf Moisture channel 1 leaf-wetness-channel-1 0x72 moisture PERCENTAGE
109 ITEM_LEAF_WETNESS_CH2 Leaf Moisture channel 2 leaf-wetness-channel-2 0x73 moisture PERCENTAGE
110 ITEM_LEAF_WETNESS_CH3 Leaf Moisture channel 3 leaf-wetness-channel-3 0x74 moisture PERCENTAGE
111 ITEM_LEAF_WETNESS_CH4 Leaf Moisture channel 4 leaf-wetness-channel-4 0x75 moisture PERCENTAGE
112 ITEM_LEAF_WETNESS_CH5 Leaf Moisture channel 5 leaf-wetness-channel-5 0x76 moisture PERCENTAGE
113 ITEM_LEAF_WETNESS_CH6 Leaf Moisture channel 6 leaf-wetness-channel-6 0x77 moisture PERCENTAGE
114 ITEM_LEAF_WETNESS_CH7 Leaf Moisture channel 7 leaf-wetness-channel-7 0x78 moisture PERCENTAGE
115 ITEM_LEAF_WETNESS_CH8 Leaf Moisture channel 8 leaf-wetness-channel-8 0x79 moisture PERCENTAGE

View File

@ -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");