]> git.basschouten.com Git - openhab-addons.git/blob
ca0a4154220f1723fd69d52f4668e90ea5648b83
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.onewire.internal.device;
14
15 import static org.openhab.binding.onewire.internal.OwBindingConstants.*;
16 import static org.openhab.core.library.unit.MetricPrefix.MILLI;
17
18 import javax.measure.quantity.Dimensionless;
19 import javax.measure.quantity.Temperature;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.onewire.internal.OwException;
23 import org.openhab.binding.onewire.internal.SensorId;
24 import org.openhab.binding.onewire.internal.Util;
25 import org.openhab.binding.onewire.internal.handler.OwBaseThingHandler;
26 import org.openhab.binding.onewire.internal.handler.OwserverBridgeHandler;
27 import org.openhab.binding.onewire.internal.owserver.OwserverDeviceParameter;
28 import org.openhab.core.config.core.Configuration;
29 import org.openhab.core.library.types.DecimalType;
30 import org.openhab.core.library.types.QuantityType;
31 import org.openhab.core.library.unit.SIUnits;
32 import org.openhab.core.library.unit.SmartHomeUnits;
33 import org.openhab.core.thing.Channel;
34 import org.openhab.core.thing.Thing;
35 import org.openhab.core.types.State;
36 import org.openhab.core.types.UnDefType;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * The {@link DS2438} class defines an DS2438 device
42  *
43  * @author Jan N. Klug - Initial contribution
44  */
45 @NonNullByDefault
46 public class DS2438 extends AbstractOwDevice {
47     private final Logger logger = LoggerFactory.getLogger(DS2438.class);
48
49     public enum LightSensorType {
50         ELABNET_V1,
51         ELABNET_V2,
52         IBUTTONLINK
53     }
54
55     public enum CurrentSensorType {
56         INTERNAL,
57         IBUTTONLINK
58     }
59
60     private LightSensorType lightSensorType = LightSensorType.ELABNET_V1;
61     private CurrentSensorType currentSensorType = CurrentSensorType.INTERNAL;
62
63     private final OwserverDeviceParameter temperatureParameter = new OwserverDeviceParameter("/temperature");
64     private OwserverDeviceParameter humidityParameter = new OwserverDeviceParameter("/humidity");
65     private final OwserverDeviceParameter voltageParameter = new OwserverDeviceParameter("/VAD");
66     private final OwserverDeviceParameter currentParamater = new OwserverDeviceParameter("/vis");
67     private final OwserverDeviceParameter supplyVoltageParameter = new OwserverDeviceParameter("/VDD");
68
69     public DS2438(SensorId sensorId, OwBaseThingHandler callback) {
70         super(sensorId, callback);
71     }
72
73     @Override
74     public void configureChannels() {
75         Thing thing = callback.getThing();
76
77         Channel humidityChannel = thing.getChannel(CHANNEL_HUMIDITY);
78         if (humidityChannel != null) {
79             Configuration channelConfiguration = humidityChannel.getConfiguration();
80             if (channelConfiguration.get(CONFIG_HUMIDITY) != null) {
81                 humidityParameter = new OwserverDeviceParameter((String) channelConfiguration.get(CONFIG_HUMIDITY));
82             } else {
83                 humidityParameter = new OwserverDeviceParameter("/humidity");
84             }
85         }
86
87         isConfigured = true;
88     }
89
90     @Override
91     public void refresh(OwserverBridgeHandler bridgeHandler, Boolean forcedRefresh) throws OwException {
92         if (isConfigured) {
93             logger.trace("refresh of sensor {} started", sensorId);
94             double Vcc = 5.0;
95
96             if (enabledChannels.contains(CHANNEL_TEMPERATURE) || enabledChannels.contains(CHANNEL_HUMIDITY)
97                     || enabledChannels.contains(CHANNEL_ABSOLUTE_HUMIDITY)
98                     || enabledChannels.contains(CHANNEL_DEWPOINT)) {
99                 QuantityType<Temperature> temperature = new QuantityType<>(
100                         (DecimalType) bridgeHandler.readDecimalType(sensorId, temperatureParameter), SIUnits.CELSIUS);
101                 logger.trace("read temperature {} from {}", temperature, sensorId);
102
103                 if (enabledChannels.contains(CHANNEL_TEMPERATURE)) {
104                     callback.postUpdate(CHANNEL_TEMPERATURE, temperature);
105                 }
106
107                 if (enabledChannels.contains(CHANNEL_HUMIDITY) || enabledChannels.contains(CHANNEL_ABSOLUTE_HUMIDITY)
108                         || enabledChannels.contains(CHANNEL_DEWPOINT)) {
109                     QuantityType<Dimensionless> humidity = new QuantityType<>(
110                             (DecimalType) bridgeHandler.readDecimalType(sensorId, humidityParameter),
111                             SmartHomeUnits.PERCENT);
112                     logger.trace("read humidity {} from {}", humidity, sensorId);
113
114                     if (enabledChannels.contains(CHANNEL_HUMIDITY)) {
115                         callback.postUpdate(CHANNEL_HUMIDITY, humidity);
116                     }
117
118                     if (enabledChannels.contains(CHANNEL_ABSOLUTE_HUMIDITY)) {
119                         callback.postUpdate(CHANNEL_ABSOLUTE_HUMIDITY,
120                                 Util.calculateAbsoluteHumidity(temperature, humidity));
121                     }
122
123                     if (enabledChannels.contains(CHANNEL_DEWPOINT)) {
124                         callback.postUpdate(CHANNEL_DEWPOINT, Util.calculateDewpoint(temperature, humidity));
125                     }
126                 }
127             }
128
129             if (enabledChannels.contains(CHANNEL_VOLTAGE)) {
130                 double measured = ((DecimalType) bridgeHandler.readDecimalType(sensorId, voltageParameter))
131                         .doubleValue();
132                 if (measured < 0 || measured > 10.0) {
133                     // workaround bug in DS2438
134                     measured = 0.0;
135                 }
136                 State voltage = new QuantityType<>(measured, SmartHomeUnits.VOLT);
137
138                 logger.trace("read voltage {} from {}", voltage, sensorId);
139                 callback.postUpdate(CHANNEL_VOLTAGE, voltage);
140             }
141
142             if (enabledChannels.contains(CHANNEL_CURRENT)) {
143                 if (currentSensorType == CurrentSensorType.IBUTTONLINK) {
144                     State current = bridgeHandler.readDecimalType(sensorId, voltageParameter);
145                     if (current instanceof DecimalType) {
146                         double currentDouble = ((DecimalType) current).doubleValue();
147                         if (currentDouble >= 0.1 || currentDouble <= 3.78) {
148                             current = new QuantityType<>(currentDouble * 5.163 + 0.483, SmartHomeUnits.AMPERE);
149                         }
150                         callback.postUpdate(CHANNEL_CURRENT, current);
151                     } else {
152                         callback.postUpdate(CHANNEL_CURRENT, UnDefType.UNDEF);
153                     }
154                 } else {
155                     State current = new QuantityType<>(
156                             (DecimalType) bridgeHandler.readDecimalType(sensorId, currentParamater),
157                             MILLI(SmartHomeUnits.AMPERE));
158                     callback.postUpdate(CHANNEL_CURRENT, current);
159                 }
160             }
161
162             if (enabledChannels.contains(CHANNEL_SUPPLYVOLTAGE)) {
163                 Vcc = ((DecimalType) bridgeHandler.readDecimalType(sensorId, supplyVoltageParameter)).doubleValue();
164                 State supplyVoltage = new QuantityType<>(Vcc, SmartHomeUnits.VOLT);
165                 callback.postUpdate(CHANNEL_SUPPLYVOLTAGE, supplyVoltage);
166             }
167
168             if (enabledChannels.contains(CHANNEL_LIGHT)) {
169                 switch (lightSensorType) {
170                     case ELABNET_V2:
171                         State light = bridgeHandler.readDecimalType(sensorId, currentParamater);
172                         if (light instanceof DecimalType) {
173                             light = new QuantityType<>(
174                                     Math.round(Math.pow(10, ((DecimalType) light).doubleValue() / 47 * 1000)),
175                                     SmartHomeUnits.LUX);
176                             callback.postUpdate(CHANNEL_LIGHT, light);
177                         }
178                         break;
179                     case ELABNET_V1:
180                         light = bridgeHandler.readDecimalType(sensorId, currentParamater);
181                         if (light instanceof DecimalType) {
182                             light = new QuantityType<>(Math.round(Math
183                                     .exp(1.059 * Math.log(1000000 * ((DecimalType) light).doubleValue() / (4096 * 390))
184                                             + 4.518)
185                                     * 20000), SmartHomeUnits.LUX);
186                             callback.postUpdate(CHANNEL_LIGHT, light);
187                         }
188                         break;
189                     case IBUTTONLINK:
190                         double measured = ((DecimalType) bridgeHandler.readDecimalType(sensorId, voltageParameter))
191                                 .doubleValue();
192                         if (measured <= 0 || measured > 10.0) {
193                             // workaround bug in DS2438
194                             light = new QuantityType<>(0, SmartHomeUnits.LUX);
195                         } else {
196                             light = new QuantityType<>(Math.pow(10, (65 / 7.5) - (47 / 7.5) * (Vcc / measured)),
197                                     SmartHomeUnits.LUX);
198                         }
199                         callback.postUpdate(CHANNEL_LIGHT, light);
200                 }
201             }
202         }
203     }
204
205     /**
206      * set the type of the attached light sensor
207      *
208      * @param lightSensorType
209      */
210     public void setLightSensorType(LightSensorType lightSensorType) {
211         this.lightSensorType = lightSensorType;
212     }
213
214     /**
215      * set the type of the attached current sensor
216      *
217      * @param currentSensorType
218      */
219     public void setCurrentSensorType(CurrentSensorType currentSensorType) {
220         this.currentSensorType = currentSensorType;
221     }
222 }