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