]> git.basschouten.com Git - openhab-addons.git/blob
63df82925bad6e6da125fc182c16734be1294c49
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.enocean.internal.eep.A5_20;
14
15 import static org.openhab.binding.enocean.internal.EnOceanBindingConstants.*;
16
17 import java.util.function.Function;
18
19 import javax.measure.quantity.Temperature;
20
21 import org.openhab.binding.enocean.internal.messages.ERP1Message;
22 import org.openhab.core.config.core.Configuration;
23 import org.openhab.core.library.types.DecimalType;
24 import org.openhab.core.library.types.OnOffType;
25 import org.openhab.core.library.types.QuantityType;
26 import org.openhab.core.library.unit.SIUnits;
27 import org.openhab.core.library.unit.Units;
28 import org.openhab.core.types.Command;
29 import org.openhab.core.types.State;
30 import org.openhab.core.types.UnDefType;
31
32 /**
33  * Heating radiator valve actuating drive with feed and room temperature measurement, local set point control and
34  * display
35  *
36  * @author Dominik Vorreiter - Initial contribution
37  */
38 public class A5_20_04 extends A5_20 {
39
40     public A5_20_04() {
41         super();
42     }
43
44     public A5_20_04(ERP1Message packet) {
45         super(packet);
46     }
47
48     @Override
49     protected String convertToEventImpl(String channelId, String channelTypeId, String lastEvent,
50             Configuration config) {
51         switch (channelId) {
52             case CHANNEL_STATUS_REQUEST_EVENT:
53                 return getStatusRequestEvent();
54         }
55
56         return null;
57     }
58
59     private String getStatusRequestEvent() {
60         return Boolean.valueOf(getBit(getDB_0Value(), 6)).toString();
61         // return getBit(getDB_0Value(), 6) ? "triggered" : null;
62     }
63
64     private byte getPos(Function<String, State> getCurrentStateFunc) {
65         State current = getCurrentStateFunc.apply(CHANNEL_VALVE_POSITION);
66
67         if ((current != null) && (current instanceof DecimalType)) {
68             DecimalType state = current.as(DecimalType.class);
69
70             if (state != null) {
71                 return state.byteValue();
72             }
73         }
74
75         return 25; // 25 %
76     }
77
78     private byte getTsp(Function<String, State> getCurrentStateFunc) {
79         State current = getCurrentStateFunc.apply(CHANNEL_TEMPERATURE_SETPOINT);
80
81         double value = 20.0; // 20 °C
82
83         if ((current != null) && (current instanceof QuantityType)) {
84             @SuppressWarnings("unchecked")
85             QuantityType<Temperature> raw = current.as(QuantityType.class);
86
87             if (raw != null) {
88                 QuantityType<Temperature> celsius = raw.toUnit(SIUnits.CELSIUS);
89
90                 if (celsius != null) {
91                     value = celsius.doubleValue();
92                 }
93             }
94         }
95
96         return (byte) ((value - 10.0) * (255.0 / 20.0));
97     }
98
99     private byte getMc(Function<String, State> getCurrentStateFunc) {
100         State current = getCurrentStateFunc.apply(CHANNEL_MEASUREMENT_CONTROL);
101
102         if ((current != null) && (current instanceof OnOffType)) {
103             OnOffType state = current.as(OnOffType.class);
104
105             if (state != null) {
106                 return (byte) (state.equals(OnOffType.ON) ? 0x00 : 0x40);
107             }
108         }
109
110         return 0x00; // on
111     }
112
113     private byte getWuc(Function<String, State> getCurrentStateFunc) {
114         State current = getCurrentStateFunc.apply(CHANNEL_WAKEUPCYCLE);
115
116         if ((current != null) && (current instanceof DecimalType)) {
117             DecimalType state = current.as(DecimalType.class);
118
119             if (state != null) {
120                 return (byte) (state.byteValue() & 0x3F);
121             }
122         }
123
124         return 0x13; // 19 = 600 sec = 10 min
125     }
126
127     private byte getDso(Function<String, State> getCurrentStateFunc) {
128         State current = getCurrentStateFunc.apply(CHANNEL_DISPLAY_ORIENTATION);
129
130         if ((current != null) && (current instanceof DecimalType)) {
131             DecimalType state = current.as(DecimalType.class);
132
133             if (state != null) {
134                 return (byte) (((state.byteValue() / 90) << 4) & 0x30);
135             }
136         }
137
138         return 0x00; // 0°
139     }
140
141     private byte getBlc(Function<String, State> getCurrentStateFunc) {
142         State current = getCurrentStateFunc.apply(CHANNEL_BUTTON_LOCK);
143
144         if ((current != null) && (current instanceof OnOffType)) {
145             OnOffType state = current.as(OnOffType.class);
146
147             if (state != null) {
148                 return (byte) (state.equals(OnOffType.ON) ? 0x04 : 0x00);
149             }
150         }
151
152         return 0x00; // unlocked
153     }
154
155     private byte getSer(Function<String, State> getCurrentStateFunc) {
156         State current = getCurrentStateFunc.apply(CHANNEL_SERVICECOMMAND);
157
158         if ((current != null) && (current instanceof DecimalType)) {
159             DecimalType state = current.as(DecimalType.class);
160
161             if (state != null) {
162                 return (byte) (state.byteValue() & 0x03);
163             }
164         }
165
166         return 0x00; // 0 = no change
167     }
168
169     @Override
170     protected void convertFromCommandImpl(String channelId, String channelTypeId, Command command,
171             Function<String, State> getCurrentStateFunc, Configuration config) {
172         if (VIRTUALCHANNEL_SEND_COMMAND.equals(channelId)) {
173             byte db3 = getPos(getCurrentStateFunc);
174             byte db2 = getTsp(getCurrentStateFunc);
175             byte db1 = (byte) (0x00 | getMc(getCurrentStateFunc) | getWuc(getCurrentStateFunc));
176             byte db0 = (byte) (0x00 | getDso(getCurrentStateFunc) | TeachInBit | getBlc(getCurrentStateFunc)
177                     | getSer(getCurrentStateFunc));
178
179             setData(db3, db2, db1, db0);
180
181             return;
182         }
183     }
184
185     @Override
186     protected State convertToStateImpl(String channelId, String channelTypeId,
187             Function<String, State> getCurrentStateFunc, Configuration config) {
188         switch (channelId) {
189             case CHANNEL_VALVE_POSITION:
190                 return getValvePosition();
191             case CHANNEL_BUTTON_LOCK:
192                 return getButtonLock();
193             case CHANNEL_TEMPERATURE_SETPOINT:
194                 return getTemperatureSetpoint();
195             case CHANNEL_TEMPERATURE:
196                 return getTemperature();
197             case CHANNEL_FEED_TEMPERATURE:
198                 return getFeedTemperature();
199             case CHANNEL_MEASUREMENT_CONTROL:
200                 return getMeasurementControl();
201             case CHANNEL_FAILURE_CODE:
202                 return getFailureCode();
203         }
204
205         return UnDefType.UNDEF;
206     }
207
208     private State getTemperature() {
209         boolean fl = getBit(getDB_0Value(), 0);
210         boolean mst = getBit(getDB_0Value(), 7);
211
212         if (fl || mst) {
213             return UnDefType.UNDEF;
214         }
215
216         double value = getDB_1Value() * (20.0 / 255.0) + 10.0;
217
218         return new QuantityType<>(value, SIUnits.CELSIUS);
219     }
220
221     private State getFailureCode() {
222         boolean fl = getBit(getDB_0Value(), 0);
223
224         if (!fl) {
225             return new QuantityType<>(-1, Units.ONE);
226         }
227
228         return new QuantityType<>(getDB_1Value(), Units.ONE);
229     }
230
231     private State getMeasurementControl() {
232         return getBit(getDB_0Value(), 7) ? OnOffType.OFF : OnOffType.ON;
233     }
234
235     private State getFeedTemperature() {
236         boolean ts = getBit(getDB_0Value(), 1);
237         boolean mst = getBit(getDB_0Value(), 7);
238
239         if (ts || mst) {
240             return UnDefType.UNDEF;
241         }
242
243         double value = getDB_2Value() * (60.0 / 255.0) + 20.0;
244
245         return new QuantityType<>(value, SIUnits.CELSIUS);
246     }
247
248     private State getTemperatureSetpoint() {
249         boolean ts = getBit(getDB_0Value(), 1);
250
251         if (!ts) {
252             return UnDefType.UNDEF;
253         }
254
255         double value = getDB_2Value() * (20.0 / 255.0) + 10.0;
256
257         return new QuantityType<>(value, SIUnits.CELSIUS);
258     }
259
260     private State getButtonLock() {
261         return getBit(getDB_0Value(), 2) ? OnOffType.ON : OnOffType.OFF;
262     }
263
264     private State getValvePosition() {
265         return new QuantityType<>(getDB_3Value(), Units.PERCENT);
266     }
267 }