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