]> git.basschouten.com Git - openhab-addons.git/blob
efd0b4494e1bc74fa09ffb17d6edda5ff86a6379
[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.comfoair.internal;
14
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.HashMap;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Set;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.comfoair.internal.datatypes.ComfoAirDataType;
25 import org.openhab.binding.comfoair.internal.datatypes.DataTypeBoolean;
26 import org.openhab.binding.comfoair.internal.datatypes.DataTypeMessage;
27 import org.openhab.binding.comfoair.internal.datatypes.DataTypeNumber;
28 import org.openhab.binding.comfoair.internal.datatypes.DataTypeRPM;
29 import org.openhab.binding.comfoair.internal.datatypes.DataTypeTemperature;
30 import org.openhab.binding.comfoair.internal.datatypes.DataTypeTime;
31 import org.openhab.binding.comfoair.internal.datatypes.DataTypeVolt;
32 import org.openhab.core.library.types.DecimalType;
33 import org.openhab.core.library.types.QuantityType;
34 import org.openhab.core.types.Command;
35 import org.openhab.core.types.State;
36 import org.openhab.core.types.UnDefType;
37
38 /**
39  * Represents all valid commands which could be processed by this binding
40  *
41  * @author Holger Hees - Initial Contribution
42  * @author Hans Böhm - Refactoring
43  */
44 @NonNullByDefault
45 public enum ComfoAirCommandType {
46     /**
47      * Below all valid commands to change or read parameters from ComfoAir
48      *
49      * @param key
50      *            command name
51      * @param dataType
52      *            data type (can be: DataTypeBoolean.getInstance(), DataTypeMessage.getInstance(),
53      *            DataTypeNumber.getInstance(), DataTypeRPM.getInstance(), DataTypeTemperature.getInstance(),
54      *            DataTypeTime.getInstance(), DataTypeVolt.getInstance())
55      * @param possibleValues
56      *            possible values for write command, if it can only take certain values
57      * @param changeCommand
58      *            byte number for ComfoAir write command
59      * @param changeDataSize
60      *            size of bytes list for ComfoAir write command
61      * @param changeDataPos
62      *            position in bytes list to change
63      * @param changeAffected
64      *            list of affected commands (can be empty)
65      *            is mandatory for read-write command
66      * @param readCommand
67      *            request byte number for ComfoAir read command
68      * @param readReplyCommand
69      *            reply byte list size for ComfoAir read command (list of values only)
70      * @param readReplyDataPos
71      *            list of byte positions in reply bytes list from ComfoAir
72      * @param readReplyDataBits
73      *            byte value on readReplyDataPos position to be considered by command (used with
74      *            DataTypeBoolean.class dataType)
75      */
76     ACTIVATE(ComfoAirBindingConstants.CG_CONTROL_PREFIX + ComfoAirBindingConstants.CHANNEL_ACTIVATE,
77             DataTypeBoolean.getInstance(), new int[] { 0x03 }, Constants.REQUEST_SET_RS232, 1, 0,
78             Constants.EMPTY_TYPE_ARRAY),
79     MENU20_MODE(ComfoAirBindingConstants.CG_MENUP1_PREFIX + ComfoAirBindingConstants.CHANNEL_MENU20_MODE,
80             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 6 },
81             0x01),
82     MENU21_MODE(ComfoAirBindingConstants.CG_MENUP1_PREFIX + ComfoAirBindingConstants.CHANNEL_MENU21_MODE,
83             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 6 },
84             0x02),
85     MENU22_MODE(ComfoAirBindingConstants.CG_MENUP1_PREFIX + ComfoAirBindingConstants.CHANNEL_MENU22_MODE,
86             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 6 },
87             0x04),
88     MENU23_MODE(ComfoAirBindingConstants.CG_MENUP1_PREFIX + ComfoAirBindingConstants.CHANNEL_MENU23_MODE,
89             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 6 },
90             0x08),
91     MENU24_MODE(ComfoAirBindingConstants.CG_MENUP1_PREFIX + ComfoAirBindingConstants.CHANNEL_MENU24_MODE,
92             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 6 },
93             0x10),
94     MENU25_MODE(ComfoAirBindingConstants.CG_MENUP1_PREFIX + ComfoAirBindingConstants.CHANNEL_MENU25_MODE,
95             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 6 },
96             0x20),
97     MENU26_MODE(ComfoAirBindingConstants.CG_MENUP1_PREFIX + ComfoAirBindingConstants.CHANNEL_MENU26_MODE,
98             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 6 },
99             0x40),
100     MENU27_MODE(ComfoAirBindingConstants.CG_MENUP1_PREFIX + ComfoAirBindingConstants.CHANNEL_MENU27_MODE,
101             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 6 },
102             0x80),
103     MENU28_MODE(ComfoAirBindingConstants.CG_MENUP1_PREFIX + ComfoAirBindingConstants.CHANNEL_MENU28_MODE,
104             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 7 },
105             0x01),
106     MENU29_MODE(ComfoAirBindingConstants.CG_MENUP1_PREFIX + ComfoAirBindingConstants.CHANNEL_MENU29_MODE,
107             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 7 },
108             0x02),
109     BATHROOM_START_DELAY(ComfoAirBindingConstants.CG_MENUP2_PREFIX + ComfoAirBindingConstants.CHANNEL_BR_START_DELAY,
110             DataTypeNumber.getInstance(), Constants.REQUEST_SET_DELAYS, 8, 0, new ComfoAirCommandType[] { MENU21_MODE },
111             Constants.REQUEST_GET_DELAYS, Constants.REPLY_GET_DELAYS, new int[] { 0 }),
112     BATHROOM_END_DELAY(ComfoAirBindingConstants.CG_MENUP2_PREFIX + ComfoAirBindingConstants.CHANNEL_BR_END_DELAY,
113             DataTypeNumber.getInstance(), Constants.REQUEST_SET_DELAYS, 8, 1, new ComfoAirCommandType[] { MENU22_MODE },
114             Constants.REQUEST_GET_DELAYS, Constants.REPLY_GET_DELAYS, new int[] { 1 }),
115     L1_END_DELAY(ComfoAirBindingConstants.CG_MENUP2_PREFIX + ComfoAirBindingConstants.CHANNEL_L1_END_DELAY,
116             DataTypeNumber.getInstance(), Constants.REQUEST_SET_DELAYS, 8, 2, new ComfoAirCommandType[] { MENU27_MODE },
117             Constants.REQUEST_GET_DELAYS, Constants.REPLY_GET_DELAYS, new int[] { 2 }),
118     PULSE_VENTILATION(ComfoAirBindingConstants.CG_MENUP2_PREFIX + ComfoAirBindingConstants.CHANNEL_PULSE_VENTILATION,
119             DataTypeNumber.getInstance(), Constants.REQUEST_SET_DELAYS, 8, 3, new ComfoAirCommandType[] { MENU23_MODE },
120             Constants.REQUEST_GET_DELAYS, Constants.REPLY_GET_DELAYS, new int[] { 3 }),
121     FILTER_WEEKS(ComfoAirBindingConstants.CG_MENUP2_PREFIX + ComfoAirBindingConstants.CHANNEL_FILTER_WEEKS,
122             DataTypeNumber.getInstance(), Constants.REQUEST_SET_DELAYS, 8, 4, new ComfoAirCommandType[] { MENU24_MODE },
123             Constants.REQUEST_GET_DELAYS, Constants.REPLY_GET_DELAYS, new int[] { 4 }),
124     RF_SHORT_DELAY(ComfoAirBindingConstants.CG_MENUP2_PREFIX + ComfoAirBindingConstants.CHANNEL_RF_SHORT_DELAY,
125             DataTypeNumber.getInstance(), Constants.REQUEST_SET_DELAYS, 8, 5, new ComfoAirCommandType[] { MENU25_MODE },
126             Constants.REQUEST_GET_DELAYS, Constants.REPLY_GET_DELAYS, new int[] { 5 }),
127     RF_LONG_DELAY(ComfoAirBindingConstants.CG_MENUP2_PREFIX + ComfoAirBindingConstants.CHANNEL_RF_LONG_DELAY,
128             DataTypeNumber.getInstance(), Constants.REQUEST_SET_DELAYS, 8, 6, new ComfoAirCommandType[] { MENU26_MODE },
129             Constants.REQUEST_GET_DELAYS, Constants.REPLY_GET_DELAYS, new int[] { 6 }),
130     COOKERHOOD_DELAY(ComfoAirBindingConstants.CG_MENUP2_PREFIX + ComfoAirBindingConstants.CHANNEL_COOKERHOOD_DELAY,
131             DataTypeNumber.getInstance(), Constants.REQUEST_SET_DELAYS, 8, 7, new ComfoAirCommandType[] { MENU20_MODE },
132             Constants.REQUEST_GET_DELAYS, Constants.REPLY_GET_DELAYS, new int[] { 7 }),
133     CHIMNEY_STATE(ComfoAirBindingConstants.CG_MENUP9_PREFIX + ComfoAirBindingConstants.CHANNEL_CHIMNEY_STATE,
134             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 8 },
135             0x01),
136     BYPASS_STATE(ComfoAirBindingConstants.CG_MENUP9_PREFIX + ComfoAirBindingConstants.CHANNEL_BYPASS_STATE,
137             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 8 },
138             0x02),
139     GHX_STATE(ComfoAirBindingConstants.CG_MENUP9_PREFIX + ComfoAirBindingConstants.CHANNEL_GHX_STATE,
140             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 8 },
141             0x04),
142     HEATER_STATE(ComfoAirBindingConstants.CG_MENUP9_PREFIX + ComfoAirBindingConstants.CHANNEL_HEATER_STATE,
143             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 8 },
144             0x08),
145     V_CONTROL_STATE(ComfoAirBindingConstants.CG_MENUP9_PREFIX + ComfoAirBindingConstants.CHANNEL_VCONTROL_STATE,
146             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 8 },
147             0x10),
148     FROST_STATE(ComfoAirBindingConstants.CG_MENUP9_PREFIX + ComfoAirBindingConstants.CHANNEL_FROST_STATE,
149             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 8 },
150             0x20),
151     COOKERHOOD_STATE(ComfoAirBindingConstants.CG_MENUP9_PREFIX + ComfoAirBindingConstants.CHANNEL_COOKERHOOD_STATE,
152             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 8 },
153             0x40),
154     ENTHALPY_STATE(ComfoAirBindingConstants.CG_MENUP9_PREFIX + ComfoAirBindingConstants.CHANNEL_ENTHALPY_STATE,
155             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 8 },
156             0x80),
157     FAN_IN_PERCENT(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_IN_PERCENT,
158             DataTypeNumber.getInstance(), Constants.REQUEST_GET_FAN, Constants.REPLY_GET_FAN, new int[] { 0 }),
159     FAN_OUT_PERCENT(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_OUT_PERCENT,
160             DataTypeNumber.getInstance(), Constants.REQUEST_GET_FAN, Constants.REPLY_GET_FAN, new int[] { 1 }),
161     FAN_IN_RPM(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_IN_RPM,
162             DataTypeRPM.getInstance(), Constants.REQUEST_GET_FAN, Constants.REPLY_GET_FAN, new int[] { 2, 3 }),
163     FAN_OUT_RPM(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_OUT_RPM,
164             DataTypeRPM.getInstance(), Constants.REQUEST_GET_FAN, Constants.REPLY_GET_FAN, new int[] { 4, 5 }),
165     FAN_OUT_0(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_OUT_0,
166             DataTypeNumber.getInstance(), Constants.REQUEST_SET_FAN_LEVEL, 9, 0,
167             new ComfoAirCommandType[] { FAN_OUT_PERCENT, FAN_OUT_RPM }, Constants.REQUEST_GET_FAN_LEVEL,
168             Constants.REPLY_GET_FAN_LEVEL, new int[] { 0 }),
169     FAN_OUT_1(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_OUT_1,
170             DataTypeNumber.getInstance(), Constants.REQUEST_SET_FAN_LEVEL, 9, 1,
171             new ComfoAirCommandType[] { FAN_OUT_PERCENT, FAN_OUT_RPM }, Constants.REQUEST_GET_FAN_LEVEL,
172             Constants.REPLY_GET_FAN_LEVEL, new int[] { 1 }),
173     FAN_OUT_2(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_OUT_2,
174             DataTypeNumber.getInstance(), Constants.REQUEST_SET_FAN_LEVEL, 9, 2,
175             new ComfoAirCommandType[] { FAN_OUT_PERCENT, FAN_OUT_RPM }, Constants.REQUEST_GET_FAN_LEVEL,
176             Constants.REPLY_GET_FAN_LEVEL, new int[] { 2 }),
177     FAN_OUT_3(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_OUT_3,
178             DataTypeNumber.getInstance(), Constants.REQUEST_SET_FAN_LEVEL, 9, 6,
179             new ComfoAirCommandType[] { FAN_OUT_PERCENT, FAN_OUT_RPM }, Constants.REQUEST_GET_FAN_LEVEL,
180             Constants.REPLY_GET_FAN_LEVEL, new int[] { 10 }),
181     FAN_IN_0(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_IN_0,
182             DataTypeNumber.getInstance(), Constants.REQUEST_SET_FAN_LEVEL, 9, 3,
183             new ComfoAirCommandType[] { FAN_IN_PERCENT, FAN_IN_RPM }, Constants.REQUEST_GET_FAN_LEVEL,
184             Constants.REPLY_GET_FAN_LEVEL, new int[] { 3 }),
185     FAN_IN_1(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_IN_1,
186             DataTypeNumber.getInstance(), Constants.REQUEST_SET_FAN_LEVEL, 9, 4,
187             new ComfoAirCommandType[] { FAN_IN_PERCENT, FAN_IN_RPM }, Constants.REQUEST_GET_FAN_LEVEL,
188             Constants.REPLY_GET_FAN_LEVEL, new int[] { 4 }),
189     FAN_IN_2(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_IN_2,
190             DataTypeNumber.getInstance(), Constants.REQUEST_SET_FAN_LEVEL, 9, 5,
191             new ComfoAirCommandType[] { FAN_IN_PERCENT, FAN_IN_RPM }, Constants.REQUEST_GET_FAN_LEVEL,
192             Constants.REPLY_GET_FAN_LEVEL, new int[] { 5 }),
193     FAN_IN_3(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_IN_3,
194             DataTypeNumber.getInstance(), Constants.REQUEST_SET_FAN_LEVEL, 9, 7,
195             new ComfoAirCommandType[] { FAN_IN_PERCENT, FAN_IN_RPM }, Constants.REQUEST_GET_FAN_LEVEL,
196             Constants.REPLY_GET_FAN_LEVEL, new int[] { 11 }),
197     FAN_LEVEL(ComfoAirBindingConstants.CG_VENTILATION_PREFIX + ComfoAirBindingConstants.CHANNEL_FAN_LEVEL,
198             DataTypeNumber.getInstance(), new int[] { 0x01, 0x02, 0x03, 0x04 }, Constants.REQUEST_SET_LEVEL, 1, 0,
199             new ComfoAirCommandType[] { FAN_IN_PERCENT, FAN_IN_RPM, FAN_OUT_PERCENT, FAN_OUT_RPM },
200             Constants.REQUEST_GET_FAN_LEVEL, Constants.REPLY_GET_FAN_LEVEL, new int[] { 8 }),
201     LEVEL0_TIME(ComfoAirBindingConstants.CG_TIMES_PREFIX + ComfoAirBindingConstants.CHANNEL_TIME_LEVEL0,
202             DataTypeTime.getInstance(), Constants.REQUEST_GET_HOURS, Constants.REPLY_GET_HOURS, new int[] { 0, 1, 2 }),
203     LEVEL1_TIME(ComfoAirBindingConstants.CG_TIMES_PREFIX + ComfoAirBindingConstants.CHANNEL_TIME_LEVEL1,
204             DataTypeTime.getInstance(), Constants.REQUEST_GET_HOURS, Constants.REPLY_GET_HOURS, new int[] { 3, 4, 5 }),
205     LEVEL2_TIME(ComfoAirBindingConstants.CG_TIMES_PREFIX + ComfoAirBindingConstants.CHANNEL_TIME_LEVEL2,
206             DataTypeTime.getInstance(), Constants.REQUEST_GET_HOURS, Constants.REPLY_GET_HOURS, new int[] { 6, 7, 8 }),
207     LEVEL3_TIME(ComfoAirBindingConstants.CG_TIMES_PREFIX + ComfoAirBindingConstants.CHANNEL_TIME_LEVEL3,
208             DataTypeTime.getInstance(), Constants.REQUEST_GET_HOURS, Constants.REPLY_GET_HOURS,
209             new int[] { 17, 18, 19 }),
210     FREEZE_TIME(ComfoAirBindingConstants.CG_TIMES_PREFIX + ComfoAirBindingConstants.CHANNEL_TIME_FREEZE,
211             DataTypeTime.getInstance(), Constants.REQUEST_GET_HOURS, Constants.REPLY_GET_HOURS, new int[] { 9, 10 }),
212     PREHEATER_TIME(ComfoAirBindingConstants.CG_TIMES_PREFIX + ComfoAirBindingConstants.CHANNEL_TIME_PREHEATER,
213             DataTypeTime.getInstance(), Constants.REQUEST_GET_HOURS, Constants.REPLY_GET_HOURS, new int[] { 11, 12 }),
214     BYPASS_TIME(ComfoAirBindingConstants.CG_TIMES_PREFIX + ComfoAirBindingConstants.CHANNEL_TIME_BYPASS,
215             DataTypeTime.getInstance(), Constants.REQUEST_GET_HOURS, Constants.REPLY_GET_HOURS, new int[] { 13, 14 }),
216     BYPASS_FACTOR(ComfoAirBindingConstants.CG_BYPASS_PREFIX + ComfoAirBindingConstants.CHANNEL_BYPASS_FACTOR,
217             DataTypeNumber.getInstance(), Constants.REQUEST_GET_BYPASS, Constants.REPLY_GET_BYPASS, new int[] { 2 }),
218     BYPASS_LEVEL(ComfoAirBindingConstants.CG_BYPASS_PREFIX + ComfoAirBindingConstants.CHANNEL_BYPASS_LEVEL,
219             DataTypeNumber.getInstance(), Constants.REQUEST_GET_BYPASS, Constants.REPLY_GET_BYPASS, new int[] { 3 }),
220     BYPASS_CORRECTION(ComfoAirBindingConstants.CG_BYPASS_PREFIX + ComfoAirBindingConstants.CHANNEL_BYPASS_CORRECTION,
221             DataTypeNumber.getInstance(), Constants.REQUEST_GET_BYPASS, Constants.REPLY_GET_BYPASS, new int[] { 4 }),
222     BYPASS_SUMMER(ComfoAirBindingConstants.CG_BYPASS_PREFIX + ComfoAirBindingConstants.CHANNEL_BYPASS_SUMMER,
223             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_BYPASS, Constants.REPLY_GET_BYPASS, new int[] { 6 }),
224     ENTHALPY_TEMPERATURE(ComfoAirBindingConstants.CG_ENTHALPY_PREFIX + ComfoAirBindingConstants.CHANNEL_ENTHALPY_TEMP,
225             DataTypeTemperature.getInstance(), Constants.REQUEST_GET_SENSORS, Constants.REPLY_GET_SENSORS,
226             new int[] { 0 }),
227     ENTHALPY_HUMIDITY(ComfoAirBindingConstants.CG_ENTHALPY_PREFIX + ComfoAirBindingConstants.CHANNEL_ENTHALPY_HUMIDITY,
228             DataTypeNumber.getInstance(), Constants.REQUEST_GET_SENSORS, Constants.REPLY_GET_SENSORS, new int[] { 1 }),
229     ENTHALPY_LEVEL(ComfoAirBindingConstants.CG_ENTHALPY_PREFIX + ComfoAirBindingConstants.CHANNEL_ENTHALPY_LEVEL,
230             DataTypeNumber.getInstance(), Constants.REQUEST_GET_SENSORS, Constants.REPLY_GET_SENSORS, new int[] { 4 }),
231     ENTHALPY_TIME(ComfoAirBindingConstants.CG_ENTHALPY_PREFIX + ComfoAirBindingConstants.CHANNEL_ENTHALPY_TIME,
232             DataTypeNumber.getInstance(), Constants.REQUEST_GET_SENSORS, Constants.REPLY_GET_SENSORS, new int[] { 5 }),
233     PREHEATER_VALVE(ComfoAirBindingConstants.CG_PREHEATER_PREFIX + ComfoAirBindingConstants.CHANNEL_PREHEATER_VALVE,
234             DataTypeNumber.getInstance(), Constants.REQUEST_GET_PREHEATER, Constants.REPLY_GET_PREHEATER,
235             new int[] { 0 }),
236     PREHEATER_FROST_PROTECT(
237             ComfoAirBindingConstants.CG_PREHEATER_PREFIX + ComfoAirBindingConstants.CHANNEL_PREHEATER_FROST_PROTECT,
238             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_PREHEATER, Constants.REPLY_GET_PREHEATER,
239             new int[] { 1 }),
240     PREHEATER_HEATING(ComfoAirBindingConstants.CG_PREHEATER_PREFIX + ComfoAirBindingConstants.CHANNEL_PREHEATER_HEATING,
241             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_PREHEATER, Constants.REPLY_GET_PREHEATER,
242             new int[] { 2 }),
243     PREHEATER_FROST_TIME(
244             ComfoAirBindingConstants.CG_PREHEATER_PREFIX + ComfoAirBindingConstants.CHANNEL_PREHEATER_FROST_TIME,
245             DataTypeNumber.getInstance(), Constants.REQUEST_GET_PREHEATER, Constants.REPLY_GET_PREHEATER,
246             new int[] { 3, 4 }),
247     PREHEATER_OPTION(ComfoAirBindingConstants.CG_PREHEATER_PREFIX + ComfoAirBindingConstants.CHANNEL_PREHEATER_SAFETY,
248             DataTypeNumber.getInstance(), Constants.REQUEST_GET_PREHEATER, Constants.REPLY_GET_PREHEATER,
249             new int[] { 5 }),
250     TARGET_TEMPERATURE(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_TEMP_TARGET,
251             DataTypeTemperature.getInstance(), Constants.REQUEST_SET_TEMPS, 1, 0,
252             new ComfoAirCommandType[] { BYPASS_FACTOR, BYPASS_LEVEL, BYPASS_SUMMER }, Constants.REQUEST_GET_TEMPS,
253             Constants.REPLY_GET_TEMPS, new int[] { 0 }),
254     OUTDOOR_TEMPERATURE_IN(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_TEMP_OUTDOOR_IN,
255             DataTypeTemperature.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 1 }),
256     OUTDOOR_TEMPERATURE_OUT(
257             ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_TEMP_OUTDOOR_OUT,
258             DataTypeTemperature.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 4 }),
259     INDOOR_TEMPERATURE_IN(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_TEMP_INDOOR_IN,
260             DataTypeTemperature.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 2 }),
261     INDOOR_TEMPERATURE_OUT(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_TEMP_INDOOR_OUT,
262             DataTypeTemperature.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 3 }),
263     IS_T1_SENSOR(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_SENSOR_T1,
264             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 5 },
265             0x01),
266     IS_T2_SENSOR(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_SENSOR_T2,
267             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 5 },
268             0x02),
269     IS_T3_SENSOR(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_SENSOR_T3,
270             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 5 },
271             0x04),
272     IS_T4_SENSOR(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_SENSOR_T4,
273             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 5 },
274             0x08),
275     IS_GHX_SENSOR(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_SENSOR_GHX,
276             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 5 },
277             0x10),
278     IS_HEATER_SENSOR(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_SENSOR_HEATER,
279             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 5 },
280             0x20),
281     IS_COOKERHOOD_SENSOR(
282             ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_SENSOR_COOKERHOOD,
283             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 5 },
284             0x40),
285     GHX_TEMPERATURE(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_TEMP_GHX,
286             DataTypeTemperature.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 6 }),
287     HEATER_TEMPERATURE(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_TEMP_HEATER,
288             DataTypeTemperature.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 7 }),
289     COOKERHOOD_TEMPERATURE(ComfoAirBindingConstants.CG_TEMPS_PREFIX + ComfoAirBindingConstants.CHANNEL_TEMP_COOKERHOOD,
290             DataTypeTemperature.getInstance(), Constants.REQUEST_GET_TEMPS, Constants.REPLY_GET_TEMPS, new int[] { 8 }),
291     GHX_SPEED(ComfoAirBindingConstants.CG_GHX_PREFIX + ComfoAirBindingConstants.CHANNEL_GHX_SPEED,
292             DataTypeNumber.getInstance(), Constants.REQUEST_SET_GHX, 5, 2,
293             new ComfoAirCommandType[] { GHX_STATE, GHX_TEMPERATURE }, Constants.REQUEST_GET_GHX,
294             Constants.REPLY_GET_GHX, new int[] { 2 }),
295     GHX_TEMPERATURE_LOW(ComfoAirBindingConstants.CG_GHX_PREFIX + ComfoAirBindingConstants.CHANNEL_GHX_TEMP_LOW,
296             DataTypeTemperature.getInstance(), Constants.REQUEST_SET_GHX, 5, 0, new ComfoAirCommandType[] { GHX_STATE },
297             Constants.REQUEST_GET_GHX, Constants.REPLY_GET_GHX, new int[] { 0 }),
298     GHX_TEMPERATURE_HIGH(ComfoAirBindingConstants.CG_GHX_PREFIX + ComfoAirBindingConstants.CHANNEL_GHX_TEMP_HIGH,
299             DataTypeTemperature.getInstance(), Constants.REQUEST_SET_GHX, 5, 1, new ComfoAirCommandType[] { GHX_STATE },
300             Constants.REQUEST_GET_GHX, Constants.REPLY_GET_GHX, new int[] { 1 }),
301     COOKERHOOD_SPEED(ComfoAirBindingConstants.CG_COOKERHOOD_PREFIX + ComfoAirBindingConstants.CHANNEL_COOKERHOOD_SPEED,
302             DataTypeNumber.getInstance(), Constants.REQUEST_SET_GHX, 5, 3,
303             new ComfoAirCommandType[] { COOKERHOOD_STATE, COOKERHOOD_TEMPERATURE }, Constants.REQUEST_GET_GHX,
304             Constants.REPLY_GET_GHX, new int[] { 3 }),
305     HEATER_POWER(ComfoAirBindingConstants.CG_HEATER_PREFIX + ComfoAirBindingConstants.CHANNEL_HEATER_POWER,
306             DataTypeNumber.getInstance(), Constants.REQUEST_GET_GHX, Constants.REPLY_GET_GHX, new int[] { 4 }),
307     HEATER_POWER_I(ComfoAirBindingConstants.CG_HEATER_PREFIX + ComfoAirBindingConstants.CHANNEL_HEATER_POWER_I,
308             DataTypeNumber.getInstance(), Constants.REQUEST_GET_GHX, Constants.REPLY_GET_GHX, new int[] { 5 }),
309     HEATER_TARGET_TEMPERATURE(
310             ComfoAirBindingConstants.CG_HEATER_PREFIX + ComfoAirBindingConstants.CHANNEL_HEATER_TEMP_TARGET,
311             DataTypeTemperature.getInstance(), Constants.REQUEST_SET_GHX, 5, 4,
312             new ComfoAirCommandType[] { HEATER_STATE, HEATER_POWER, HEATER_TEMPERATURE }, Constants.REQUEST_GET_GHX,
313             Constants.REPLY_GET_GHX, new int[] { 6 }),
314     IS_PREHEATER(ComfoAirBindingConstants.CG_OPTIONS_PREFIX + ComfoAirBindingConstants.CHANNEL_OPTION_PREHEATER,
315             DataTypeBoolean.getInstance(), Constants.REQUEST_SET_STATES, 8, 0,
316             new ComfoAirCommandType[] { OUTDOOR_TEMPERATURE_IN, INDOOR_TEMPERATURE_IN, PREHEATER_FROST_PROTECT,
317                     PREHEATER_FROST_TIME, PREHEATER_HEATING, FROST_STATE, PREHEATER_OPTION, PREHEATER_TIME,
318                     PREHEATER_VALVE },
319             Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 0 }),
320     IS_BYPASS(ComfoAirBindingConstants.CG_OPTIONS_PREFIX + ComfoAirBindingConstants.CHANNEL_OPTION_BYPASS,
321             DataTypeBoolean.getInstance(), Constants.REQUEST_SET_STATES, 8, 1,
322             new ComfoAirCommandType[] { INDOOR_TEMPERATURE_IN, OUTDOOR_TEMPERATURE_OUT }, Constants.REQUEST_GET_STATES,
323             Constants.REPLY_GET_STATES, new int[] { 1 }),
324     RECU_TYPE(ComfoAirBindingConstants.CG_OPTIONS_PREFIX + ComfoAirBindingConstants.CHANNEL_OPTION_RECU_TYPE,
325             DataTypeNumber.getInstance(), new int[] { 0x01, 0x02 }, Constants.REQUEST_SET_STATES, 8, 2,
326             new ComfoAirCommandType[] { FAN_IN_PERCENT, FAN_OUT_PERCENT, INDOOR_TEMPERATURE_IN, INDOOR_TEMPERATURE_OUT,
327                     OUTDOOR_TEMPERATURE_IN, OUTDOOR_TEMPERATURE_OUT },
328             Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 2 }),
329     RECU_SIZE(ComfoAirBindingConstants.CG_OPTIONS_PREFIX + ComfoAirBindingConstants.CHANNEL_OPTION_RECU_SIZE,
330             DataTypeNumber.getInstance(), new int[] { 0x01, 0x02 }, Constants.REQUEST_SET_STATES, 8, 3,
331             new ComfoAirCommandType[] { FAN_IN_PERCENT, FAN_OUT_PERCENT, FAN_IN_0, FAN_IN_1, FAN_IN_2, FAN_IN_3,
332                     FAN_OUT_0, FAN_OUT_1, FAN_OUT_2, FAN_OUT_3 },
333             Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 3 }),
334     IS_CHIMNEY(ComfoAirBindingConstants.CG_OPTIONS_PREFIX + ComfoAirBindingConstants.CHANNEL_OPTION_CHIMNEY,
335             DataTypeBoolean.getInstance(), new int[] { 0x01 }, Constants.REQUEST_SET_STATES, 8, 4,
336             Constants.EMPTY_TYPE_ARRAY, Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 4 },
337             0x01),
338     IS_COOKERHOOD(ComfoAirBindingConstants.CG_OPTIONS_PREFIX + ComfoAirBindingConstants.CHANNEL_OPTION_COOKERHOOD,
339             DataTypeBoolean.getInstance(), new int[] { 0x02 }, Constants.REQUEST_SET_STATES, 8, 4,
340             new ComfoAirCommandType[] { COOKERHOOD_DELAY, COOKERHOOD_STATE, COOKERHOOD_SPEED, COOKERHOOD_TEMPERATURE },
341             Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 4 }, 0x02),
342     IS_HEATER(ComfoAirBindingConstants.CG_OPTIONS_PREFIX + ComfoAirBindingConstants.CHANNEL_OPTION_HEATER,
343             DataTypeBoolean.getInstance(), new int[] { 0x04 }, Constants.REQUEST_SET_STATES, 8, 4,
344             new ComfoAirCommandType[] { HEATER_TARGET_TEMPERATURE, HEATER_POWER, HEATER_STATE, HEATER_POWER_I,
345                     HEATER_TEMPERATURE },
346             Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 4 }, 0x04),
347     IS_ENTHALPY(ComfoAirBindingConstants.CG_OPTIONS_PREFIX + ComfoAirBindingConstants.CHANNEL_OPTION_ENTHALPY,
348             DataTypeNumber.getInstance(), new int[] { 0x00, 0x01, 0x02 }, Constants.REQUEST_SET_STATES, 8, 6,
349             new ComfoAirCommandType[] { ENTHALPY_TEMPERATURE, ENTHALPY_HUMIDITY, ENTHALPY_LEVEL, ENTHALPY_STATE,
350                     ENTHALPY_TIME },
351             Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 9 }),
352     IS_GHX(ComfoAirBindingConstants.CG_OPTIONS_PREFIX + ComfoAirBindingConstants.CHANNEL_OPTION_GHX,
353             DataTypeNumber.getInstance(), new int[] { 0x00, 0x01, 0x02 }, Constants.REQUEST_SET_STATES, 8, 7,
354             new ComfoAirCommandType[] { GHX_SPEED, GHX_TEMPERATURE_LOW, GHX_TEMPERATURE_HIGH, GHX_STATE,
355                     GHX_TEMPERATURE },
356             Constants.REQUEST_GET_STATES, Constants.REPLY_GET_STATES, new int[] { 10 }),
357     SOFTWARE_MAIN_VERSION(ComfoAirBindingConstants.PROPERTY_SOFTWARE_MAIN_VERSION, DataTypeNumber.getInstance(),
358             Constants.REQUEST_GET_FIRMWARE, Constants.REPLY_GET_FIRMWARE, new int[] { 0 }),
359     SOFTWARE_MINOR_VERSION(ComfoAirBindingConstants.PROPERTY_SOFTWARE_MINOR_VERSION, DataTypeNumber.getInstance(),
360             Constants.REQUEST_GET_FIRMWARE, Constants.REPLY_GET_FIRMWARE, new int[] { 1 }),
361     DEVICE_NAME(ComfoAirBindingConstants.PROPERTY_DEVICE_NAME, DataTypeNumber.getInstance(),
362             Constants.REQUEST_GET_FIRMWARE, Constants.REPLY_GET_FIRMWARE,
363             new int[] { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }),
364     ERRORS_CURRENT(ComfoAirBindingConstants.CG_ERRORS_PREFIX + ComfoAirBindingConstants.CHANNEL_ERRORS_CURRENT,
365             DataTypeMessage.getInstance(), Constants.REQUEST_GET_ERRORS, Constants.REPLY_GET_ERRORS,
366             new int[] { 0, 1, 9, 13 }),
367     ERRORS_LAST(ComfoAirBindingConstants.CG_ERRORS_PREFIX + ComfoAirBindingConstants.CHANNEL_ERRORS_LAST,
368             DataTypeMessage.getInstance(), Constants.REQUEST_GET_ERRORS, Constants.REPLY_GET_ERRORS,
369             new int[] { 2, 3, 10, 14 }),
370     ERRORS_PRELAST(ComfoAirBindingConstants.CG_ERRORS_PREFIX + ComfoAirBindingConstants.CHANNEL_ERRORS_PRELAST,
371             DataTypeMessage.getInstance(), Constants.REQUEST_GET_ERRORS, Constants.REPLY_GET_ERRORS,
372             new int[] { 4, 5, 11, 15 }),
373     ERRORS_PREPRELAST(ComfoAirBindingConstants.CG_ERRORS_PREFIX + ComfoAirBindingConstants.CHANNEL_ERRORS_PREPRELAST,
374             DataTypeMessage.getInstance(), Constants.REQUEST_GET_ERRORS, Constants.REPLY_GET_ERRORS,
375             new int[] { 6, 7, 12, 16 }),
376     ERROR_RESET(ComfoAirBindingConstants.CG_RESETS_PREFIX + ComfoAirBindingConstants.CHANNEL_ERROR_RESET,
377             DataTypeNumber.getInstance(), new int[] { 0x01 }, Constants.REQUEST_SET_RESETS, 4, 0,
378             new ComfoAirCommandType[] { ERRORS_CURRENT, ERRORS_LAST, ERRORS_PRELAST, ERRORS_PREPRELAST }),
379     FILTER_ERROR(ComfoAirBindingConstants.CG_ERRORS_PREFIX + ComfoAirBindingConstants.CHANNEL_FILTER_ERROR,
380             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_ERRORS, Constants.REPLY_GET_ERRORS, new int[] { 8 },
381             0x01),
382     FILTER_HOURS(ComfoAirBindingConstants.CG_TIMES_PREFIX + ComfoAirBindingConstants.CHANNEL_TIME_FILTER,
383             DataTypeTime.getInstance(), Constants.REQUEST_GET_HOURS, Constants.REPLY_GET_HOURS, new int[] { 15, 16 }),
384     FILTER_RESET(ComfoAirBindingConstants.CG_RESETS_PREFIX + ComfoAirBindingConstants.CHANNEL_FILTER_RESET,
385             DataTypeNumber.getInstance(), new int[] { 0x01 }, Constants.REQUEST_SET_RESETS, 4, 3,
386             new ComfoAirCommandType[] { FILTER_HOURS, FILTER_ERROR }),
387     ANALOG1_NEGATIVE(ComfoAirBindingConstants.CG_ANALOG1_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_NEGATIVE,
388             DataTypeBoolean.getInstance(), new int[] { 0x01 }, Constants.REQUEST_SET_ANALOGS, 19, 2,
389             Constants.EMPTY_TYPE_ARRAY, Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 2 },
390             0x01),
391     ANALOG2_NEGATIVE(ComfoAirBindingConstants.CG_ANALOG2_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_NEGATIVE,
392             DataTypeBoolean.getInstance(), new int[] { 0x02 }, Constants.REQUEST_SET_ANALOGS, 19, 2,
393             Constants.EMPTY_TYPE_ARRAY, Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 2 },
394             0x02),
395     ANALOG3_NEGATIVE(ComfoAirBindingConstants.CG_ANALOG3_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_NEGATIVE,
396             DataTypeBoolean.getInstance(), new int[] { 0x04 }, Constants.REQUEST_SET_ANALOGS, 19, 2,
397             Constants.EMPTY_TYPE_ARRAY, Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 2 },
398             0x04),
399     ANALOG4_NEGATIVE(ComfoAirBindingConstants.CG_ANALOG4_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_NEGATIVE,
400             DataTypeBoolean.getInstance(), new int[] { 0x08 }, Constants.REQUEST_SET_ANALOGS, 19, 2,
401             Constants.EMPTY_TYPE_ARRAY, Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 2 },
402             0x08),
403     RF_NEGATIVE(ComfoAirBindingConstants.CG_ANALOGRF_PREFIX + ComfoAirBindingConstants.CHANNEL_RF_NEGATIVE,
404             DataTypeBoolean.getInstance(), new int[] { 0x10 }, Constants.REQUEST_SET_ANALOGS, 19, 2,
405             Constants.EMPTY_TYPE_ARRAY, Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 2 },
406             0x10),
407     ANALOG1_MIN(ComfoAirBindingConstants.CG_ANALOG1_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MIN,
408             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 3, Constants.EMPTY_TYPE_ARRAY,
409             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 3 }),
410     ANALOG1_MAX(ComfoAirBindingConstants.CG_ANALOG1_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MAX,
411             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 4, Constants.EMPTY_TYPE_ARRAY,
412             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 4 }),
413     ANALOG1_VALUE(ComfoAirBindingConstants.CG_ANALOG1_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_VALUE,
414             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 5, Constants.EMPTY_TYPE_ARRAY,
415             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 5 }),
416     ANALOG2_MIN(ComfoAirBindingConstants.CG_ANALOG2_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MIN,
417             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 6, Constants.EMPTY_TYPE_ARRAY,
418             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 6 }),
419     ANALOG2_MAX(ComfoAirBindingConstants.CG_ANALOG2_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MAX,
420             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 7, Constants.EMPTY_TYPE_ARRAY,
421             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 7 }),
422     ANALOG2_VALUE(ComfoAirBindingConstants.CG_ANALOG2_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_VALUE,
423             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 8, Constants.EMPTY_TYPE_ARRAY,
424             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 8 }),
425     ANALOG3_MIN(ComfoAirBindingConstants.CG_ANALOG3_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MIN,
426             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 9, Constants.EMPTY_TYPE_ARRAY,
427             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 9 }),
428     ANALOG3_MAX(ComfoAirBindingConstants.CG_ANALOG3_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MAX,
429             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 10, Constants.EMPTY_TYPE_ARRAY,
430             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 10 }),
431     ANALOG3_VALUE(ComfoAirBindingConstants.CG_ANALOG3_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_VALUE,
432             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 11, Constants.EMPTY_TYPE_ARRAY,
433             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 11 }),
434     ANALOG4_MIN(ComfoAirBindingConstants.CG_ANALOG4_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MIN,
435             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 12, Constants.EMPTY_TYPE_ARRAY,
436             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 12 }),
437     ANALOG4_MAX(ComfoAirBindingConstants.CG_ANALOG4_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MAX,
438             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 13, Constants.EMPTY_TYPE_ARRAY,
439             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 13 }),
440     ANALOG4_VALUE(ComfoAirBindingConstants.CG_ANALOG4_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_VALUE,
441             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 14, Constants.EMPTY_TYPE_ARRAY,
442             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 14 }),
443     RF_MIN(ComfoAirBindingConstants.CG_ANALOGRF_PREFIX + ComfoAirBindingConstants.CHANNEL_RF_MIN,
444             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 15, Constants.EMPTY_TYPE_ARRAY,
445             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 15 }),
446     RF_MAX(ComfoAirBindingConstants.CG_ANALOGRF_PREFIX + ComfoAirBindingConstants.CHANNEL_RF_MAX,
447             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 16, Constants.EMPTY_TYPE_ARRAY,
448             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 16 }),
449     RF_VALUE(ComfoAirBindingConstants.CG_ANALOGRF_PREFIX + ComfoAirBindingConstants.CHANNEL_RF_VALUE,
450             DataTypeNumber.getInstance(), Constants.REQUEST_SET_ANALOGS, 19, 17, Constants.EMPTY_TYPE_ARRAY,
451             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 17 }),
452     ANALOG_MODE(ComfoAirBindingConstants.CG_OPTIONS_PREFIX + ComfoAirBindingConstants.CHANNEL_OPTION_PRIORITY,
453             DataTypeNumber.getInstance(), new int[] { 0x00, 0x01 }, Constants.REQUEST_SET_ANALOGS, 19, 18,
454             Constants.EMPTY_TYPE_ARRAY, Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 18 }),
455     ANALOG1_VOLT(ComfoAirBindingConstants.CG_ANALOG1_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_VOLT,
456             DataTypeVolt.getInstance(), Constants.REQUEST_GET_ANALOG_VOLTS, Constants.REPLY_GET_ANALOG_VOLTS,
457             new int[] { 0 }),
458     ANALOG2_VOLT(ComfoAirBindingConstants.CG_ANALOG2_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_VOLT,
459             DataTypeVolt.getInstance(), Constants.REQUEST_GET_ANALOG_VOLTS, Constants.REPLY_GET_ANALOG_VOLTS,
460             new int[] { 1 }),
461     ANALOG3_VOLT(ComfoAirBindingConstants.CG_ANALOG3_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_VOLT,
462             DataTypeVolt.getInstance(), Constants.REQUEST_GET_ANALOG_VOLTS, Constants.REPLY_GET_ANALOG_VOLTS,
463             new int[] { 2 }),
464     ANALOG4_VOLT(ComfoAirBindingConstants.CG_ANALOG4_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_VOLT,
465             DataTypeVolt.getInstance(), Constants.REQUEST_GET_ANALOG_VOLTS, Constants.REPLY_GET_ANALOG_VOLTS,
466             new int[] { 3 }),
467     ANALOG1_MODE(ComfoAirBindingConstants.CG_ANALOG1_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MODE,
468             DataTypeBoolean.getInstance(), new int[] { 0x01 }, Constants.REQUEST_SET_ANALOGS, 19, 1,
469             new ComfoAirCommandType[] { ANALOG1_NEGATIVE, ANALOG1_MIN, ANALOG1_MAX, ANALOG1_VALUE, ANALOG1_VOLT },
470             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 1 }, 0x01),
471     ANALOG2_MODE(ComfoAirBindingConstants.CG_ANALOG2_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MODE,
472             DataTypeBoolean.getInstance(), new int[] { 0x02 }, Constants.REQUEST_SET_ANALOGS, 19, 1,
473             new ComfoAirCommandType[] { ANALOG2_NEGATIVE, ANALOG2_MIN, ANALOG2_MAX, ANALOG2_VALUE, ANALOG2_VOLT },
474             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 1 }, 0x02),
475     ANALOG3_MODE(ComfoAirBindingConstants.CG_ANALOG3_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MODE,
476             DataTypeBoolean.getInstance(), new int[] { 0x04 }, Constants.REQUEST_SET_ANALOGS, 19, 1,
477             new ComfoAirCommandType[] { ANALOG3_NEGATIVE, ANALOG3_MIN, ANALOG3_MAX, ANALOG3_VALUE, ANALOG3_VOLT },
478             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 1 }, 0x04),
479     ANALOG4_MODE(ComfoAirBindingConstants.CG_ANALOG4_PREFIX + ComfoAirBindingConstants.CHANNEL_ANALOG_MODE,
480             DataTypeBoolean.getInstance(), new int[] { 0x08 }, Constants.REQUEST_SET_ANALOGS, 19, 1,
481             new ComfoAirCommandType[] { ANALOG4_NEGATIVE, ANALOG4_MIN, ANALOG4_MAX, ANALOG4_VALUE, ANALOG4_VOLT },
482             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 1 }, 0x08),
483     RF_MODE(ComfoAirBindingConstants.CG_ANALOGRF_PREFIX + ComfoAirBindingConstants.CHANNEL_RF_MODE,
484             DataTypeBoolean.getInstance(), new int[] { 0x10 }, Constants.REQUEST_SET_ANALOGS, 19, 1,
485             new ComfoAirCommandType[] { RF_NEGATIVE, RF_MIN, RF_MAX, RF_VALUE }, Constants.REQUEST_GET_ANALOGS,
486             Constants.REPLY_GET_ANALOGS, new int[] { 1 }, 0x10),
487     IS_L1_SWITCH(ComfoAirBindingConstants.CG_INPUTS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_L1_SWITCH,
488             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_INPUTS, Constants.REPLY_GET_INPUTS, new int[] { 0 },
489             0x01),
490     IS_L2_SWITCH(ComfoAirBindingConstants.CG_INPUTS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_L2_SWITCH,
491             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_INPUTS, Constants.REPLY_GET_INPUTS, new int[] { 0 },
492             0x02),
493     IS_BATHROOM_SWITCH(ComfoAirBindingConstants.CG_INPUTS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_BATHROOM_SWITCH,
494             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_INPUTS, Constants.REPLY_GET_INPUTS, new int[] { 1 },
495             0x01),
496     IS_COOKERHOOD_SWITCH(
497             ComfoAirBindingConstants.CG_INPUTS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_COOKERHOOD_SWITCH,
498             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_INPUTS, Constants.REPLY_GET_INPUTS, new int[] { 1 },
499             0x02),
500     IS_EXTERNAL_FILTER(ComfoAirBindingConstants.CG_INPUTS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_EXTERNAL_FILTER,
501             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_INPUTS, Constants.REPLY_GET_INPUTS, new int[] { 1 },
502             0x04),
503     IS_WTW(ComfoAirBindingConstants.CG_INPUTS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_WTW,
504             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_INPUTS, Constants.REPLY_GET_INPUTS, new int[] { 1 },
505             0x08),
506     IS_BATHROOM2_SWITCH(
507             ComfoAirBindingConstants.CG_INPUTS_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_BATHROOM2_SWITCH,
508             DataTypeBoolean.getInstance(), Constants.REQUEST_GET_INPUTS, Constants.REPLY_GET_INPUTS, new int[] { 1 },
509             0x10),
510     IS_ANALOG1(ComfoAirBindingConstants.CG_ANALOG1_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_ANALOG,
511             DataTypeBoolean.getInstance(), new int[] { 0x01 }, Constants.REQUEST_SET_ANALOGS, 19, 0,
512             new ComfoAirCommandType[] { ANALOG1_MODE, ANALOG1_NEGATIVE, ANALOG1_MIN, ANALOG1_MAX, ANALOG1_VALUE,
513                     ANALOG1_VOLT },
514             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 0 }, 0x01),
515     IS_ANALOG2(ComfoAirBindingConstants.CG_ANALOG1_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_ANALOG,
516             DataTypeBoolean.getInstance(), new int[] { 0x02 }, Constants.REQUEST_SET_ANALOGS, 19, 0,
517             new ComfoAirCommandType[] { ANALOG2_MODE, ANALOG2_NEGATIVE, ANALOG2_MIN, ANALOG2_MAX, ANALOG2_VALUE,
518                     ANALOG2_VOLT },
519             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 0 }, 0x02),
520     IS_ANALOG3(ComfoAirBindingConstants.CG_ANALOG1_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_ANALOG,
521             DataTypeBoolean.getInstance(), new int[] { 0x04 }, Constants.REQUEST_SET_ANALOGS, 19, 0,
522             new ComfoAirCommandType[] { ANALOG3_MODE, ANALOG3_NEGATIVE, ANALOG3_MIN, ANALOG3_MAX, ANALOG3_VALUE,
523                     ANALOG3_VOLT },
524             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 0 }, 0x04),
525     IS_ANALOG4(ComfoAirBindingConstants.CG_ANALOG1_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_ANALOG,
526             DataTypeBoolean.getInstance(), new int[] { 0x08 }, Constants.REQUEST_SET_ANALOGS, 19, 0,
527             new ComfoAirCommandType[] { ANALOG4_MODE, ANALOG4_NEGATIVE, ANALOG4_MIN, ANALOG4_MAX, ANALOG4_VALUE,
528                     ANALOG4_VOLT },
529             Constants.REQUEST_GET_ANALOGS, Constants.REPLY_GET_ANALOGS, new int[] { 0 }, 0x08),
530     IS_RF(ComfoAirBindingConstants.CG_ANALOGRF_PREFIX + ComfoAirBindingConstants.CHANNEL_IS_RF,
531             DataTypeBoolean.getInstance(), new int[] { 0x10 }, Constants.REQUEST_SET_ANALOGS, 19, 0,
532             new ComfoAirCommandType[] { RF_MODE, RF_NEGATIVE, RF_MIN, RF_MAX, RF_VALUE }, Constants.REQUEST_GET_ANALOGS,
533             Constants.REPLY_GET_ANALOGS, new int[] { 0 }, 0x10);
534
535     private final String key;
536     private final ComfoAirDataType dataType;
537
538     /*
539      * Possible values
540      */
541     private final int @Nullable [] possibleValues;
542
543     /*
544      * Cmd code to change properties on the comfoair.
545      */
546     private final int changeCommand;
547
548     /*
549      * The size of the data block.
550      */
551     private final int changeDataSize;
552
553     /*
554      * The byte inside the data block which holds the crucial value.
555      */
556     private final int changeDataPos;
557
558     /*
559      * Affected commands which should be refreshed after a successful change
560      * command call.
561      */
562     private final ComfoAirCommandType @Nullable [] changeAffected;
563
564     /*
565      * Command for reading properties.
566      */
567     private final int readCommand;
568
569     /*
570      * ACK Command which identifies the matching response.
571      */
572     private final int readReplyCommand;
573
574     /*
575      * The byte position inside the response data.
576      */
577     private final int @Nullable [] readReplyDataPos;
578
579     /*
580      * Bit mask for boolean response properties to identify a true value.
581      */
582     private final int readReplyDataBits;
583
584     /*
585      * Constructor for full read/write command
586      */
587     private ComfoAirCommandType(String key, ComfoAirDataType dataType, int @Nullable [] possibleValues,
588             int changeCommand, int changeDataSize, int changeDataPos, ComfoAirCommandType @Nullable [] changeAffected,
589             int readCommand, int readReplyCommand, int @Nullable [] readReplyDataPos, int readReplyDataBits) {
590         this.key = key;
591         this.dataType = dataType;
592         this.possibleValues = possibleValues;
593         this.changeCommand = changeCommand;
594         this.changeDataSize = changeDataSize;
595         this.changeDataPos = changeDataPos;
596         this.changeAffected = changeAffected;
597         this.readCommand = readCommand;
598         this.readReplyCommand = readReplyCommand;
599         this.readReplyDataPos = readReplyDataPos;
600         this.readReplyDataBits = readReplyDataBits;
601     }
602
603     /*
604      * Constructor for read/write command w/o predefined readReplyDataBits
605      */
606     private ComfoAirCommandType(String key, ComfoAirDataType dataType, int[] possibleValues, int changeCommand,
607             int changeDataSize, int changeDataPos, ComfoAirCommandType[] changeAffected, int readCommand,
608             int readReplyCommand, int[] readReplyDataPos) {
609         this(key, dataType, possibleValues, changeCommand, changeDataSize, changeDataPos, changeAffected, readCommand,
610                 readReplyCommand, readReplyDataPos, 0);
611     }
612
613     /*
614      * Constructor for read/write command w/o predefined readReplyDataBits & possibleValues
615      */
616     private ComfoAirCommandType(String key, ComfoAirDataType dataType, int changeCommand, int changeDataSize,
617             int changeDataPos, ComfoAirCommandType[] changeAffected, int readCommand, int readReplyCommand,
618             int[] readReplyDataPos) {
619         this(key, dataType, null, changeCommand, changeDataSize, changeDataPos, changeAffected, readCommand,
620                 readReplyCommand, readReplyDataPos, 0);
621     }
622
623     /*
624      * Constructor for write-only command (reset)
625      */
626     private ComfoAirCommandType(String key, ComfoAirDataType dataType, int[] possibleValues, int changeCommand,
627             int changeDataSize, int changeDataPos, ComfoAirCommandType[] changeAffected) {
628         this(key, dataType, possibleValues, changeCommand, changeDataSize, changeDataPos, changeAffected, 0, 0, null,
629                 0);
630     }
631
632     /*
633      * Constructor for read-only command
634      */
635     private ComfoAirCommandType(String key, ComfoAirDataType dataType, int readCommand, int readReplyCommand,
636             int[] readReplyDataPos, int readReplyDataBits) {
637         this(key, dataType, null, 0, 0, 0, null, readCommand, readReplyCommand, readReplyDataPos, readReplyDataBits);
638     }
639
640     /*
641      * Constructor for read-only command w/o readReplyDataBits
642      */
643     private ComfoAirCommandType(String key, ComfoAirDataType dataType, int readCommand, int readReplyCommand,
644             int[] readReplyDataPos) {
645         this(key, dataType, null, 0, 0, 0, null, readCommand, readReplyCommand, readReplyDataPos, 0);
646     }
647
648     public static class Constants {
649         public static final int REQUEST_GET_INPUTS = 0x03;
650         public static final int REPLY_GET_INPUTS = 0x04;
651         public static final int REQUEST_GET_FAN = 0x0b;
652         public static final int REPLY_GET_FAN = 0x0c;
653         public static final int REQUEST_GET_ANALOG_VOLTS = 0x13;
654         public static final int REPLY_GET_ANALOG_VOLTS = 0x14;
655         public static final int REQUEST_GET_FIRMWARE = 0x69;
656         public static final int REPLY_GET_FIRMWARE = 0x6a;
657         public static final int REQUEST_GET_SENSORS = 0x97;
658         public static final int REPLY_GET_SENSORS = 0x98;
659         public static final int REQUEST_SET_LEVEL = 0x99;
660         public static final int REQUEST_SET_RS232 = 0x9b;
661         public static final int REPLY_SET_RS232 = 0x9c;
662         public static final int REQUEST_GET_ANALOGS = 0x9d;
663         public static final int REPLY_GET_ANALOGS = 0x9e;
664         public static final int REQUEST_SET_ANALOGS = 0x9f;
665         public static final int REQUEST_GET_DELAYS = 0xc9;
666         public static final int REPLY_GET_DELAYS = 0xca;
667         public static final int REQUEST_SET_DELAYS = 0xcb;
668         public static final int REQUEST_GET_FAN_LEVEL = 0xcd;
669         public static final int REPLY_GET_FAN_LEVEL = 0xce;
670         public static final int REQUEST_SET_FAN_LEVEL = 0xcf;
671         public static final int REQUEST_GET_TEMPS = 0xd1;
672         public static final int REPLY_GET_TEMPS = 0xd2;
673         public static final int REQUEST_SET_TEMPS = 0xd3;
674         public static final int REQUEST_GET_STATES = 0xd5;
675         public static final int REPLY_GET_STATES = 0xd6;
676         public static final int REQUEST_SET_STATES = 0xd7;
677         public static final int REQUEST_GET_ERRORS = 0xd9;
678         public static final int REPLY_GET_ERRORS = 0xda;
679         public static final int REQUEST_SET_RESETS = 0xdb;
680         public static final int REQUEST_GET_HOURS = 0xdd;
681         public static final int REPLY_GET_HOURS = 0xde;
682         public static final int REQUEST_GET_BYPASS = 0xdf;
683         public static final int REPLY_GET_BYPASS = 0xe0;
684         public static final int REQUEST_GET_PREHEATER = 0xe1;
685         public static final int REPLY_GET_PREHEATER = 0xe2;
686         public static final int REQUEST_GET_RF = 0xe5;
687         public static final int REPLY_GET_RF = 0xe6;
688         public static final int REQUEST_GET_GHX = 0xeb;
689         public static final int REPLY_GET_GHX = 0xec;
690         public static final int REQUEST_SET_GHX = 0xed;
691
692         public static final String[] EMPTY_STRING_ARRAY = new String[0];
693         public static final int[] EMPTY_INT_ARRAY = new int[0];
694         public static final ComfoAirCommandType[] EMPTY_TYPE_ARRAY = new ComfoAirCommandType[0];
695     }
696
697     /**
698      * @return command key
699      */
700     public String getKey() {
701         return key;
702     }
703
704     /**
705      * @return data type for this command key
706      */
707     public ComfoAirDataType getDataType() {
708         return dataType;
709     }
710
711     /**
712      * @return readCommand for this command key
713      */
714     public int getReadCommand() {
715         return readCommand;
716     }
717
718     /**
719      * @return readCommand for this command key
720      */
721     public int getReadReplyCommand() {
722         return readReplyCommand;
723     }
724
725     /**
726      * @return possible byte values
727      */
728     public int @Nullable [] getPossibleValues() {
729         return possibleValues;
730     }
731
732     /**
733      * @return relevant byte position inside the response byte value array
734      */
735     public int getChangeDataPos() {
736         return changeDataPos;
737     }
738
739     /**
740      * @return generate a byte value sequence for the response stream
741      */
742     public int[] getChangeDataTemplate() {
743         int[] template = new int[changeDataSize];
744         for (int i = 0; i < template.length; i++) {
745             template[i] = 0x00;
746         }
747         return template;
748     }
749
750     /**
751      * @return byte position inside the request byte value array
752      */
753     public int @Nullable [] getReadReplyDataPos() {
754         return readReplyDataPos;
755     }
756
757     /**
758      * @return bit mask for the response byte value
759      */
760     public int getReadReplyDataBits() {
761         return readReplyDataBits;
762     }
763
764     /**
765      * Get single read command to update item.
766      *
767      * @param key
768      *
769      * @return ComfoAirCommand identified by key
770      */
771     public static @Nullable ComfoAirCommand getReadCommand(String key) {
772         ComfoAirCommandType commandType = getCommandTypeByKey(key);
773
774         if (commandType != null && commandType.readCommand > 0) {
775             return new ComfoAirCommand(key);
776         }
777         return null;
778     }
779
780     /**
781      * Get a command to change properties on the comfoair.
782      *
783      * @param key
784      *            command key
785      * @param value
786      *            new state
787      * @return initialized ComfoAirCommand
788      */
789     @SuppressWarnings("PMD.CompareObjectsWithEquals")
790     public static @Nullable ComfoAirCommand getChangeCommand(String key, Command command) {
791         ComfoAirCommandType commandType = getCommandTypeByKey(key);
792         State value = UnDefType.NULL;
793
794         if (commandType != null) {
795             ComfoAirDataType dataType = commandType.getDataType();
796             if (dataType == DataTypeBoolean.getInstance() || dataType == DataTypeNumber.getInstance()
797                     || dataType == DataTypeRPM.getInstance() || command instanceof QuantityType<?>) {
798                 value = (State) command;
799             }
800             if (value instanceof UnDefType) {
801                 return null;
802             } else {
803                 int[] data = dataType.convertFromState(value, commandType);
804                 DecimalType decimalValue = value.as(DecimalType.class);
805                 if (decimalValue != null) {
806                     int intValue = decimalValue.intValue();
807
808                     if (data != null) {
809                         int dataPosition = commandType.getChangeDataPos();
810                         return new ComfoAirCommand(key, commandType.changeCommand, null, data, dataPosition, intValue);
811                     }
812                 }
813             }
814         }
815         return null;
816     }
817
818     /**
819      * Get all commands which should be refreshed after a successful change
820      * command.
821      *
822      * @param key
823      *            command key
824      * @param usedKeys
825      * @return ComfoAirCommand's which should be updated after a modifying
826      *         ComfoAirCommand named by key
827      */
828     public static Collection<ComfoAirCommand> getAffectedReadCommands(String key, Set<String> usedKeys) {
829         Map<Integer, ComfoAirCommand> commands = new HashMap<>();
830
831         ComfoAirCommandType commandType = getCommandTypeByKey(key);
832         if (commandType != null) {
833             uniteCommandsMap(commands, commandType);
834
835             if (commandType.changeAffected != null) {
836                 for (ComfoAirCommandType affectedCommandType : commandType.changeAffected) {
837                     // refresh affected event keys only when they are used
838                     if (usedKeys.contains(affectedCommandType.getKey())) {
839                         uniteCommandsMap(commands, affectedCommandType);
840                     }
841                 }
842             }
843         }
844         return commands.values();
845     }
846
847     /**
848      * Get all commands which receive informations to update items.
849      *
850      * @return all ComfoAirCommand's identified by keys
851      */
852     public static Collection<ComfoAirCommand> getReadCommandsByEventTypes(List<String> keys) {
853         Map<Integer, ComfoAirCommand> commands = new HashMap<>();
854         for (ComfoAirCommandType entry : values()) {
855             if (keys.contains(entry.key)) {
856                 uniteCommandsMap(commands, entry);
857             }
858         }
859         return commands.values();
860     }
861
862     /**
863      * Get commandtypes which matches the replyCmd.
864      *
865      * @param replyCmd
866      *            reply command byte value
867      * @return ComfoAirCommandType identified by replyCmd
868      */
869     public static List<ComfoAirCommandType> getCommandTypesByReplyCmd(int replyCmd) {
870         List<ComfoAirCommandType> commands = new ArrayList<>();
871         for (ComfoAirCommandType entry : values()) {
872             if (entry.readReplyCommand == replyCmd) {
873                 commands.add(entry);
874             }
875         }
876         return commands;
877     }
878
879     /**
880      * Get a specific command.
881      *
882      * @param key
883      *            command key
884      * @return ComfoAirCommandType identified by key
885      */
886     public static @Nullable ComfoAirCommandType getCommandTypeByKey(String key) {
887         for (ComfoAirCommandType entry : values()) {
888             if (entry.key.equals(key)) {
889                 return entry;
890             }
891         }
892         return null;
893     }
894
895     private static void uniteCommandsMap(Map<Integer, ComfoAirCommand> commands, ComfoAirCommandType commandType) {
896         if (commandType.readReplyCommand != 0) {
897             int replyCmd = commandType.readReplyCommand;
898
899             ComfoAirCommand command = commands.get(replyCmd);
900
901             if (command == null) {
902                 command = new ComfoAirCommand(commandType.key);
903                 commands.put(replyCmd, command);
904             } else {
905                 command.addKey(commandType.key);
906             }
907         }
908     }
909 }