2 * Copyright (c) 2010-2022 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.enocean.internal.eep.A5_20;
15 import static org.openhab.binding.enocean.internal.EnOceanBindingConstants.*;
17 import java.util.function.Function;
19 import javax.measure.quantity.Temperature;
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;
33 * Heating radiator valve actuating drive with feed and room temperature measurement, local set point control and
36 * @author Dominik Vorreiter - Initial contribution
38 public class A5_20_04 extends A5_20 {
44 public A5_20_04(ERP1Message packet) {
49 protected String convertToEventImpl(String channelId, String channelTypeId, String lastEvent,
50 Configuration config) {
52 case CHANNEL_STATUS_REQUEST_EVENT:
53 return getStatusRequestEvent();
59 private String getStatusRequestEvent() {
60 return Boolean.valueOf(getBit(getDB_0Value(), 6)).toString();
61 // return getBit(getDB_0Value(), 6) ? "triggered" : null;
64 private byte getPos(Function<String, State> getCurrentStateFunc) {
65 State current = getCurrentStateFunc.apply(CHANNEL_VALVE_POSITION);
67 if ((current != null) && (current instanceof DecimalType)) {
68 DecimalType state = current.as(DecimalType.class);
71 return state.byteValue();
78 private byte getTsp(Function<String, State> getCurrentStateFunc) {
79 State current = getCurrentStateFunc.apply(CHANNEL_TEMPERATURE_SETPOINT);
81 double value = 20.0; // 20 °C
83 if ((current != null) && (current instanceof QuantityType)) {
84 @SuppressWarnings("unchecked")
85 QuantityType<Temperature> raw = current.as(QuantityType.class);
88 QuantityType<Temperature> celsius = raw.toUnit(SIUnits.CELSIUS);
90 if (celsius != null) {
91 value = celsius.doubleValue();
96 return (byte) ((value - 10.0) * (255.0 / 20.0));
99 private byte getMc(Function<String, State> getCurrentStateFunc) {
100 State current = getCurrentStateFunc.apply(CHANNEL_MEASUREMENT_CONTROL);
102 if ((current != null) && (current instanceof OnOffType)) {
103 OnOffType state = current.as(OnOffType.class);
106 return (byte) (state.equals(OnOffType.ON) ? 0x00 : 0x40);
113 private byte getWuc(Function<String, State> getCurrentStateFunc) {
114 State current = getCurrentStateFunc.apply(CHANNEL_WAKEUPCYCLE);
116 if ((current != null) && (current instanceof DecimalType)) {
117 DecimalType state = current.as(DecimalType.class);
120 return (byte) (state.byteValue() & 0x3F);
124 return 0x13; // 19 = 600 sec = 10 min
127 private byte getDso(Function<String, State> getCurrentStateFunc) {
128 State current = getCurrentStateFunc.apply(CHANNEL_DISPLAY_ORIENTATION);
130 if ((current != null) && (current instanceof DecimalType)) {
131 DecimalType state = current.as(DecimalType.class);
134 return (byte) (((state.byteValue() / 90) << 4) & 0x30);
141 private byte getBlc(Function<String, State> getCurrentStateFunc) {
142 State current = getCurrentStateFunc.apply(CHANNEL_BUTTON_LOCK);
144 if ((current != null) && (current instanceof OnOffType)) {
145 OnOffType state = current.as(OnOffType.class);
148 return (byte) (state.equals(OnOffType.ON) ? 0x04 : 0x00);
152 return 0x00; // unlocked
155 private byte getSer(Function<String, State> getCurrentStateFunc) {
156 State current = getCurrentStateFunc.apply(CHANNEL_SERVICECOMMAND);
158 if ((current != null) && (current instanceof DecimalType)) {
159 DecimalType state = current.as(DecimalType.class);
162 return (byte) (state.byteValue() & 0x03);
166 return 0x00; // 0 = no change
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));
179 setData(db3, db2, db1, db0);
186 protected State convertToStateImpl(String channelId, String channelTypeId,
187 Function<String, State> getCurrentStateFunc, Configuration config) {
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();
205 return UnDefType.UNDEF;
208 private State getTemperature() {
209 boolean fl = getBit(getDB_0Value(), 0);
210 boolean mst = getBit(getDB_0Value(), 7);
213 return UnDefType.UNDEF;
216 double value = getDB_1Value() * (20.0 / 255.0) + 10.0;
218 return new QuantityType<>(value, SIUnits.CELSIUS);
221 private State getFailureCode() {
222 boolean fl = getBit(getDB_0Value(), 0);
225 return new QuantityType<>(-1, Units.ONE);
228 return new QuantityType<>(getDB_1Value(), Units.ONE);
231 private State getMeasurementControl() {
232 return getBit(getDB_0Value(), 7) ? OnOffType.OFF : OnOffType.ON;
235 private State getFeedTemperature() {
236 boolean ts = getBit(getDB_0Value(), 1);
237 boolean mst = getBit(getDB_0Value(), 7);
240 return UnDefType.UNDEF;
243 double value = getDB_2Value() * (60.0 / 255.0) + 20.0;
245 return new QuantityType<>(value, SIUnits.CELSIUS);
248 private State getTemperatureSetpoint() {
249 boolean ts = getBit(getDB_0Value(), 1);
252 return UnDefType.UNDEF;
255 double value = getDB_2Value() * (20.0 / 255.0) + 10.0;
257 return new QuantityType<>(value, SIUnits.CELSIUS);
260 private State getButtonLock() {
261 return getBit(getDB_0Value(), 2) ? OnOffType.ON : OnOffType.OFF;
264 private State getValvePosition() {
265 return new QuantityType<>(getDB_3Value(), Units.PERCENT);