diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/README.md b/bundles/org.openhab.binding.fineoffsetweatherstation/README.md index 67192dfda..2759b046b 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/README.md +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/README.md @@ -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 diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/pom.xml b/bundles/org.openhab.binding.fineoffsetweatherstation/pom.xml index 7eefa47fc..3f766a2a3 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/pom.xml +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/pom.xml @@ -26,11 +26,6 @@ openHAB Add-ons :: Bundles :: Fine Offset Weather Station - - org.apache.commons - commons-csv - 1.9.0 - org.assertj assertj-core diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/discovery/FineOffsetGatewayDiscoveryService.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/discovery/FineOffsetGatewayDiscoveryService.java index 552c2e6b3..92e30db08 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/discovery/FineOffsetGatewayDiscoveryService.java +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/discovery/FineOffsetGatewayDiscoveryService.java @@ -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 result = gatewayQueryService.getMeasuredValues(); + Collection result = gatewayQueryService.getMeasuredValues(); logger.trace("found {} measured values via protocol {}", result.size(), protocol); if (!result.isEmpty()) { return protocol; diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Command.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Command.java index 0d044fae9..7f4d1bfd6 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Command.java +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Command.java @@ -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; diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Measurand.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Measurand.java new file mode 100644 index 000000000..bc600130f --- /dev/null +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Measurand.java @@ -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 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 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 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 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 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 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 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); + } + } +} diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Measurands.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Measurands.java deleted file mode 100644 index 27658feb4..000000000 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Measurands.java +++ /dev/null @@ -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 INSTANCES = new HashMap<>(); - private final Map> 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 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 parsers = parsersPerCode.computeIfAbsent(code, aByte -> new ArrayList<>()); - // noinspection ConstantConditions - if (parsers != null) { - parsers.add(parser); - } - }); - for (List 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 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 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 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 result) { - List 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; - } -} diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Protocol.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Protocol.java index 0ca9da2b6..1eb9ad301 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Protocol.java +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/Protocol.java @@ -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, diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/response/MeasuredValue.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/response/MeasuredValue.java index ba42b3c0a..45cb0e675 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/response/MeasuredValue.java +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/domain/response/MeasuredValue.java @@ -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 + '\'' + '}'; } } diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/handler/FineOffsetGatewayHandler.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/handler/FineOffsetGatewayHandler.java index aa91798d4..55837928e 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/handler/FineOffsetGatewayHandler.java +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/handler/FineOffsetGatewayHandler.java @@ -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 data = query(GatewayQueryService::getMeasuredValues); + Collection 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); } diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/handler/FineOffsetSensorHandler.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/handler/FineOffsetSensorHandler.java index 88506094b..116e22ec4 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/handler/FineOffsetSensorHandler.java +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/handler/FineOffsetSensorHandler.java @@ -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. * diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetDataParser.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetDataParser.java index 5bd28d0c4..2acad4a24 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetDataParser.java +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetDataParser.java @@ -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 getRainData(byte[] data, ConversionContext context) { + return readMeasuredValues(data, 5, context, Measurand.ParserCustomizationType.RAIN_READING); + } + + private List readMeasuredValues(byte[] data, int idx, ConversionContext context, + Measurand.@Nullable ParserCustomizationType protocol) { var size = toUInt16(data, 3); List 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; } diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetGatewayQueryService.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetGatewayQueryService.java index 7520f9540..fdcf5243e 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetGatewayQueryService.java +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetGatewayQueryService.java @@ -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 getMeasuredValues() { + public Collection getMeasuredValues() { + Map valuePerChannel = new LinkedHashMap<>(); + byte[] data = executeCommand(Command.CMD_GW1000_LIVEDATA); - if (data == null) { - return Collections.emptyList(); + if (data != null) { + List 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 measuredRainValues = fineOffsetDataParser.getRainData(data, conversionContext); + for (MeasuredValue measuredValue : measuredRainValues) { + valuePerChannel.put(measuredValue.getChannelId(), measuredValue); + } + } + + return valuePerChannel.values(); } protected byte @Nullable [] executeCommand(Command command) { diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/GatewayQueryService.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/GatewayQueryService.java index 4f28ac8f6..94ca5769f 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/GatewayQueryService.java +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/java/org/openhab/binding/fineoffsetweatherstation/internal/service/GatewayQueryService.java @@ -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 getMeasuredValues(); + public abstract Collection getMeasuredValues(); public GatewayQueryService(FineOffsetGatewayConfiguration config, @Nullable ThingStatusListener thingStatusListener) { diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/resources/OH-INF/i18n/fineoffsetweatherstation.properties b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/resources/OH-INF/i18n/fineoffsetweatherstation.properties index 81e8310c6..9ec4c045b 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/resources/OH-INF/i18n/fineoffsetweatherstation.properties +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/resources/OH-INF/i18n/fineoffsetweatherstation.properties @@ -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 diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/resources/measurands.csv b/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/resources/measurands.csv deleted file mode 100644 index 485826300..000000000 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/main/resources/measurands.csv +++ /dev/null @@ -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, diff --git a/bundles/org.openhab.binding.fineoffsetweatherstation/src/test/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetDataParserTest.java b/bundles/org.openhab.binding.fineoffsetweatherstation/src/test/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetDataParserTest.java index 52c765b7f..088d51819 100644 --- a/bundles/org.openhab.binding.fineoffsetweatherstation/src/test/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetDataParserTest.java +++ b/bundles/org.openhab.binding.fineoffsetweatherstation/src/test/java/org/openhab/binding/fineoffsetweatherstation/internal/service/FineOffsetDataParserTest.java @@ -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 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 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");