]> git.basschouten.com Git - openhab-addons.git/blob
1d48f537c83f57b2dcdf1793d4592c4bd0e72662
[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.digitalstrom.internal.providers;
14
15 import static org.openhab.binding.digitalstrom.internal.DigitalSTROMBindingConstants.BINDING_ID;
16
17 import java.math.BigDecimal;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.Collection;
21 import java.util.HashSet;
22 import java.util.LinkedList;
23 import java.util.List;
24 import java.util.Locale;
25 import java.util.Set;
26
27 import org.openhab.binding.digitalstrom.internal.DigitalSTROMBindingConstants;
28 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.deviceparameters.constants.ApplicationGroup;
29 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.deviceparameters.constants.DeviceBinarayInputEnum;
30 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.deviceparameters.constants.MeteringTypeEnum;
31 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.deviceparameters.constants.MeteringUnitsEnum;
32 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.deviceparameters.constants.OutputChannelEnum;
33 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.deviceparameters.constants.OutputModeEnum;
34 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.deviceparameters.constants.SensorEnum;
35 import org.openhab.core.i18n.TranslationProvider;
36 import org.openhab.core.thing.type.ChannelGroupTypeUID;
37 import org.openhab.core.thing.type.ChannelType;
38 import org.openhab.core.thing.type.ChannelTypeBuilder;
39 import org.openhab.core.thing.type.ChannelTypeProvider;
40 import org.openhab.core.thing.type.ChannelTypeUID;
41 import org.openhab.core.types.StateDescriptionFragment;
42 import org.openhab.core.types.StateDescriptionFragmentBuilder;
43 import org.openhab.core.types.StateOption;
44 import org.osgi.service.component.ComponentContext;
45 import org.osgi.service.component.annotations.Activate;
46 import org.osgi.service.component.annotations.Component;
47 import org.osgi.service.component.annotations.Deactivate;
48 import org.osgi.service.component.annotations.Reference;
49
50 /**
51  * The {@link DsChannelTypeProvider} implements the {@link ChannelTypeProvider}
52  * generates all supported {@link Channel}'s for digitalSTROM.
53  *
54  * @author Michael Ochel - Initial contribution
55  * @author Matthias Siegele - Initial contribution
56  *
57  */
58 @Component(service = ChannelTypeProvider.class)
59 public class DsChannelTypeProvider extends BaseDsI18n implements ChannelTypeProvider {
60
61     // channelID building (effect group type + (nothing || SEPERATOR + item type ||
62     // SEPERATOR + extended item type) e.g.
63     // light_switch, shade or shade_angle
64     // channel effect group type
65     public static final String LIGHT = "light"; // and tag
66     public static final String SHADE = "shade"; // and tag
67     public static final String HEATING = "heating"; // and tag
68     public static final String GENERAL = "general";
69     public static final String SCENE = "scene";
70     // channel extended item type
71     public static final String WIPE = "wipe";
72     public static final String ANGLE = "angle";
73     public static final String STAGE = "stage"; // pre stageses e.g. 2+STAGE_SWITCH
74     public static final String TEMPERATURE_CONTROLLED = "temperature_controlled";
75
76     // item types
77     public static final String DIMMER = "Dimmer";
78     public static final String SWITCH = "Switch";
79     public static final String ROLLERSHUTTER = "Rollershutter";
80     public static final String STRING = "String";
81     public static final String NUMBER = "Number";
82
83     public static final String TOTAL_PRE = "total";
84     public static final String BINARY_INPUT_PRE = "binary_input";
85     public static final String OPTION = "opt";
86
87     // tags
88     public static final String GE = "GE";
89     public static final String GR = "GR";
90     public static final String BL = "BL";
91     public static final String SW = "SW";
92     public static final String DS = "DS";
93     public static final String JOKER = "JOKER";
94
95     // categories
96     public static final String CATEGORY_BLINDES = "Blinds";
97     public static final String CATEGORY_DIMMABLE_LIGHT = "DimmableLight";
98     public static final String CATEGORY_CARBONE_DIOXIDE = "CarbonDioxide";
99     public static final String CATEGORY_ENERGY = "Energy";
100     public static final String CATEGORY_HUMIDITY = "Humidity";
101     public static final String CATEGORY_BRIGHTNESS = "Brightness";
102     public static final String CATEGORY_LIGHT = "Light";
103     public static final String CATEGORY_PRESSURE = "Pressure";
104     public static final String CATEGORY_SOUND_VOLUME = "SoundVolume";
105     public static final String CATEGORY_TEMPERATURE = "Temperature";
106     public static final String CATEGORY_WIND = "Wind";
107     public static final String CATEGORY_RAIN = "Rain";
108     public static final String CATEGORY_BATTERY = "Battery";
109     public static final String CATEGORY_DOOR = "Door";
110     public static final String CATEGORY_WINDOW = "Window";
111     public static final String CATEGORY_GARAGE_DOOR = "GarageDoor";
112     public static final String CATEGORY_SMOKE = "Smoke";
113     public static final String CATEGORY_ALARM = "Alarm";
114     public static final String CATEGORY_MOTION = "Motion";
115
116     /**
117      * Returns the output channel type id as {@link String} for the given
118      * {@link ApplicationGroup.Color} and {@link OutputModeEnum} or null, if no
119      * channel type exists for the given {@link ApplicationGroup.Color} and
120      * {@link OutputModeEnum}.
121      *
122      * @param functionalGroup of the {@link Device}
123      * @param outputMode of the {@link Device}
124      * @return the output channel type id or null
125      */
126     public static String getOutputChannelTypeID(ApplicationGroup.Color functionalGroup, OutputModeEnum outputMode,
127             List<OutputChannelEnum> outputChannels) {
128         if (functionalGroup != null && outputMode != null) {
129             String channelPreID = GENERAL;
130
131             switch (functionalGroup) {
132                 case YELLOW:
133                     channelPreID = LIGHT;
134                     break;
135                 case GREY:
136                     if (outputChannels != null && (outputChannels.contains(OutputChannelEnum.SHADE_OPENING_ANGLE_INDOOR)
137                             || outputChannels.contains(OutputChannelEnum.SHADE_OPENING_ANGLE_OUTSIDE))) {
138                         return buildIdentifier(SHADE, ANGLE);
139                     } else {
140                         return buildIdentifier(SHADE);
141                     }
142                 case BLUE:
143                     channelPreID = HEATING;
144                     if (OutputModeEnum.outputModeIsTemperationControlled(outputMode)) {
145                         return buildIdentifier(channelPreID, TEMPERATURE_CONTROLLED);
146                     }
147                 default:
148                     break;
149             }
150
151             if (OutputModeEnum.outputModeIsSwitch(outputMode)) {
152                 return buildIdentifier(channelPreID, SWITCH);
153             }
154             if (OutputModeEnum.outputModeIsDimmable(outputMode)) {
155                 return buildIdentifier(channelPreID, DIMMER);
156             }
157             if (!channelPreID.equals(HEATING)) {
158                 if (outputMode.equals(OutputModeEnum.COMBINED_2_STAGE_SWITCH)) {
159                     return buildIdentifier(channelPreID, "2", STAGE);
160                 }
161                 if (outputMode.equals(OutputModeEnum.COMBINED_3_STAGE_SWITCH)) {
162                     return buildIdentifier(channelPreID, "3", STAGE);
163                 }
164             }
165         }
166         return null;
167     }
168
169     public static String getMeteringChannelID(MeteringTypeEnum type, MeteringUnitsEnum unit, boolean isTotal) {
170         if (isTotal) {
171             return buildIdentifier(TOTAL_PRE, type, unit);
172         } else {
173             return buildIdentifier(type, unit);
174         }
175     }
176
177     public static MeteringTypeEnum getMeteringType(String channelID) {
178         // check metering channel
179         String[] meteringChannelSplit = channelID.split(SEPERATOR);
180         if (meteringChannelSplit.length > 1) {
181             short offset = 0;
182             // if total_
183             if (meteringChannelSplit.length == 3) {
184                 offset = 1;
185             }
186             try {
187                 // check through IllegalArgumentException, if channel is metering
188                 return MeteringTypeEnum.valueOf(meteringChannelSplit[0 + offset].toUpperCase());
189             } catch (IllegalArgumentException e) {
190                 return null;
191             }
192         }
193         return null;
194     }
195
196     private static final List<String> SUPPORTED_OUTPUT_CHANNEL_TYPES = new ArrayList<>();
197
198     /**
199      * Returns true, if the given channel type id is an output channel.
200      *
201      * @param channelTypeID to check
202      * @return true, if channel type id is output channel
203      */
204     public static boolean isOutputChannel(String channelTypeID) {
205         return SUPPORTED_OUTPUT_CHANNEL_TYPES.contains(channelTypeID);
206     }
207
208     @Activate
209     @Override
210     protected void activate(ComponentContext componentContext) {
211         super.activate(componentContext);
212     }
213
214     @Deactivate
215     @Override
216     protected void deactivate(ComponentContext componentContext) {
217         super.deactivate(componentContext);
218     }
219
220     @Reference
221     @Override
222     protected void setTranslationProvider(TranslationProvider translationProvider) {
223         super.setTranslationProvider(translationProvider);
224     }
225
226     @Override
227     protected void unsetTranslationProvider(TranslationProvider translationProvider) {
228         super.unsetTranslationProvider(translationProvider);
229     }
230
231     @Override
232     protected void init() {
233         String channelIDpre = GENERAL;
234         for (short i = 0; i < 3; i++) {
235             if (i == 1) {
236                 channelIDpre = LIGHT;
237             }
238             if (i == 2) {
239                 channelIDpre = HEATING;
240                 SUPPORTED_OUTPUT_CHANNEL_TYPES.add(buildIdentifier(channelIDpre, TEMPERATURE_CONTROLLED));
241             }
242             SUPPORTED_OUTPUT_CHANNEL_TYPES.add(buildIdentifier(channelIDpre, SWITCH));
243             SUPPORTED_OUTPUT_CHANNEL_TYPES.add(buildIdentifier(channelIDpre, DIMMER));
244             if (i < 2) {
245                 SUPPORTED_OUTPUT_CHANNEL_TYPES.add(buildIdentifier(channelIDpre, "2", STAGE));
246                 SUPPORTED_OUTPUT_CHANNEL_TYPES.add(buildIdentifier(channelIDpre, "3", STAGE));
247             }
248         }
249         channelIDpre = SHADE;
250         SUPPORTED_OUTPUT_CHANNEL_TYPES.add(channelIDpre);
251         SUPPORTED_OUTPUT_CHANNEL_TYPES.add(buildIdentifier(channelIDpre, ANGLE));
252         SUPPORTED_OUTPUT_CHANNEL_TYPES.add(SCENE);
253     }
254
255     private String getSensorCategory(SensorEnum sensorType) {
256         switch (sensorType) {
257             case ACTIVE_POWER:
258             case ELECTRIC_METER:
259             case OUTPUT_CURRENT:
260             case OUTPUT_CURRENT_H:
261             case POWER_CONSUMPTION:
262                 return CATEGORY_ENERGY;
263             case AIR_PRESSURE:
264                 return CATEGORY_PRESSURE;
265             case CARBON_DIOXIDE:
266                 return CATEGORY_CARBONE_DIOXIDE;
267             case PRECIPITATION:
268                 return CATEGORY_RAIN;
269             case RELATIVE_HUMIDITY_INDOORS:
270             case RELATIVE_HUMIDITY_OUTDOORS:
271                 return CATEGORY_HUMIDITY;
272             case ROOM_TEMPERATURE_CONTROL_VARIABLE:
273                 break;
274             case ROOM_TEMPERATURE_SET_POINT:
275                 break;
276             case TEMPERATURE_INDOORS:
277             case TEMPERATURE_OUTDOORS:
278                 return CATEGORY_TEMPERATURE;
279             case WIND_DIRECTION:
280             case WIND_SPEED:
281                 return CATEGORY_WIND;
282             case SOUND_PRESSURE_LEVEL:
283                 return CATEGORY_SOUND_VOLUME;
284             case BRIGHTNESS_INDOORS:
285             case BRIGHTNESS_OUTDOORS:
286                 return CATEGORY_BRIGHTNESS;
287             default:
288                 break;
289
290         }
291         return null;
292     }
293
294     private String getBinaryInputCategory(DeviceBinarayInputEnum binaryInputType) {
295         switch (binaryInputType) {
296             case BATTERY_STATUS_IS_LOW:
297                 return CATEGORY_BATTERY;
298             case SUN_RADIATION:
299             case SUN_PROTECTION:
300             case TWILIGHT:
301             case BRIGHTNESS:
302                 return CATEGORY_BRIGHTNESS;
303             case HEATING_OPERATION_ON_OFF:
304             case CHANGE_OVER_HEATING_COOLING:
305             case TEMPERATION_BELOW_LIMIT:
306                 return CATEGORY_TEMPERATURE;
307             case DOOR_IS_OPEN:
308                 return CATEGORY_DOOR;
309             case GARAGE_DOOR_IS_OPEN:
310                 return CATEGORY_GARAGE_DOOR;
311             case PRESENCE:
312             case PRESENCE_IN_DARKNESS:
313             case MOTION:
314             case MOTION_IN_DARKNESS:
315                 return CATEGORY_MOTION;
316             case RAIN:
317                 return CATEGORY_RAIN;
318             case SMOKE:
319                 return CATEGORY_SMOKE;
320             case WINDOW_IS_OPEN:
321             case WINDOW_IS_TILTED:
322                 return CATEGORY_WINDOW;
323             case WIND_STRENGHT_ABOVE_LIMIT:
324                 return CATEGORY_WIND;
325             case FROST:
326                 return CATEGORY_ALARM;
327             default:
328                 break;
329
330         }
331         return null;
332     }
333
334     private StateDescriptionFragment getSensorStateDescription(SensorEnum sensorType) {
335         // the digitalSTROM resolution for temperature in kelvin is not correct but
336         // sensor-events and cached values are
337         // shown in °C so we will use this unit for temperature sensors
338         String unitShortCut = sensorType.getUnitShortcut();
339         if (unitShortCut.equals("%")) {
340             unitShortCut = "%%";
341         }
342         if (sensorType.toString().contains("TEMPERATURE")) {
343             unitShortCut = "°C";
344         }
345         return StateDescriptionFragmentBuilder.create().withPattern(sensorType.getPattern() + " " + unitShortCut)
346                 .withReadOnly(true).build();
347     }
348
349     private String getStageChannelOption(String type, String option) {
350         return buildIdentifier(type, STAGE, OPTION, option);
351     }
352
353     private StateDescriptionFragment getStageDescription(String channelID, Locale locale) {
354         if (channelID.contains(STAGE.toLowerCase())) {
355             List<StateOption> stateOptions = new ArrayList<>();
356             if (channelID.contains(LIGHT)) {
357                 stateOptions.add(new StateOption(DigitalSTROMBindingConstants.OPTION_COMBINED_BOTH_OFF, getText(
358                         getStageChannelOption(LIGHT, DigitalSTROMBindingConstants.OPTION_COMBINED_BOTH_OFF), locale)));
359                 stateOptions.add(new StateOption(DigitalSTROMBindingConstants.OPTION_COMBINED_BOTH_ON, getText(
360                         getStageChannelOption(LIGHT, DigitalSTROMBindingConstants.OPTION_COMBINED_BOTH_ON), locale)));
361                 stateOptions.add(new StateOption(DigitalSTROMBindingConstants.OPTION_COMBINED_FIRST_ON, getText(
362                         getStageChannelOption(LIGHT, DigitalSTROMBindingConstants.OPTION_COMBINED_FIRST_ON), locale)));
363                 if (channelID.contains("3")) {
364                     stateOptions.add(new StateOption(DigitalSTROMBindingConstants.OPTION_COMBINED_SECOND_ON, getText(
365                             getStageChannelOption(LIGHT, DigitalSTROMBindingConstants.OPTION_COMBINED_SECOND_ON),
366                             locale)));
367                 }
368             } else {
369                 stateOptions.add(new StateOption(DigitalSTROMBindingConstants.OPTION_COMBINED_BOTH_OFF,
370                         getText(getStageChannelOption(GENERAL, DigitalSTROMBindingConstants.OPTION_COMBINED_BOTH_OFF),
371                                 locale)));
372                 stateOptions.add(new StateOption(DigitalSTROMBindingConstants.OPTION_COMBINED_BOTH_ON, getText(
373                         getStageChannelOption(GENERAL, DigitalSTROMBindingConstants.OPTION_COMBINED_BOTH_ON), locale)));
374                 stateOptions.add(new StateOption(DigitalSTROMBindingConstants.OPTION_COMBINED_FIRST_ON,
375                         getText(getStageChannelOption(GENERAL, DigitalSTROMBindingConstants.OPTION_COMBINED_FIRST_ON),
376                                 locale)));
377                 if (channelID.contains("3")) {
378                     stateOptions.add(new StateOption(DigitalSTROMBindingConstants.OPTION_COMBINED_SECOND_ON, getText(
379                             getStageChannelOption(GENERAL, DigitalSTROMBindingConstants.OPTION_COMBINED_SECOND_ON),
380                             locale)));
381                 }
382             }
383             return StateDescriptionFragmentBuilder.create().withReadOnly(false).withOptions(stateOptions).build();
384         }
385         if (channelID.contains(TEMPERATURE_CONTROLLED)) {
386             return StateDescriptionFragmentBuilder.create().withMinimum(new BigDecimal(0))
387                     .withMaximum(new BigDecimal(50)).withStep(new BigDecimal(0.1)).withPattern("%.1f °C")
388                     .withReadOnly(false).build();
389         }
390         return null;
391     }
392
393     private String getCategory(String channelID) {
394         if (channelID.contains(LIGHT)) {
395             if (channelID.contains(DIMMER.toLowerCase())) {
396                 return CATEGORY_DIMMABLE_LIGHT;
397             }
398             return CATEGORY_LIGHT;
399         }
400         if (channelID.contains(SHADE)) {
401             if (channelID.contains(ANGLE.toLowerCase())) {
402                 return CATEGORY_BLINDES;
403             }
404             return ROLLERSHUTTER;
405         }
406         if (channelID.contains(TEMPERATURE_CONTROLLED)) {
407             return CATEGORY_TEMPERATURE;
408         }
409         return null;
410     }
411
412     private Set<String> getTags(String channelID, Locale locale) {
413         if (channelID.contains(LIGHT)) {
414             return new HashSet<>(Arrays.asList(getText(GE, locale), getText(DS, locale), getText(LIGHT, locale)));
415         }
416         if (channelID.contains(GENERAL)) {
417             return new HashSet<>(Arrays.asList(getText(SW, locale), getText(DS, locale), getText(JOKER, locale)));
418         }
419         if (channelID.contains(SHADE)) {
420             return new HashSet<>(Arrays.asList(getText(GR, locale), getText(DS, locale), getText("SHADE", locale)));
421         }
422         if (channelID.contains(SCENE)) {
423             return new HashSet<>(Arrays.asList(getText(SCENE, locale), getText(DS, locale)));
424         }
425         if (channelID.contains(HEATING)) {
426             return new HashSet<>(Arrays.asList(getText(BL, locale), getText(DS, locale), getText(HEATING, locale)));
427         }
428         return null;
429     }
430
431     private Set<String> getSimpleTags(String channelID, Locale locale) {
432         return new HashSet<>(Arrays.asList(getText(channelID, locale), getText(channelID, locale)));
433     }
434
435     /**
436      * Returns the supported item type for the given channel type id or null, if the
437      * channel type does not exist.
438      *
439      * @param channelTypeID of the channel
440      * @return item type or null
441      */
442     public static String getItemType(String channelTypeID) {
443         if (channelTypeID != null) {
444             if (stringContains(channelTypeID, STAGE)) {
445                 return STRING;
446             }
447             if (stringContains(channelTypeID, SWITCH) || stringContains(channelTypeID, SCENE)
448                     || stringContains(channelTypeID, WIPE) || stringContains(channelTypeID, BINARY_INPUT_PRE)) {
449                 return SWITCH;
450             }
451             if (stringContains(channelTypeID, DIMMER) || stringContains(channelTypeID, ANGLE)) {
452                 return DIMMER;
453             }
454             if (stringContains(channelTypeID, TEMPERATURE_CONTROLLED)) {
455                 return NUMBER;
456             }
457             if (channelTypeID.contains(SHADE)) {
458                 return ROLLERSHUTTER;
459             }
460         }
461         return null;
462     }
463
464     private static boolean stringContains(String string, String compare) {
465         return string.toLowerCase().contains(compare.toLowerCase());
466     }
467
468     @Override
469     public Collection<ChannelType> getChannelTypes(Locale locale) {
470         List<ChannelType> channelTypeList = new LinkedList<>();
471         for (String channelTypeId : SUPPORTED_OUTPUT_CHANNEL_TYPES) {
472             channelTypeList.add(
473                     getChannelType(new ChannelTypeUID(DigitalSTROMBindingConstants.BINDING_ID, channelTypeId), locale));
474         }
475         for (SensorEnum sensorType : SensorEnum.values()) {
476             channelTypeList.add(getChannelType(
477                     new ChannelTypeUID(DigitalSTROMBindingConstants.BINDING_ID, buildIdentifier(sensorType)), locale));
478         }
479         for (MeteringTypeEnum meteringType : MeteringTypeEnum.values()) {
480             channelTypeList.add(getChannelType(new ChannelTypeUID(DigitalSTROMBindingConstants.BINDING_ID,
481                     buildIdentifier(meteringType, MeteringUnitsEnum.WH)), locale));
482             channelTypeList.add(getChannelType(new ChannelTypeUID(DigitalSTROMBindingConstants.BINDING_ID,
483                     buildIdentifier(TOTAL_PRE, meteringType, MeteringUnitsEnum.WH)), locale));
484         }
485         for (DeviceBinarayInputEnum binaryInput : DeviceBinarayInputEnum.values()) {
486             channelTypeList.add(getChannelType(new ChannelTypeUID(DigitalSTROMBindingConstants.BINDING_ID,
487                     buildIdentifier(BINARY_INPUT_PRE, binaryInput)), locale));
488         }
489         return channelTypeList;
490     }
491
492     @Override
493     public ChannelType getChannelType(ChannelTypeUID channelTypeUID, Locale locale) {
494         if (channelTypeUID.getBindingId().equals(DigitalSTROMBindingConstants.BINDING_ID)) {
495             String channelID = channelTypeUID.getId();
496             try {
497                 SensorEnum sensorType = SensorEnum.valueOf(channelTypeUID.getId().toUpperCase());
498                 return ChannelTypeBuilder.state(channelTypeUID, getLabelText(channelID, locale), NUMBER)
499                         .withDescription(getDescText(channelID, locale)).withCategory(getSensorCategory(sensorType))
500                         .withTags(getSimpleTags(channelID, locale))
501                         .withStateDescriptionFragment(getSensorStateDescription(sensorType)).build();
502             } catch (IllegalArgumentException e) {
503                 if (SUPPORTED_OUTPUT_CHANNEL_TYPES.contains(channelID)) {
504                     return ChannelTypeBuilder
505                             .state(channelTypeUID, getLabelText(channelID, locale), getItemType(channelID))
506                             .withDescription(getDescText(channelID, locale)).withCategory(getCategory(channelID))
507                             .withTags(getTags(channelID, locale))
508                             .withStateDescriptionFragment(getStageDescription(channelID, locale)).build();
509                 }
510                 MeteringTypeEnum meteringType = getMeteringType(channelID);
511                 if (meteringType != null) {
512                     String pattern = "%.3f kWh";
513
514                     if (MeteringTypeEnum.CONSUMPTION.equals(meteringType)) {
515                         pattern = "%d W";
516                     }
517
518                     return ChannelTypeBuilder.state(channelTypeUID, getLabelText(channelID, locale), NUMBER)
519                             .withDescription(getDescText(channelID, locale)).withCategory(CATEGORY_ENERGY)
520                             .withTags(
521                                     new HashSet<>(Arrays.asList(getLabelText(channelID, locale), getText(DS, locale))))
522                             .withStateDescriptionFragment(StateDescriptionFragmentBuilder.create().withPattern(pattern)
523                                     .withReadOnly(true).build())
524                             .build();
525                 }
526                 try {
527                     DeviceBinarayInputEnum binarayInputType = DeviceBinarayInputEnum
528                             .valueOf(channelTypeUID.getId().replaceAll(BINARY_INPUT_PRE + SEPERATOR, "").toUpperCase());
529                     return ChannelTypeBuilder
530                             .state(channelTypeUID, getLabelText(channelID, locale), getItemType(channelID))
531                             .withDescription(getDescText(channelID, locale))
532                             .withCategory(getBinaryInputCategory(binarayInputType))
533                             .withTags(getSimpleTags(channelTypeUID.getId(), locale)).withStateDescriptionFragment(
534                                     StateDescriptionFragmentBuilder.create().withReadOnly(true).build())
535                             .build();
536                 } catch (IllegalArgumentException e1) {
537                     // ignore
538                 }
539             }
540         }
541         return null;
542     }
543
544     /**
545      * Returns the {@link ChannelGroupTypeUID} for the given {@link SensorEnum}.
546      *
547      * @param sensorType (must not be null)
548      * @return the channel type uid
549      */
550     public static ChannelTypeUID getSensorChannelUID(SensorEnum sensorType) {
551         return new ChannelTypeUID(BINDING_ID, buildIdentifier(sensorType));
552     }
553
554     /**
555      * Returns the {@link ChannelGroupTypeUID} for the given
556      * {@link DeviceBinarayInputEnum}.
557      *
558      * @param binaryInputType (must not be null)
559      * @return the channel type uid
560      */
561     public static ChannelTypeUID getBinaryInputChannelUID(DeviceBinarayInputEnum binaryInputType) {
562         return new ChannelTypeUID(BINDING_ID, buildIdentifier(BINARY_INPUT_PRE, binaryInputType));
563     }
564 }