2 * Copyright (c) 2010-2024 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.freeathomesystem.internal.datamodel;
15 import static org.openhab.binding.freeathomesystem.internal.datamodel.FreeAtHomeDatapoint.*;
16 import static org.openhab.binding.freeathomesystem.internal.util.FidTranslationUtils.*;
18 import java.util.ArrayList;
19 import java.util.List;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.freeathomesystem.internal.util.FidTranslationUtils;
24 import org.openhab.binding.freeathomesystem.internal.util.FreeAtHomeGeneralException;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
28 import com.google.gson.JsonObject;
31 * The {@link FreeAtHomeDeviceChannel} holding the information of device channels
33 * @author Andras Uhrin - Initial contribution
37 public class FreeAtHomeDeviceChannel {
39 private final Logger logger = LoggerFactory.getLogger(FreeAtHomeDeviceChannel.class);
41 private String channelLabel = "";
42 private String channelId = "";
43 private String channelFunctionID = "";
45 private List<FreeAtHomeDatapointGroup> datapointGroups = new ArrayList<>();
47 public boolean createChannelFromJson(String deviceLabel, String channelId, JsonObject jsonObjectOfChannels,
48 boolean isScene, boolean isRule) {
49 JsonObject channelObject = jsonObjectOfChannels.getAsJsonObject(channelId);
51 channelFunctionID = channelObject.get("functionID").getAsString();
53 // check whether this is a valid channel
54 if (channelFunctionID.isEmpty()) {
55 // invalid channel found
56 logger.info("Invalid channel function ID found - Devicelabel: {} Channel: {}", deviceLabel, channelId);
61 if (!channelFunctionID.isEmpty()) {
62 channelLabel = channelObject.get("displayName").getAsString();
64 if (channelLabel.isEmpty()) {
65 channelLabel = deviceLabel;
70 channelFunctionID = channelFunctionID.substring(0, channelFunctionID.length() - 1) + "0";
73 switch (Integer.parseInt(channelFunctionID, 16)) {
74 case FID_PANEL_SWITCH_SENSOR:
75 case FID_SWITCH_SENSOR: {
76 this.channelId = channelId;
78 logger.debug("Switch sensor channel found - Channel FID: {}", channelFunctionID);
80 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
81 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1, channelId, channelObject);
83 datapointGroups.add(newDatapointGroup);
87 case FID_PANEL_DIMMING_SENSOR:
88 case FID_DIMMING_SENSOR: {
89 this.channelId = channelId;
91 logger.debug("Dimming sensor channel found - Channel FID: {}", channelFunctionID);
93 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
94 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 17, channelId, channelObject);
96 datapointGroups.add(newDatapointGroup);
98 newDatapointGroup = new FreeAtHomeDatapointGroup();
99 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1, channelId, channelObject);
101 datapointGroups.add(newDatapointGroup);
106 case FID_SWITCH_ACTUATOR: {
107 this.channelId = channelId;
109 logger.debug("Switch actuator channel created - Channel FID: {}", channelFunctionID);
111 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
112 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
113 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 1, channelId, channelObject);
115 datapointGroups.add(newDatapointGroup);
119 case FID_MOVEMENT_DETECTOR_FLEX:
120 case FID_MOVEMENT_DETECTOR: {
121 this.channelId = channelId;
123 logger.debug("Movement detector channel found - Channel FID: {}", channelFunctionID);
125 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
126 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 6, channelId, channelObject);
128 datapointGroups.add(newDatapointGroup);
130 newDatapointGroup = new FreeAtHomeDatapointGroup();
131 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 7, channelId, channelObject);
133 datapointGroups.add(newDatapointGroup);
135 newDatapointGroup = new FreeAtHomeDatapointGroup();
136 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1027, channelId, channelObject);
138 datapointGroups.add(newDatapointGroup);
140 newDatapointGroup = new FreeAtHomeDatapointGroup();
141 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT_AS_OUTPUT, 256, channelId,
144 datapointGroups.add(newDatapointGroup);
148 case FID_ROOM_TEMPERATURE_CONTROLLER_MASTER_WITHOUT_FAN:
149 case FID_RADIATOR_ACTUATOR_MASTER: {
150 this.channelId = channelId;
152 if (Integer.parseInt(channelFunctionID, 16) == FID_RADIATOR_ACTUATOR_MASTER) {
153 logger.debug("Radiator actuator channel - Channel FID: {}", channelFunctionID);
155 logger.debug("Room temperature actuator channel - Channel FID: {}", channelFunctionID);
158 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
159 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 304, channelId, channelObject);
160 datapointGroups.add(newDatapointGroup);
162 newDatapointGroup = new FreeAtHomeDatapointGroup();
163 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 333, channelId, channelObject);
164 datapointGroups.add(newDatapointGroup);
166 newDatapointGroup = new FreeAtHomeDatapointGroup();
167 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 331, channelId, channelObject);
168 datapointGroups.add(newDatapointGroup);
170 newDatapointGroup = new FreeAtHomeDatapointGroup();
171 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 54, channelId, channelObject);
172 datapointGroups.add(newDatapointGroup);
174 newDatapointGroup = new FreeAtHomeDatapointGroup();
175 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 51, channelId, channelObject);
176 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 320, channelId, channelObject);
177 datapointGroups.add(newDatapointGroup);
179 newDatapointGroup = new FreeAtHomeDatapointGroup();
180 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 68, channelId, channelObject);
181 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 58, channelId, channelObject);
182 datapointGroups.add(newDatapointGroup);
184 newDatapointGroup = new FreeAtHomeDatapointGroup();
185 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 56, channelId, channelObject);
186 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 66, channelId, channelObject);
187 datapointGroups.add(newDatapointGroup);
189 // Additional channel for RTC device
190 if (Integer.parseInt(channelFunctionID, 16) == FID_ROOM_TEMPERATURE_CONTROLLER_MASTER_WITHOUT_FAN) {
191 newDatapointGroup = new FreeAtHomeDatapointGroup();
192 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 48, channelId, channelObject);
193 datapointGroups.add(newDatapointGroup);
198 case FID_WINDOW_DOOR_POSITION_SENSOR:
199 case FID_WINDOW_DOOR_SENSOR: {
200 this.channelId = channelId;
202 logger.debug("Window/Door position sensor channel created - Channel FID: {}", channelFunctionID);
204 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
205 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 53, channelId, channelObject);
206 datapointGroups.add(newDatapointGroup);
208 newDatapointGroup = new FreeAtHomeDatapointGroup();
209 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 41, channelId, channelObject);
210 datapointGroups.add(newDatapointGroup);
214 case FID_SCENE_TRIGGER: {
215 this.channelId = channelId;
217 logger.debug("Scene trigger channel - Channel FID: {}", channelFunctionID);
219 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
220 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 4, channelId, channelObject);
222 datapointGroups.add(newDatapointGroup);
226 case FID_RULE_SWITCH: {
227 this.channelId = channelId;
229 logger.debug("Rule channel - Channel FID: {}", channelFunctionID);
231 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
232 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 61698, channelId, channelObject);
233 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 61697, channelId, channelObject);
235 datapointGroups.add(newDatapointGroup);
239 case FID_DES_DOOR_OPENER_ACTUATOR: {
240 this.channelId = channelId;
242 logger.debug("Door opener actuator channel - Channel FID: {}", channelFunctionID);
244 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
245 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
246 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 2, channelId, channelObject);
248 datapointGroups.add(newDatapointGroup);
252 case FID_DES_LEVEL_CALL_SENSOR:
253 case FID_DES_DOOR_RINGING_SENSOR: {
254 this.channelId = channelId;
256 logger.debug("Door ring sensor channel - Channel FID: {}", channelFunctionID);
258 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
259 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 2, channelId, channelObject);
261 datapointGroups.add(newDatapointGroup);
265 case FID_DES_LIGHT_SWITCH_ACTUATOR: {
266 this.channelId = channelId;
268 logger.debug("DES light switch channel - Channel FID: {}", channelFunctionID);
270 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
271 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
272 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 2, channelId, channelObject);
274 datapointGroups.add(newDatapointGroup);
278 case FID_DIMMING_ACTUATOR_FLEX:
279 case FID_DIMMING_ACTUATOR: {
280 this.channelId = channelId;
282 logger.debug("Dimming actuator channel - Channel FID: {}", channelFunctionID);
284 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
285 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 272, channelId, channelObject);
286 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 17, channelId, channelObject);
288 datapointGroups.add(newDatapointGroup);
290 newDatapointGroup = new FreeAtHomeDatapointGroup();
291 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
292 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 1, channelId, channelObject);
294 datapointGroups.add(newDatapointGroup);
298 case FID_AWNING_ACTUATOR:
299 case FID_ATTIC_WINDOW_ACTUATOR:
300 case FID_BLIND_ACTUATOR:
301 case FID_SHUTTER_ACTUATOR: {
302 this.channelId = channelId;
304 logger.debug("Shutter actuator channel - Channel FID: {}", channelFunctionID);
306 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
307 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 32, channelId, channelObject);
308 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 288, channelId, channelObject);
309 datapointGroups.add(newDatapointGroup);
311 newDatapointGroup = new FreeAtHomeDatapointGroup();
312 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 33, channelId, channelObject);
313 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 288, channelId, channelObject);
314 datapointGroups.add(newDatapointGroup);
316 newDatapointGroup = new FreeAtHomeDatapointGroup();
317 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 289, channelId, channelObject);
318 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 35, channelId, channelObject);
320 datapointGroups.add(newDatapointGroup);
324 case FID_BRIGHTNESS_SENSOR: {
325 this.channelId = channelId;
327 logger.debug("Brightness sensor channel - Channel FID: {}", channelFunctionID);
329 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
330 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1026, channelId, channelObject);
331 datapointGroups.add(newDatapointGroup);
333 newDatapointGroup = new FreeAtHomeDatapointGroup();
334 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1027, channelId, channelObject);
335 datapointGroups.add(newDatapointGroup);
339 case FID_RAIN_SENSOR: {
340 this.channelId = channelId;
342 logger.debug("Rain sensor channel - Channel FID: {}", channelFunctionID);
344 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
345 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 39, channelId, channelObject);
346 datapointGroups.add(newDatapointGroup);
348 newDatapointGroup = new FreeAtHomeDatapointGroup();
349 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1029, channelId, channelObject);
350 datapointGroups.add(newDatapointGroup);
352 newDatapointGroup = new FreeAtHomeDatapointGroup();
353 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1030, channelId, channelObject);
354 datapointGroups.add(newDatapointGroup);
358 case FID_TEMPERATURE_SENSOR: {
359 this.channelId = channelId;
361 logger.debug("Temperature sensor channel - Channel FID: {}", channelFunctionID);
363 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
364 if (newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 38, channelId, channelObject)) {
365 datapointGroups.add(newDatapointGroup);
368 newDatapointGroup = new FreeAtHomeDatapointGroup();
369 if (newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1024, channelId, channelObject)) {
370 datapointGroups.add(newDatapointGroup);
373 newDatapointGroup = new FreeAtHomeDatapointGroup();
374 if (newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 304, channelId, channelObject)) {
375 datapointGroups.add(newDatapointGroup);
380 case FID_WIND_SENSOR: {
381 this.channelId = channelId;
383 logger.debug("Wind sensor channel - Channel FID: {}", channelFunctionID);
385 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
386 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 37, channelId, channelObject);
387 datapointGroups.add(newDatapointGroup);
389 newDatapointGroup = new FreeAtHomeDatapointGroup();
390 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1025, channelId, channelObject);
391 datapointGroups.add(newDatapointGroup);
393 newDatapointGroup = new FreeAtHomeDatapointGroup();
394 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1028, channelId, channelObject);
395 datapointGroups.add(newDatapointGroup);
399 case FID_AIRQUALITYSENSOR_CO: {
400 this.channelId = channelId;
402 logger.debug("AQS CO channel - Channel FID: {}", channelFunctionID);
404 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
405 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1564, channelId, channelObject);
406 datapointGroups.add(newDatapointGroup);
410 case FID_AIRQUALITYSENSOR_CO2: {
411 this.channelId = channelId;
413 logger.debug("AQS CO2 channel - Channel FID: {}", channelFunctionID);
415 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
416 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1563, channelId, channelObject);
417 datapointGroups.add(newDatapointGroup);
421 case FID_AIRQUALITYSENSOR_HUMIDITY: {
422 this.channelId = channelId;
424 logger.debug("AQS Humidity channel - Channel FID: {}", channelFunctionID);
426 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
427 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 337, channelId, channelObject);
428 datapointGroups.add(newDatapointGroup);
432 case FID_AIRQUALITYSENSOR_PRESSURE: {
433 this.channelId = channelId;
435 logger.debug("AQS Pressure channel - Channel FID: {}", channelFunctionID);
437 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
438 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1562, channelId, channelObject);
439 datapointGroups.add(newDatapointGroup);
443 case FID_AIRQUALITYSENSOR_NO2: {
444 this.channelId = channelId;
446 logger.debug("AQS NO2 channel - Channel FID: {}", channelFunctionID);
448 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
449 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1565, channelId, channelObject);
450 datapointGroups.add(newDatapointGroup);
454 case FID_AIRQUALITYSENSOR_O3: {
455 this.channelId = channelId;
457 logger.debug("AQS O3 channel - Channel FID: {}", channelFunctionID);
459 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
460 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1566, channelId, channelObject);
461 datapointGroups.add(newDatapointGroup);
465 case FID_AIRQUALITYSENSOR_PM10: {
466 this.channelId = channelId;
468 logger.debug("AQS PM10 channel - Channel FID: {}", channelFunctionID);
470 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
471 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1567, channelId, channelObject);
472 datapointGroups.add(newDatapointGroup);
476 case FID_AIRQUALITYSENSOR_VOC: {
477 this.channelId = channelId;
479 logger.debug("AQS VOC channel - Channel FID: {}", channelFunctionID);
481 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
482 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1569, channelId, channelObject);
483 datapointGroups.add(newDatapointGroup);
487 case FID_AIRQUALITYSENSOR_PM25: {
488 this.channelId = channelId;
490 logger.debug("AQS PM25 channel - Channel FID: {}", channelFunctionID);
492 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
493 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1568, channelId, channelObject);
494 datapointGroups.add(newDatapointGroup);
499 logger.debug("Unknown channel found - Channel FID: {}", channelFunctionID);
508 public String getChannelIdforDatapoint() {
512 public String getChannelLabel() {
516 public String getChannelId() {
520 public String getFunctionId() {
521 return channelFunctionID;
524 public @Nullable String getFunctionIdText() throws FreeAtHomeGeneralException {
525 String functionIdText = FidTranslationUtils
526 .getFunctionIdText(String.format("0x%04X", Integer.parseInt(channelFunctionID, 16)));
527 return functionIdText;
530 public int getNumberOfDatapointGroup() {
531 return datapointGroups.size();
534 public FreeAtHomeDatapointGroup getDatapointGroup(int idx) {
535 return datapointGroups.get(idx);
538 public void applyChangesForVirtualDevice() {
539 for (FreeAtHomeDatapointGroup localDatapointGroup : datapointGroups) {
540 localDatapointGroup.applyChangesForVirtualDevice();