]> git.basschouten.com Git - openhab-addons.git/blob
ef75942c224bf4c6b6bbe9fbd65d51ba21fab94a
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.freeathomesystem.internal.datamodel;
14
15 import static org.openhab.binding.freeathomesystem.internal.datamodel.FreeAtHomeDatapoint.*;
16 import static org.openhab.binding.freeathomesystem.internal.util.FidTranslationUtils.*;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
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;
27
28 import com.google.gson.JsonObject;
29
30 /**
31  * The {@link FreeAtHomeDeviceChannel} holding the information of device channels
32  *
33  * @author Andras Uhrin - Initial contribution
34  *
35  */
36 @NonNullByDefault
37 public class FreeAtHomeDeviceChannel {
38
39     private final Logger logger = LoggerFactory.getLogger(FreeAtHomeDeviceChannel.class);
40
41     private String channelLabel = "";
42     private String channelId = "";
43     private String channelFunctionID = "";
44
45     private List<FreeAtHomeDatapointGroup> datapointGroups = new ArrayList<>();
46
47     public boolean createChannelFromJson(String deviceLabel, String channelId, JsonObject jsonObjectOfChannels,
48             boolean isScene, boolean isRule) {
49         JsonObject channelObject = jsonObjectOfChannels.getAsJsonObject(channelId);
50
51         channelFunctionID = channelObject.get("functionID").getAsString();
52
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);
57
58             return false;
59         }
60
61         if (!channelFunctionID.isEmpty()) {
62             channelLabel = channelObject.get("displayName").getAsString();
63
64             if (channelLabel.isEmpty()) {
65                 channelLabel = deviceLabel;
66             }
67         }
68
69         if (isScene) {
70             channelFunctionID = channelFunctionID.substring(0, channelFunctionID.length() - 1) + "0";
71         }
72
73         switch (Integer.parseInt(channelFunctionID, 16)) {
74             case FID_PANEL_SWITCH_SENSOR:
75             case FID_SWITCH_SENSOR: {
76                 this.channelId = channelId;
77
78                 logger.debug("Switch sensor channel found - Channel FID: {}", channelFunctionID);
79
80                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
81                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1, channelId, channelObject);
82
83                 datapointGroups.add(newDatapointGroup);
84
85                 break;
86             }
87             case FID_PANEL_DIMMING_SENSOR:
88             case FID_DIMMING_SENSOR: {
89                 this.channelId = channelId;
90
91                 logger.debug("Dimming sensor channel found - Channel FID: {}", channelFunctionID);
92
93                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
94                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 17, channelId, channelObject);
95
96                 datapointGroups.add(newDatapointGroup);
97
98                 newDatapointGroup = new FreeAtHomeDatapointGroup();
99                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1, channelId, channelObject);
100
101                 datapointGroups.add(newDatapointGroup);
102
103                 break;
104             }
105             case FID_TRIGGER:
106             case FID_SWITCH_ACTUATOR: {
107                 this.channelId = channelId;
108
109                 logger.debug("Switch actuator channel created - Channel FID: {}", channelFunctionID);
110
111                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
112                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
113                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 1, channelId, channelObject);
114
115                 datapointGroups.add(newDatapointGroup);
116
117                 break;
118             }
119             case FID_MOVEMENT_DETECTOR_FLEX:
120             case FID_MOVEMENT_DETECTOR: {
121                 this.channelId = channelId;
122
123                 logger.debug("Movement detector channel found - Channel FID: {}", channelFunctionID);
124
125                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
126                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 6, channelId, channelObject);
127
128                 datapointGroups.add(newDatapointGroup);
129
130                 newDatapointGroup = new FreeAtHomeDatapointGroup();
131                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 7, channelId, channelObject);
132
133                 datapointGroups.add(newDatapointGroup);
134
135                 newDatapointGroup = new FreeAtHomeDatapointGroup();
136                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1027, channelId, channelObject);
137
138                 datapointGroups.add(newDatapointGroup);
139
140                 newDatapointGroup = new FreeAtHomeDatapointGroup();
141                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT_AS_OUTPUT, 256, channelId,
142                         channelObject);
143
144                 datapointGroups.add(newDatapointGroup);
145
146                 break;
147             }
148             case FID_ROOM_TEMPERATURE_CONTROLLER_MASTER_WITHOUT_FAN:
149             case FID_RADIATOR_ACTUATOR_MASTER: {
150                 this.channelId = channelId;
151
152                 if (Integer.parseInt(channelFunctionID, 16) == FID_RADIATOR_ACTUATOR_MASTER) {
153                     logger.debug("Radiator actuator channel - Channel FID: {}", channelFunctionID);
154                 } else {
155                     logger.debug("Room temperature actuator channel - Channel FID: {}", channelFunctionID);
156                 }
157
158                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
159                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 304, channelId, channelObject);
160                 datapointGroups.add(newDatapointGroup);
161
162                 newDatapointGroup = new FreeAtHomeDatapointGroup();
163                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 333, channelId, channelObject);
164                 datapointGroups.add(newDatapointGroup);
165
166                 newDatapointGroup = new FreeAtHomeDatapointGroup();
167                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 331, channelId, channelObject);
168                 datapointGroups.add(newDatapointGroup);
169
170                 newDatapointGroup = new FreeAtHomeDatapointGroup();
171                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 54, channelId, channelObject);
172                 datapointGroups.add(newDatapointGroup);
173
174                 newDatapointGroup = new FreeAtHomeDatapointGroup();
175                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 51, channelId, channelObject);
176                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 320, channelId, channelObject);
177                 datapointGroups.add(newDatapointGroup);
178
179                 newDatapointGroup = new FreeAtHomeDatapointGroup();
180                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 68, channelId, channelObject);
181                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 58, channelId, channelObject);
182                 datapointGroups.add(newDatapointGroup);
183
184                 newDatapointGroup = new FreeAtHomeDatapointGroup();
185                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 56, channelId, channelObject);
186                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 66, channelId, channelObject);
187                 datapointGroups.add(newDatapointGroup);
188
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);
194                 }
195
196                 break;
197             }
198             case FID_WINDOW_DOOR_POSITION_SENSOR:
199             case FID_WINDOW_DOOR_SENSOR: {
200                 this.channelId = channelId;
201
202                 logger.debug("Window/Door position sensor channel created - Channel FID: {}", channelFunctionID);
203
204                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
205                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 53, channelId, channelObject);
206                 datapointGroups.add(newDatapointGroup);
207
208                 newDatapointGroup = new FreeAtHomeDatapointGroup();
209                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 41, channelId, channelObject);
210                 datapointGroups.add(newDatapointGroup);
211
212                 break;
213             }
214             case FID_SCENE_TRIGGER: {
215                 this.channelId = channelId;
216
217                 logger.debug("Scene trigger channel - Channel FID: {}", channelFunctionID);
218
219                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
220                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 4, channelId, channelObject);
221
222                 datapointGroups.add(newDatapointGroup);
223
224                 break;
225             }
226             case FID_RULE_SWITCH: {
227                 this.channelId = channelId;
228
229                 logger.debug("Rule channel - Channel FID: {}", channelFunctionID);
230
231                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
232                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 61698, channelId, channelObject);
233                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 61697, channelId, channelObject);
234
235                 datapointGroups.add(newDatapointGroup);
236
237                 break;
238             }
239             case FID_DES_DOOR_OPENER_ACTUATOR: {
240                 this.channelId = channelId;
241
242                 logger.debug("Door opener actuator channel - Channel FID: {}", channelFunctionID);
243
244                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
245                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
246                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 2, channelId, channelObject);
247
248                 datapointGroups.add(newDatapointGroup);
249
250                 break;
251             }
252             case FID_DES_LEVEL_CALL_SENSOR:
253             case FID_DES_DOOR_RINGING_SENSOR: {
254                 this.channelId = channelId;
255
256                 logger.debug("Door ring sensor channel - Channel FID: {}", channelFunctionID);
257
258                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
259                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 2, channelId, channelObject);
260
261                 datapointGroups.add(newDatapointGroup);
262
263                 break;
264             }
265             case FID_DES_LIGHT_SWITCH_ACTUATOR: {
266                 this.channelId = channelId;
267
268                 logger.debug("DES light switch channel - Channel FID: {}", channelFunctionID);
269
270                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
271                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
272                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 2, channelId, channelObject);
273
274                 datapointGroups.add(newDatapointGroup);
275
276                 break;
277             }
278             case FID_DIMMING_ACTUATOR_FLEX:
279             case FID_DIMMING_ACTUATOR: {
280                 this.channelId = channelId;
281
282                 logger.debug("Dimming actuator channel - Channel FID: {}", channelFunctionID);
283
284                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
285                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 272, channelId, channelObject);
286                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 17, channelId, channelObject);
287
288                 datapointGroups.add(newDatapointGroup);
289
290                 newDatapointGroup = new FreeAtHomeDatapointGroup();
291                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 256, channelId, channelObject);
292                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 1, channelId, channelObject);
293
294                 datapointGroups.add(newDatapointGroup);
295
296                 break;
297             }
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;
303
304                 logger.debug("Shutter actuator channel - Channel FID: {}", channelFunctionID);
305
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);
310
311                 newDatapointGroup = new FreeAtHomeDatapointGroup();
312                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 33, channelId, channelObject);
313                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 288, channelId, channelObject);
314                 datapointGroups.add(newDatapointGroup);
315
316                 newDatapointGroup = new FreeAtHomeDatapointGroup();
317                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 289, channelId, channelObject);
318                 newDatapointGroup.addDatapointToGroup(DatapointDirection.INPUT, 35, channelId, channelObject);
319
320                 datapointGroups.add(newDatapointGroup);
321
322                 break;
323             }
324             case FID_BRIGHTNESS_SENSOR: {
325                 this.channelId = channelId;
326
327                 logger.debug("Brightness sensor channel - Channel FID: {}", channelFunctionID);
328
329                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
330                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1026, channelId, channelObject);
331                 datapointGroups.add(newDatapointGroup);
332
333                 newDatapointGroup = new FreeAtHomeDatapointGroup();
334                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1027, channelId, channelObject);
335                 datapointGroups.add(newDatapointGroup);
336
337                 break;
338             }
339             case FID_RAIN_SENSOR: {
340                 this.channelId = channelId;
341
342                 logger.debug("Rain sensor channel - Channel FID: {}", channelFunctionID);
343
344                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
345                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 39, channelId, channelObject);
346                 datapointGroups.add(newDatapointGroup);
347
348                 newDatapointGroup = new FreeAtHomeDatapointGroup();
349                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1029, channelId, channelObject);
350                 datapointGroups.add(newDatapointGroup);
351
352                 newDatapointGroup = new FreeAtHomeDatapointGroup();
353                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1030, channelId, channelObject);
354                 datapointGroups.add(newDatapointGroup);
355
356                 break;
357             }
358             case FID_TEMPERATURE_SENSOR: {
359                 this.channelId = channelId;
360
361                 logger.debug("Temperature sensor channel - Channel FID: {}", channelFunctionID);
362
363                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
364                 if (newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 38, channelId, channelObject)) {
365                     datapointGroups.add(newDatapointGroup);
366                 }
367
368                 newDatapointGroup = new FreeAtHomeDatapointGroup();
369                 if (newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1024, channelId, channelObject)) {
370                     datapointGroups.add(newDatapointGroup);
371                 }
372
373                 newDatapointGroup = new FreeAtHomeDatapointGroup();
374                 if (newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 304, channelId, channelObject)) {
375                     datapointGroups.add(newDatapointGroup);
376                 }
377
378                 break;
379             }
380             case FID_WIND_SENSOR: {
381                 this.channelId = channelId;
382
383                 logger.debug("Wind sensor channel - Channel FID: {}", channelFunctionID);
384
385                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
386                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 37, channelId, channelObject);
387                 datapointGroups.add(newDatapointGroup);
388
389                 newDatapointGroup = new FreeAtHomeDatapointGroup();
390                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1025, channelId, channelObject);
391                 datapointGroups.add(newDatapointGroup);
392
393                 newDatapointGroup = new FreeAtHomeDatapointGroup();
394                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1028, channelId, channelObject);
395                 datapointGroups.add(newDatapointGroup);
396
397                 break;
398             }
399             case FID_AIRQUALITYSENSOR_CO: {
400                 this.channelId = channelId;
401
402                 logger.debug("AQS CO channel - Channel FID: {}", channelFunctionID);
403
404                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
405                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1564, channelId, channelObject);
406                 datapointGroups.add(newDatapointGroup);
407
408                 break;
409             }
410             case FID_AIRQUALITYSENSOR_CO2: {
411                 this.channelId = channelId;
412
413                 logger.debug("AQS CO2 channel - Channel FID: {}", channelFunctionID);
414
415                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
416                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1563, channelId, channelObject);
417                 datapointGroups.add(newDatapointGroup);
418
419                 break;
420             }
421             case FID_AIRQUALITYSENSOR_HUMIDITY: {
422                 this.channelId = channelId;
423
424                 logger.debug("AQS Humidity channel - Channel FID: {}", channelFunctionID);
425
426                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
427                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 337, channelId, channelObject);
428                 datapointGroups.add(newDatapointGroup);
429
430                 break;
431             }
432             case FID_AIRQUALITYSENSOR_PRESSURE: {
433                 this.channelId = channelId;
434
435                 logger.debug("AQS Pressure channel - Channel FID: {}", channelFunctionID);
436
437                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
438                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1562, channelId, channelObject);
439                 datapointGroups.add(newDatapointGroup);
440
441                 break;
442             }
443             case FID_AIRQUALITYSENSOR_NO2: {
444                 this.channelId = channelId;
445
446                 logger.debug("AQS NO2 channel - Channel FID: {}", channelFunctionID);
447
448                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
449                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1565, channelId, channelObject);
450                 datapointGroups.add(newDatapointGroup);
451
452                 break;
453             }
454             case FID_AIRQUALITYSENSOR_O3: {
455                 this.channelId = channelId;
456
457                 logger.debug("AQS O3 channel - Channel FID: {}", channelFunctionID);
458
459                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
460                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1566, channelId, channelObject);
461                 datapointGroups.add(newDatapointGroup);
462
463                 break;
464             }
465             case FID_AIRQUALITYSENSOR_PM10: {
466                 this.channelId = channelId;
467
468                 logger.debug("AQS PM10 channel - Channel FID: {}", channelFunctionID);
469
470                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
471                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1567, channelId, channelObject);
472                 datapointGroups.add(newDatapointGroup);
473
474                 break;
475             }
476             case FID_AIRQUALITYSENSOR_VOC: {
477                 this.channelId = channelId;
478
479                 logger.debug("AQS VOC channel - Channel FID: {}", channelFunctionID);
480
481                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
482                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1569, channelId, channelObject);
483                 datapointGroups.add(newDatapointGroup);
484
485                 break;
486             }
487             case FID_AIRQUALITYSENSOR_PM25: {
488                 this.channelId = channelId;
489
490                 logger.debug("AQS PM25 channel - Channel FID: {}", channelFunctionID);
491
492                 FreeAtHomeDatapointGroup newDatapointGroup = new FreeAtHomeDatapointGroup();
493                 newDatapointGroup.addDatapointToGroup(DatapointDirection.OUTPUT, 1568, channelId, channelObject);
494                 datapointGroups.add(newDatapointGroup);
495
496                 break;
497             }
498             default: {
499                 logger.debug("Unknown channel found - Channel FID: {}", channelFunctionID);
500
501                 return false;
502             }
503         }
504
505         return true;
506     }
507
508     public String getChannelIdforDatapoint() {
509         return channelId;
510     }
511
512     public String getChannelLabel() {
513         return channelLabel;
514     }
515
516     public String getChannelId() {
517         return channelId;
518     }
519
520     public String getFunctionId() {
521         return channelFunctionID;
522     }
523
524     public @Nullable String getFunctionIdText() throws FreeAtHomeGeneralException {
525         String functionIdText = FidTranslationUtils
526                 .getFunctionIdText(String.format("0x%04X", Integer.parseInt(channelFunctionID, 16)));
527         return functionIdText;
528     }
529
530     public int getNumberOfDatapointGroup() {
531         return datapointGroups.size();
532     }
533
534     public FreeAtHomeDatapointGroup getDatapointGroup(int idx) {
535         return datapointGroups.get(idx);
536     }
537
538     public void applyChangesForVirtualDevice() {
539         for (FreeAtHomeDatapointGroup localDatapointGroup : datapointGroups) {
540             localDatapointGroup.applyChangesForVirtualDevice();
541         }
542     }
543 }