]> git.basschouten.com Git - openhab-addons.git/blob
c5085977766360feadff65bc2a51976fe43b0246
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.fineoffsetweatherstation.internal.domain;
14
15 import static javax.measure.MetricPrefix.HECTO;
16 import static javax.measure.MetricPrefix.KILO;
17 import static javax.measure.MetricPrefix.MILLI;
18 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_CO2;
19 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_HUMIDITY;
20 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_ILLUMINATION;
21 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_LIGHTNING_COUNTER;
22 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_LIGHTNING_DISTANCE;
23 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_LIGHTNING_TIME;
24 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_PM10;
25 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_PM25;
26 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_PRESSURE;
27 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_RAIN;
28 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_RAIN_RATE;
29 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_TEMPERATURE;
30 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_UV_RADIATION;
31 import static org.openhab.binding.fineoffsetweatherstation.internal.FineOffsetWeatherStationBindingConstants.CHANNEL_TYPE_WATER_LEAK_DETECTION;
32 import static org.openhab.binding.fineoffsetweatherstation.internal.Utils.toInt16;
33 import static org.openhab.binding.fineoffsetweatherstation.internal.Utils.toUInt16;
34 import static org.openhab.binding.fineoffsetweatherstation.internal.Utils.toUInt32;
35 import static org.openhab.binding.fineoffsetweatherstation.internal.Utils.toUInt8;
36 import static org.openhab.core.library.unit.SIUnits.CELSIUS;
37 import static org.openhab.core.library.unit.SIUnits.METRE;
38 import static org.openhab.core.library.unit.SIUnits.PASCAL;
39 import static org.openhab.core.library.unit.SIUnits.SQUARE_METRE;
40 import static org.openhab.core.library.unit.Units.DEGREE_ANGLE;
41 import static org.openhab.core.library.unit.Units.METRE_PER_SECOND;
42 import static org.openhab.core.library.unit.Units.MICROGRAM_PER_CUBICMETRE;
43 import static org.openhab.core.library.unit.Units.MILLIMETRE_PER_HOUR;
44 import static org.openhab.core.library.unit.Units.PARTS_PER_MILLION;
45 import static org.openhab.core.library.unit.Units.PERCENT;
46
47 import java.time.Instant;
48 import java.time.ZonedDateTime;
49 import java.util.function.BiFunction;
50
51 import javax.measure.Unit;
52
53 import org.eclipse.jdt.annotation.NonNullByDefault;
54 import org.eclipse.jdt.annotation.Nullable;
55 import org.openhab.binding.fineoffsetweatherstation.internal.Utils;
56 import org.openhab.core.library.types.DateTimeType;
57 import org.openhab.core.library.types.DecimalType;
58 import org.openhab.core.library.types.OnOffType;
59 import org.openhab.core.library.types.QuantityType;
60 import org.openhab.core.library.unit.Units;
61 import org.openhab.core.thing.type.ChannelTypeUID;
62 import org.openhab.core.types.State;
63 import org.openhab.core.types.UnDefType;
64
65 /**
66  * Represents the measured type with conversion from the sensors' bytes to the openHAB state.
67  *
68  * @author Andreas Berger - Initial contribution
69  */
70 @NonNullByDefault
71 public enum MeasureType {
72
73     TEMPERATURE(CELSIUS, 2, CHANNEL_TYPE_TEMPERATURE, (data, offset) -> toInt16(data, offset) / 10.),
74
75     PERCENTAGE(PERCENT, 1, CHANNEL_TYPE_HUMIDITY, (data, offset) -> toUInt8(data[offset])),
76
77     PRESSURE(HECTO(PASCAL), 2, CHANNEL_TYPE_PRESSURE, (data, offset) -> toUInt16(data, offset) / 10.),
78
79     DEGREE(DEGREE_ANGLE, 2, null, Utils::toUInt16),
80
81     SPEED(METRE_PER_SECOND, 2, null, (data, offset) -> toUInt16(data, offset) / 10.),
82
83     HEIGHT(MILLI(METRE), 2, CHANNEL_TYPE_RAIN, (data, offset) -> toUInt16(data, offset) / 10.),
84
85     HEIGHT_BIG(MILLI(METRE), 4, CHANNEL_TYPE_RAIN, (data, offset) -> toUInt32(data, offset) / 10.),
86
87     HEIGHT_PER_HOUR(MILLIMETRE_PER_HOUR, 2, CHANNEL_TYPE_RAIN_RATE, (data, offset) -> toUInt16(data, offset) / 10.),
88
89     HEIGHT_PER_HOUR_BIG(MILLIMETRE_PER_HOUR, 4, CHANNEL_TYPE_RAIN_RATE, (data, offset) -> toUInt32(data, offset) / 10.),
90
91     LUX(Units.LUX, 4, CHANNEL_TYPE_ILLUMINATION, (data, offset) -> toUInt32(data, offset) / 10.),
92
93     PM25(MICROGRAM_PER_CUBICMETRE, 2, CHANNEL_TYPE_PM25, (data, offset) -> toUInt16(data, offset) / 10.),
94
95     PM10(MICROGRAM_PER_CUBICMETRE, 2, CHANNEL_TYPE_PM10, (data, offset) -> toUInt16(data, offset) / 10.),
96
97     CO2(PARTS_PER_MILLION, 2, CHANNEL_TYPE_CO2, Utils::toUInt16),
98
99     WATER_LEAK_DETECTION(1, CHANNEL_TYPE_WATER_LEAK_DETECTION,
100             (data, offset, context) -> OnOffType.from(toUInt8(data[offset]) != 0)),
101
102     LIGHTNING_DISTANCE(KILO(METRE), 1, CHANNEL_TYPE_LIGHTNING_DISTANCE, (data, offset) -> {
103         int distance = toUInt8(data[offset]);
104         if (distance == 0xFF) {
105             return null;
106         }
107         return distance;
108     }),
109
110     LIGHTNING_COUNTER(4, CHANNEL_TYPE_LIGHTNING_COUNTER,
111             (data, offset, context) -> new DecimalType(toUInt32(data, offset))),
112
113     LIGHTNING_TIME(4, CHANNEL_TYPE_LIGHTNING_TIME, (data, offset, context) -> {
114         int epochSecond = toUInt32(data, offset);
115         if (epochSecond == 0xFFFFFFFF) {
116             return UnDefType.UNDEF;
117         }
118         return new DateTimeType(ZonedDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), context.getZoneId()));
119     }),
120
121     MILLIWATT_PER_SQUARE_METRE(MILLI(Units.WATT).divide(SQUARE_METRE), 2, CHANNEL_TYPE_UV_RADIATION,
122             (data, offset) -> Utils.toUInt16(data, offset) / 10.),
123
124     BYTE(1, null, (data, offset, context) -> new DecimalType(toUInt8(data[offset]))),
125
126     DATE_TIME2(6, null, (data, offset, context) -> new DateTimeType(
127             ZonedDateTime.ofInstant(Instant.ofEpochSecond(toUInt32(data, offset)), context.getZoneId())));
128
129     private final int byteSize;
130     private final @Nullable ChannelTypeUID channelTypeUID;
131     private final StateConverter stateConverter;
132
133     /**
134      * @param unit the unit
135      * @param byteSize the size in the sensors' payload
136      * @param channelTypeUID the channel type
137      * @param valueExtractor a function to extract the sensor data into a number of the dimension defined by the unit
138      */
139     MeasureType(Unit<?> unit, int byteSize, @Nullable ChannelTypeUID channelTypeUID,
140             BiFunction<byte[], Integer, @Nullable Number> valueExtractor) {
141         this(byteSize, channelTypeUID, (bytes, offset, context) -> {
142             Number value = valueExtractor.apply(bytes, offset);
143             return value == null ? UnDefType.UNDEF : new QuantityType<>(value, unit);
144         });
145     }
146
147     /**
148      * @param byteSize the size in the sensors' payload
149      * @param channelTypeUID the channel type
150      * @param stateConverter a function to extract the sensor data into the openHAB's state
151      */
152     MeasureType(int byteSize, @Nullable ChannelTypeUID channelTypeUID, StateConverter stateConverter) {
153         this.byteSize = byteSize;
154         this.channelTypeUID = channelTypeUID;
155         this.stateConverter = stateConverter;
156     }
157
158     public int getByteSize() {
159         return byteSize;
160     }
161
162     public @Nullable ChannelTypeUID getChannelTypeId() {
163         return channelTypeUID;
164     }
165
166     public @Nullable State toState(byte[] data, int offset, ConversionContext context) {
167         return stateConverter.toState(data, offset, context);
168     }
169
170     private interface StateConverter {
171         @Nullable
172         State toState(byte[] data, int offset, ConversionContext context);
173     }
174 }