diff --git a/developers/bindings/semantic-tags.md b/developers/bindings/semantic-tags.md new file mode 100644 index 000000000..63e92aef9 --- /dev/null +++ b/developers/bindings/semantic-tags.md @@ -0,0 +1,117 @@ +--- +layout: developersguide +title: Developer Guidelines on Semantic Tags +--- + +# Developer Guidelines on Semantic Tags + +## Introduction + +A semantic tag is an attribute of an openHAB [object](#objects-that-use-semantic-tags) that provides information to the openHAB User Interface about the type (i.e. the nature) of either things or items. +Note the use of the word `type`. + +Semantic tags are divided into the following categories: + +- EQUIPMENT (relates to the `type` of a piece of equipment) +- POINT (relates to the `type` of a particular data point within some equipment) +- PROPERTY (relates to the `type` of the information carried by a point) +- LOCATION (relates to the `type` of the location of an equipment or point). + +## Purpose of Semantic Tags + +The various equipment, points, properties, and locations are displayed in the openHAB User Interface in a hierarchical tree structure, which is based on a hierarchy of semantic tags defined in openHAB Core. +The primary purpose of semantic tags is to help the User Interface generate such a hierarchical tree structure of the user’s home system with its respective nested rooms, devices (things) and items. +Semantic tags are also used by HABot and end users in rules. + +The purpose of this document is to provide rules for openHAB developers and openHAB maintainers in applying existing semantic tags as follows: + +- By addon developers/reviewers at design time in the addon's `thing-type.xml` and `channel-type.xml` definitions. +- By addon developers/reviewers at run-time dynamically in the addon's Java code. +- By addon developers/reviewers in deciding whether to propose/approve a new semantic tag. + +Note: the document may also provide information to help users when setting up their system. + +## Objects that use Semantic Tags + +Semantic tags can be applied to the following openHAB objects with a chain of inheritance as follows: + +- `Channel-Type` : POINT/PROPERTY tags applied at design time via the `channel-type.xml`. +- `Channel` : POINT/PROPERTY tags inherited from the `Channel-Type` above, and/or applied at run time by the binding Java code. +- `Item` : POINT/PROPERTY tags inherited from the `Channel` above, and/or all types of tags applied users when setting up their system. +- `Thing-Type` : EQUIPMENT tag (single) applied at design time in the `thing-type.xml`. +- `Thing`: EQUIPMENT tag inherited from the `Thing-Type` above, and/or applied at run time by the binding Java code. +- `Semantic Model`: EQUIPMENT tree structure ("create equipment from thing") inherited from the `Thing` above, and/or by users. + +## General Rules for Semantic Tags + +The list of semantic tags defined in openHAB Core is extensible. +This document describes the developer rules for applying or extending this list. + +The core predefined semantic tags are presented to users as propositions, suggestions, or hints. +It is possible for users to add their own customised tags at their own discretion. +The remainder of this document does NOT relate to user customised tags. +It applies solely to the openHAB Core tags. + +This following uses terms "MUST", "MAY", "SHALL", "SHALL NOT", etc. that are defined in Internet Standard [RFC-2119](https://datatracker.ietf.org/doc/html/rfc2119) + +### A. Rules for **APPLYING** Core Predefined Semantic Tags + +1. Developers MUST apply core predefined tags in their addons where possible. +1. Developers MAY hard code the tags in the `thing-type.xml` or apply them dynamically at run time via the Java code. +1. Developers SHALL NOT apply LOCATION tags either in the `thing-type.xml`, or via the Java code. +1. Developers SHALL NOT apply customised tags in their addons. +1. Developers MAY apply a POINT tag without a PROPERTY tag (in cases where a property makes no sense). However, in such a case the developer MAY submit a new PROPERTY tag that fits. +1. Developers SHALL NOT apply a PROPERTY tag without a POINT tag. +1. Semantic EQUIPMENT tags MUST be applied at the thing level. +1. Semantic POINT and PROPERTY tags MUST be applied at channel level. +1. Developers MAY open a new PR to propose extensions to the core predefined tags as follows. + +### B. Rules for **EXTENDING** Core Predefined Semantic Tags + +The purpose of the semantic model is to provide a stable base set of tags for binding authors to use. +Submiting and adopting new tags should be a rare occurance. + +1. New tags MUST fit within the hierarchy of semantic tags already defined in openHAB Core. +1. New tags SHALL NOT be synonyms of existing tags e.g. kitchen/kitchenette, sitting/living room. +1. New PROPERTY, POINT and EQUIPMENT tags SHOULD aim to be applicable across more than one binding. +1. Developers MUST provide supporting arguments in their PR that the rules above and below are met. + +## C. Rules for extending EQUIPMENT Tags + +An EQUIPMENT tag describes the equipment type of a piece of equipment. +Examples are thermostat, pump, car, wall switch, push button, alarm system, or alarm detector. + +1. New EQUIPMENT tags MUST describe the equipment type of a physical or virtual device. +1. New EQUIPMENT tags MUST be a noun. + +## D. Rules for extending POINT Tags + +A POINT is a tag that describes the functional type (or purpose) of a data point within an equipment. +Examples are measurement, control, set point, or status. + +1. New POINT tags MUST describe the functional type (or purpose) of the data point. +1. New POINT tags MUST be what you (the binding) does to, or how you (the binding) gets, the state of the Item. +1. New POINT tags SHOULD be defined in conjunction with an information type in a PROPERTY tag. See examples [below](#examples-of-point-and-property-tags). + +## E. Rules for extending PROPERTY Tags + +A PROPERTY is a tag that describes the information type (or content type) of the data produced or consumed by a point. +Examples are temperature, brightness, on-off, time stamp. + +1. New PROPERTY tags MUST describe the information type (or content type) of the point. +1. New PROPERTY tags MUST be a noun and represent some attribute commonly controlled or sensed in a home automation context. +1. New PROPERTY tags MUST be defined in conjunction with the functional type of a POINT tag. See examples below. + +### Examples of Point and Property Tags: + +- A humidity sensor would have POINT=`Measurement` plus PROPERTY=`Humidity`. +- A thermostat's target temperature would have POINT=`Setpoint` plus PROPERTY=`Temperature`. +- A smoke alarm would have POINT=`Alarm` plus PROPERTY=`Smoke`. + +## F. Rules for extending LOCATION Tags + +A LOCATION is a tag that describes the location type of a point. +Its most common use case is to assign equipment to a location. +Examples are ground floor, dining (eating) room, kitchen (cooking room), living room, or garage. + +1. New LOCATION tags SHALL NOT be synonyms of existing tags (see [rule B.2.](#b-rules-for-extending-core-predefined-semantic-tags)) diff --git a/developers/bindings/thing-xml.md b/developers/bindings/thing-xml.md index 775b34bd7..e6cb0d37b 100644 --- a/developers/bindings/thing-xml.md +++ b/developers/bindings/thing-xml.md @@ -1,940 +1,951 @@ ---- -layout: developersguide -title: Thing Descriptions ---- - -# Binding Definitions - -In order to work with _Things_ and _Channels_, some meta information about them is needed. - -These are provided through 'ThingType' and 'ChannelType' definitions, -which describe details about their functionality and configuration options. - -[[toc]] - -## ThingTypeProvider / ChannelTypeProvider - -Technically, the thing types are provided by `ThingTypeProvider`s (`org.openhab.core.thing.binding.ThingTypeProvider`). - -openHAB comes with an implementation of such a provider that reads XML files from the folder `OH-INF/thing` of bundles. -Although we refer to this XML syntax in the following, you also have the option to provide directly object model instances through your own provider implementation. - -The same applies for the channel types. -The `ChannelTypeProvider` interface can be registered as OSGi service to provide channel types programmatically. -When implementing a dynamic `ThingTypeProvider` you can also refer to the channel types that are defined inside XML files. - -## Things - -Things represent devices or services that can be individually added to, configured or removed from the system. -They either contain a set of channels or a set of channel groups. -A bridge is a specific type of thing as it can additionally provide access to other Things as well. -Which Things can be associated through which bridge type is defined within the description of a thing: - -```xml - - - - - - Some sample description - Lightbulb - ... - -``` - -Bindings may optionally set the listing of a thing type. -By doing do, they indicate to user interfaces whether it should be shown to the users or not, e.g. when pairing things manually: - -```xml - - ... - -``` - -Thing types are listed by default, unless specified otherwise. -Hiding thing types potentially makes sense if they are deprecated and should not be used anymore. -Also, this can be useful if users should not be bothered with distinguishing similar devices which for technical reasons have to have separate thing types. -In that way, a generic thing type could be listed for users and a corresponding thing handler would change the thing type immediately to a more concrete one, handing over control to the correct specialized handler. - -### Thing Categories - -Categories are used to provide meta information about Things. Thing categories describe how the physical device **looks like**. UIs can use this information e.g. to render icons. -The available categories correspond with the [available icons of the classic iconset]({{base}}/configuration/iconsets/classic/), however categories are written in Java class-naming style, e.g. `FrontDoor` instead of lowercase `frontdoor`. - -## Channels - -A channel describes a specific functionality of a thing and can be linked to an item. -So the basic information is, which command types the channel can handle and which state it sends to the linked item. -This can be specified by the accepted item type. -Inside the thing type description XML file a list of channels can be referenced. -The channel type definition is specified on the same level as the thing type definition. -That way channels can be reused in different things. - -The granularity of channel types should be on its semantic level, i.e. very fine-grained: -If a Thing measures two temperature values, one for indoor and one for outdoor, this should be modelled as two different channel types. -Overriding labels of a channel type must only be done if the very same functionality is offered multiple times, e.g. having an actuator with 5 relays, which each is a simple "switch", but you want to individually name the channels (1-5). - -### State Channel Types - -The following XML snippet shows a thing type definition with three channels and two referenced channel types: - -```xml - - - Some sample description - - - - - - - - Number - - Temperature - - - - Number:Dimensionless - - - -``` - -The `item-type` element defines the [item type](../../configuration/items.md#type) to be used when a linked item is created. -If the `item-type` is a `Number:`, then a `unitHint` attribute may be provided to suggest the measurement unit to be used when a linked item is created. - -In order to reuse identical channels in different bindings a channel type can be system-wide. -A channel type can be declared as system-wide by setting its `system` property to true and can then be referenced using a `system.` prefix in a `channel` `typeId` attribute in any binding - note that this should only be done in the core framework, but not by individual bindings! - -The following XML snippet shows a system channel type definition and thing type definition that references it: - -```xml - - - Some sample description - - - - - - Number - - QualityOfService - -``` - -### System State Channel Types - -There exist system-wide channel types that are available by default and which should be used whenever possible: - -| Channel Type ID | Reference typeId | Item Type | Category | Tags | Description | -|-----------------------|------------------------------|--------------------------|------------------|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| signal-strength | system.signal-strength | Number | QualityOfService | Measurement, Level | Represents signal strength of a device as a Number with values 0, 1, 2, 3 or 4; 0 being worst strength and 4 being best strength. | -| low-battery | system.low-battery | Switch | LowBattery | LowBattery, Energy | Represents a low battery warning with possible values on (low battery) and off (battery ok). | -| battery-level | system.battery-level | Number | Battery | Measurement, Energy | Represents the battery level as a percentage (0-100%). Bindings for things supporting battery level in a different format (e.g. 4 levels) should convert to a percentage to provide a consistent battery level reading. | -| power | system.power | Switch | Switch | Switch, Power | Turn a device on/off. | -| brightness | system.brightness | Dimmer | Light | Control, Light | Brightness of a bulb (0-100%). | -| color | system.color | Color | ColorLight | Control, Light | Color of a bulb. | -| color-temperature | system.color-temperature | Dimmer | ColorLight | Control, ColorTemperature | Color temperature of a bulb (0-100%). 0% should be the coldest setting (highest Kelvin value), 100 the warmest. | -| color-temperature-abs | system.color-temperature-abs | Number | ColorLight | Control, ColorTemperature | Color temperature of a bulb in Kelvin (1000K-10000K). | -| location | system.location | Location | - | Measurement | Location in lat.,lon.,height coordinates. | -| motion | system.motion | Switch | Motion | Status, Presence | Motion detected by the device (ON if motion is detected). | -| mute | system.mute | Switch | SoundVolume | Switch, SoundVolume | Turn on/off the volume of a device. | -| volume | system.volume | Dimmer | SoundVolume | Control, SoundVolume | Change the sound volume of a device (0-100%). | -| media-control | system.media-control | Player | MediaControl | Control | Control for a media player. | -| media-title | system.media-title | String | - | Status | Title of a (played) media file. | -| media-artist | system.media-artist | String | - | Status | Artist of a (played) media file. | -| outdoor-temperature | system.outdoor-temperature | Number:Temperature | Temperature | Measurement, Temperature | Current outdoor temperature. | -| indoor-temperature | system.indoor-temperature | Number:Temperature | Temperature | Measurement, Temperature | Current indoor temperature. | -| wind-direction | system.wind-direction | Number:Angle | Wind | Measurement, Wind | Wind direction in degrees (0-360°). | -| wind-speed | system.wind-speed | Number:Speed | Wind | Measurement, Wind | Wind speed | -| atmospheric-humidity | system.atmospheric-humidity | Number:Dimensionless | Humidity | Measurement, Humidity | Atmospheric humidity in percent. | -| barometric-pressure | system.barometric-pressure | Number:Pressure | Pressure | Measurement, Pressure | Barometric pressure | -| electric-current | system.electric-current | Number:ElectricCurrent | Energy | Measurement, Current | Electric current | -| electric-power | system.electric-power | Number:Power | Energy | Measurement, Power | Electric power | -| electric-voltage | system.electric-voltage | Number:ElectricPotential | Energy | Measurement, Voltage | Electric voltage | -| electrical-energy | system.electric-energy | Number:Energy | Energy | Measurement, Energy | Electrical energy | - -The `advanced` property indicates whether this channel is a basic or a more specific functionality of the thing. -If `advanced` is set to `true` a user interface may hide this channel by default. -The default value is `false` and thus will be taken if the `advanced` attribute is not specified. -Especially for complex devices with a lot of channels, only a small set of channels - the most important ones - should be shown to the user to reduce complexity. -Whether a channel should be declared as `advanced` depends on the device and can be decided by the binding developer. -If a functionality is rarely used it should be better marked as `advanced`. - -### Trigger Channel Types - -The following XML snippet shows a trigger channel: - -```xml - - - Some sample description - - - - - - trigger - - - - - - - - - -``` - -This channel can emit the event payloads `PRESSED`, `RELEASED` and `DOUBLE_PRESSED`. - -If no `` tag is specified, the channel can be triggered, but has no event payload. -If an empty `` tag is specified, the channel can trigger any event payload. - -### System Trigger Channel Types - -There exist system-wide trigger channel types that are available by default: - -| Channel Type ID | Reference typeId | Description | -|-----------------|------------------|---------------------------------------------------------------------------------| -| trigger | system.trigger | Can only trigger, no event payload | -| rawbutton | system.rawbutton | Can trigger `PRESSED` and `RELEASED` | -| button | system.button | Can trigger `SHORT_PRESSED`, `DOUBLE_PRESSED` and `LONG_PRESSED` | -| rawrocker | system.rawrocker | Can trigger `DIR1_PRESSED`, `DIR1_RELEASED`, `DIR2_PRESSED` and `DIR2_RELEASED` | - -In the following sections the declaration and semantics of tags, state descriptions and channel categories will be explained in more detail. -For a complete sample of the thing types XML file and a full list of possible configuration options please see the [XML Configuration Guide](../addons/config-xml.html). - -### Default Tags - -The XML definition of a ChannelType allows to assign default tags to channels. -All items bound to this channel will automatically be tagged with these default tags. -The following snippet shows a 'Control' and 'Light' tags definition: - -```xml - - Control - Light - -``` - -Please note that only [Point](https://openhab.org/javadoc/latest/org/openhab/core/semantics/model/point/package-summary.html) and/or [Property](https://openhab.org/javadoc/latest/org/openhab/core/semantics/model/property/package-summary.html) tags from the pre-defined tag library should be used. -See also the [Semantic Model]({{base}}/tutorial/model.html) for more information on how tags are used with items. - -### State Description - -The state description allows to specify restrictions and additional information for the state of an item, that is linked to the channel. -Some configuration options are only valid for specific item types. -The following XML snippet shows the definition for a temperature actuator channel: - -```xml - -``` - -- The attributes `min` and `max` can only be declared for channel with the item type `Number`. - It defines the range of the numeric value. - The Java data type is a BigDecimal. - For example user interfaces can create sliders with an appropriate scale based on this information. -- The `step` attribute can be declared for `Number` and `Dimmer` items and defines what is the minimal step size that can be used. -- The `readonly` attribute can be used for all item types and defines if the state of an item can be changed. - For all sensors the `readonly` attribute should be set to `true`. -- The `pattern` attribute can be used for `Number` and `String` items. - It gives user interface a hint how to render the item. - The format of the pattern must be compliant to the [Java Number Format](https://docs.oracle.com/javase/tutorial/java/data/numberformat.html). - The pattern can be localized (see also [Internationalization](../utils/i18n.html)). - The special pattern placeholder `%unit%` is used for channels which bind to items of type `Number:` which define a dimension for unit support. - These channels will send state updates of type [QuantityType](../../concepts/units-of-measurement.html#quantitytype) and the unit is then rendered for the placeholder. - -Some channels might have only a limited and countable set of states. -These states can be specified as options. -A `String` or `Number` item must be used as item type. -In general `String` should be preferred with a meaningful option value. -This prevents the user from having to guess what a value represents if a number is used as option value. -`Number` is useful when the value represents a quantity (e.g. like in the system-wide channel type `signal-strength`). - -The following XML snippet defines a list of predefined state options: - -```xml - - - - - - - -``` - -The user interface can use these values to render labels for values or to provide a selection of states, when the channel is writable. -The option labels can also be localized. - -### Command Description - -If the primary purpose of a channel is to send commands towards a device (i.e. the opposite direction of trigger channels), -it can use command options. - -A `String` item must be used as item type. - -The following XML snippet defines a list of commands: - -```xml - - - - - - -``` - -The user interface can use these values to render - -- a drop down and also represent the current state or -- as push buttons to simply send a command to the ThingHandler. - -The option labels can also be localized. - -#### Dynamic State / Command Description - -In situations where the static definition of a state description is not sufficient a binding would implement a `DynamicStateDescriptionProvider` or a `DynamicCommandDescriptionProvider`. - -These providers allow to provide a `StateDescription` (or `CommandDescription` respectively) based on the specific `Channel`. - -Also implement this interface if you want to provide dynamic state / command options. -The original `StateDescription`/`CommandDescription` is available for modification and enhancement. -The framework provides two abstract implementations for bindings to support translation, publishing `ChannelDescriptionChangedEvent`s and other basic features: `BaseDynamicStateDescriptionProvider` and `BaseDynamicCommandDescriptionProvider`. - -The `StateDescriptionFragmentBuilder` (and `CommandDescriptionBuilder`) can be used to only provide the information which is available at the time of construction. - -##### Example code for a `DynamicStateDescriptionProvider` implementation - -```java -@Component(service = { DynamicStateDescriptionProvider.class, ExampleDynamicStateDescriptionProvider.class }) -public class ExampleDynamicStateDescriptionProvider implements DynamicStateDescriptionProvider { - - private final Map> channelOptionsMap = new ConcurrentHashMap<>(); - - /** - * For a given channel UID, set a {@link List} of {@link StateOption}s that should be used for the channel, instead - * of the one defined statically in the {@link ChannelType}. - * - * @param channelUID the channel UID of the channel - * @param options a {@link List} of {@link StateOption}s - */ - public void setStateOptions(ChannelUID channelUID, List options) { - channelOptionsMap.put(channelUID, options); - } - - @Override - public @Nullable StateDescription getStateDescription(Channel channel, @Nullable StateDescription original, - @Nullable Locale locale) { - List options = channelOptionsMap.get(channel.getUID()); - if (options == null) { - return null; - } - - StateDescriptionFragmentBuilder builder = (original == null) ? StateDescriptionFragmentBuilder.create() - : StateDescriptionFragmentBuilder.create(original); - return builder.withOptions(options).build().toStateDescription(); - } - - @Deactivate - public void deactivate() { - channelOptionsMap.clear(); - } -} -``` - -##### Example code for a `DynamicStateDescriptionProvider` implementation which extends the `BaseDynamicStateDescriptionProvider` - -```java -@Component(service = { DynamicStateDescriptionProvider.class, ExampleDynamicStateDescriptionProvider.class }) -public class ExampleDynamicStateDescriptionProvider extends BaseDynamicStateDescriptionProvider { - - @Activate - public ExampleDynamicStateDescriptionProvider(final @Reference EventPublisher eventPublisher, // - final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry, // - final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { - this.eventPublisher = eventPublisher; - this.itemChannelLinkRegistry = itemChannelLinkRegistry; - this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService; - } -} -``` - -##### Example code for a `DynamicCommandDescriptionProvider` implementation - -```java -@Component(service = { DynamicCommandDescriptionProvider.class, ExampleDynamicCommandDescriptionProvider.class }) -public class ExampleDynamicCommandDescriptionProvider implements DynamicCommandDescriptionProvider { - - private final Map> channelOptionsMap = new ConcurrentHashMap<>(); - - /** - * For a given channel UID, set a {@link List} of {@link CommandOption}s that should be used for the channel, - * instead of the one defined statically in the {@link ChannelType}. - * - * @param channelUID the channel UID of the channel - * @param options a {@link List} of {@link CommandOption}s - */ - public void setCommandOptions(ChannelUID channelUID, List options) { - channelOptionsMap.put(channelUID, options); - } - - @Override - public @Nullable CommandDescription getCommandDescription(Channel channel, - @Nullable CommandDescription originalCommandDescription, @Nullable Locale locale) { - List options = channelOptionsMap.get(channel.getUID()); - if (options == null) { - return null; - } - - return CommandDescriptionBuilder.create().withCommandOptions(options).build(); - } -} -``` - -Most of the times handlers need to modify those dynamic information. -Therefore the `ThingHandlerFactory` has to reference the bundle instance and pass it to the handler. - -```java -public class ExampleHandlerFactory extends BaseThingHandlerFactory { - - private final ExampleDynamicStateDescriptionProvider stateDescriptionProvider; - - @Activate - public ExampleHandlerFactory(final @Reference ExampleDynamicStateDescriptionProvider stateDescriptionProvider) { - this.stateDescriptionProvider = stateDescriptionProvider; - } - - @Override - protected ThingHandler createHandler(Thing thing) { - if (EXAMPLE_THING_TYPE.equals(thing.getThingTypeUID())) { - return new ExampleHandler(thing, stateDescriptionProvider); - } - return null; - } -} -``` - -### Channel Categories - -Channel categories are used to provide meta information about channels. Channel categories describe the **functional purpose** of the channel and are used by the UI to render icons. -The available categories correspond with the [available icons of the classic iconset]({{base}}/configuration/iconsets/classic/), however categories are written in Java class-naming style, e.g. `BatteryLevel` instead of lowercase `batterylevel`. - -### Channel Groups - -Some devices might have a lot of channels. -There are also complex devices like a multi-channel actuator, which is installed inside the switchboard, but controls switches in other rooms. -Therefore channel groups can be used to group a set of channels together into one logical block. -A thing can only have direct channels or channel groups, but not both. - -Inside the thing types XML file channel groups can be defined like this: - -```xml - - - - - - - - -``` - -The channel group type is defined on the same level as the thing types and channel types. -The group type must have a label, an optional description, and an optional category (e.g. used to render an icon).. -Moreover the list of contained channels must be specified: - -```xml - - - This is a single switch actor with a switch channel - Light - - - - -``` - -When a thing will be created for a thing type with channel groups, the channel UID will contain the group ID in the last segment divided by a hash (#). -If an Item should be linked to a channel within a group, the channel UID would be `binding:multiChannelSwitchActor:myDevice:switchActor1#switch` for the XML example before. - -## Properties - -Solutions based on openHAB might require meta data from a device. -These meta data could include: - -- general device information, e.g. the device vendor, the device series or the model ID, ... -- device characteristics, e.g. if it is battery based, which home automation protocol is used, what is the current firmware version or the serial number, ... -- physical descriptions, e.g. what is the size, the weight or the color of the device, ... -- any other meta data that should be made available for the solution by the binding - -Depending on the solution the provided meta data can be used for different purposes. -Among others the one solution could use the data during a device pairing process whereas another solution might use the data to group the devices/things by the vendors or by the home automation protocols on a user interface. -To define such thing meta data the thing type definition provides the possibility to specify so-called `properties`: - -```xml - - ... - - MyThingVendor - thingTypeId - ZigBee - ... - - ... - -``` - -In general each `property` must have a name attribute which should be written in camel case syntax. -The actual property value is defined as plain text and is placed as child node of the property element. -It is recommended that at least the vendor and the model id properties are specified here since they should be definable for the most of the devices. -In contrast to the properties defined in the 'ThingType' definitions the thing handler [documentation](thing-handler.html) explains how properties can be set during runtime. - -### Representation Property - -A thing type can contain a so-called `representation property`. -This optional property contains the **name** of a property whose value can be used to uniquely identify a device. -The `thingUID` cannot be used for this purpose because there can be more than one thing for the same device. - -Each physical device normally has some kind of a technical identifier which is unique. -This could be a MAC address (e.g. Hue bridge, camera, all IP-based devices), a unique device id (e.g. a Hue lamp) or some other property that is unique per device type. -This property is normally part of a discovery result for that specific thing type. -Having this property identified per binding it could be used as the `representation property` for this thing. - -The `representation property` shall be defined in the thing type XML: - -```xml - - ... - - Philips - - uniqueId - ... - -``` - -Note that the `representation property` is normally not listed in the `properties` part of the Thing type XML, as this part contains static properties, that are the same for all instances of this Thing type. -The name of the `representation property` identifies a property or configuration parameter that is added to the Thing in the Thing handler upon successful initialization. - -### Representation Property and Discovery - -The representation property is used to auto-ignore discovery results of Things that already exist in the system. -This can happen if, a) a Thing has been created manually, or b) the Thing has been discovered separately by two mechanisms e.g. by mDNS, and by NetBios, or UPnP. -If this is the case, the Thing in the inbox is automatically ignored. -Note that this Thing is automatically removed when the manually added Thing is removed. -A new discovery would then automatically find this Thing again and add it to the inbox properly. - -See also [Implementing a Discovery Service](index.md#representation-property) - -When comparing representation properties, the auto-ignore service checks for matches between the representation property of the newly discovered Thing, and both the properties and the configuration parameters of existing Things. -If a configuration parameter will be used, then its respective `parameter` shall be declared in the XML `config-description` section or the `config-description` [XML file](../addons/config-xml.md): - -```xml - - ... - uniqueId - ... - - - - The Unique Id for Representation Property - - - ... - -``` - -## Formatting Labels and Descriptions - -The label and descriptions for things, channels and config descriptions should follow the following format. -The label should be short so that for most UIs it does not spread across multiple lines. -Guideline is 2-3 words with up to 25 chars. -Labels should be capitalized using the following rules: - -- Always capitalize the first and the last word. -- Lowercase articles, coordinating conjunctions, and prepositions (`a, an, the, and, as, but, by, for, from, in, into, like, near, nor, of, onto, or, out, over, past, so, till, to, up, upon, with, yet`). -- Capitalize all other words. -- Brand- or product names that starts with a lowercase character can be written using their official spelling. - -The description can contain longer text to describe the thing in more detail. -Limited use of HTML tags is permitted to enhance the description - if a long description is provided, the first line should be kept short, and a line break (```
```) placed at the end of the line to allow UIs to display a short description in limited space. - -Configuration options should be kept short so that they are displayable in a single line in most UIs. -If you want to provide a longer description of the options provided by a particular parameter, then this should be placed into the `````` of the parameter to keep the option label short. -The description can include limited HTML to enhance the display of this information. - -The following HTML tags are allowed : ```,
, ,

,

,

,

,

,
, ,

, , , , ,

    ,
      ,
    1. ```. -These must be inside the XML escape sequence - e.g. ``````. - -## Auto Update Policies - -Channel types can optionally define a policy with respect to the auto update handling. -This influences the decision within the framework if an auto-update of the item's state should be sent in case a command is received for it. -The auto update policy typically is inherited by the channel from its channel type. -Nevertheless, this value can be overridden in the channel definition. - -In this example, an auto update policy is defined for the channel type, but is overridden in the channel definition: - -```xml - - - recommend - - - - - Thing type which overrides the auto update policy of a channel - - - default - - - -``` - -The following policies are supported: - -- **veto**: No automatic state update should be sent by the framework. - The thing handler will make sure it sends a state update and it can do it better than just converting the command to a state. -- **default**: The binding does not care and the framework may do what it deems to be right. - The state update which the framework will send out normally will correspond the command state anyway. - This is the default if no other policy is set explicitly. -- **recommend**: An automatic state update should be sent by the framework because no updates are sent by the binding. - This usually is the case when devices don't expose their current state to the handler. - -## Bridges and Thing Descriptions - -Every binding has to provide meta information about which bridges and/or _Thing_s it provides and how their relations to each other are structured. -In that way a binding could describe that it requires specific bridges to be operational or define which channels (e.g. temperature, color, etc.) it provides. - -Every bridge or _Thing_ has to provide meta information such as label or description. -The meta information of all bridges and _Thing_s is accessible through the `org.openhab.core.thing.binding.ThingTypeProvider` service. - -Bridge and _Thing_ descriptions must be placed as XML file(s) (with the ending `.xml`) in the bundle's folder `/OH-INF/thing/`. -The full Java API for bridge and _Thing_ descriptions can be found in the Java package `org.openhab.core.thing.type`. - -### XML Structure for Thing Descriptions - -```xml - - - - - - - ... - - - - String - String - - - - OR - - - String - - ... - - OR - - - OR - - - String - - ... - - - - propertyValue - ... - - propertyName - - - ... - - OR - - - - - - - ... - - - - String - String - - - - OR - - - String - - ... - - OR - - - OR - - - String - - ... - - - - propertyValue - ... - - propertyName - - - ... - - OR - - - - - Dimmer - OR - trigger - - String - String - - - String - ... - - - - - - ... - - - OR - - - - ... - - - - - - - ... - - - - - ... - - OR - - - - - - String - String - - - - ... - - - - ... - - -``` - -| Property | Description | | -|------------------------------|----------------------------------------------------|-----------| -| thing-descriptions.bindingId | The identifier of the binding this types belong to | mandatory | - -**Bridges and Things:** - -| Property | Description | | -|------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------| -| bridge-type.id / thing-type.id | An identifier for the bridge/Thing type | mandatory | -| bridge-type.listed / thing-type.listed | Denotes if user interfaces should list the bridge/Thing, e.g. for pairing | optional, defaults to true | -| bridge-type.extensible / thing-type.extensible | If the bridge/Thing supports a generic number of channels the allowed channelTypeIds can be listed here. This provides a hint for UIs to support adding/removing channels. Channel groups are not supported. | optional | -| supported-bridge-type-refs | The identifiers of the bridges this bridge/Thing can connect to | optional | -| bridge-type-ref.id | The identifier of a bridge this bridge/Thing can connect to | mandatory | -| label | A human-readable label for the bridge/Thing | mandatory | -| description | A human-readable description for the bridge/Thing | optional | -| category | Category this bridge/Thing belongs to, see categories) | optional | -| channels | The channels the bridge/Thing provides | optional | -| channel.id | An identifier of the channel the bridge/Thing provides | mandatory | -| channel.typeId | An identifier of the channel type definition the bridge/Thing provides | mandatory | -| label | A human-readable label for the channel | optional | -| description | A human-readable description for the channel | optional | -| channel-groups | The channel groups defining the channels the bridge/Thing provides | optional | -| channel-group.id | An identifier of the channel group the bridge/Thing provides | mandatory | -| channel-group.typeId | An identifier of the channel group type definition the bridge/Thing provides | mandatory | -| properties | Name/value pairs for properties to be set to the thing | optional | -| representation-property | The name of the property that contains a unique identifier of the thing | optional | -| config-description | The configuration description for the bridge/Thing within the ConfigDescriptionRegistry | optional | -| config-description-ref | The reference to a configuration description for the bridge/Thing within the ConfigDescriptionRegistry | optional | -| config-description-ref.uri | The URI of the configuration description for the bridge/Thing within the ConfigDescriptionRegistry | mandatory | - -**Channels:** - -| Property | Description | | -|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------| -| channel-type.id | An identifier for the channel type | mandatory | -| channel-type.advanced | The flag indicating if this channel contains advanced functionalities which should be typically not shown in the basic view of user interfaces | optional, default: false | -| kind | The kind of channel. state for channels which have a state, trigger for trigger channels. state is the default. | | -| item-type | An item type of the channel. All item types are specified in ItemFactory instances. The following items belong to the core: Switch, Rollershutter, Contact, String, Number, Dimmer, DateTime, Color, Image, Location, Player, Call. | mandatory if kind state, which is the default | -| label | A human-readable label for the channel | mandatory | -| description | A human-readable description for the channel | optional | -| category | The category for the channel, e.g. TEMPERATURE | optional | -| tags | A list of default tags to be assigned to bound items | optional | -| tag | A tag semantically describes the feature (typical usage) of the channel e.g. AlarmSystem. There are no pre-default tags, they are custom-specific | mandatory | -| state | The restrictions of an item state which gives information how to interpret it | optional | -| state.min | The minimum decimal value of the range for the state | optional | -| state.max | The maximum decimal value of the range for the state | optional | -| state.step | The increasing/decreasing decimal step size within the defined range, specified by the minimum/maximum values | optional | -| state.pattern | The pattern following the printf syntax to render the state | optional | -| state.readOnly | The flag indicating if the state is read-only or can be modified | optional, default: false | -| options | A list restricting all possible values | optional | -| option | The description for the option | optional | -| option.value | The value for the option. Note that the value may be outside of the range specified in the min/max if this is specified. | mandatory | -| command | Commands this channel will send to the binding. This is used to model "write-only" channels and gives UIs a hint to display push-buttons without state | optional | -| options | A list defining the possible commands | optional | -| option | The description for the option | optional | -| option.value | The value for the option. This is the actual command send to the channel. | mandatory | -| event | The restrictions of a trigger event which gives information how to interpret it | optional | -| autoUpdatePolicy | The auto update policy to use | optional | -| config-description | The configuration description for the channel within the ConfigDescriptionRegistry | optional | -| config-description-ref | The reference to a configuration description for the channel within the ConfigDescriptionRegistry | optional | -| config-description-ref.uri | The URI of the configuration description for the channel within the ConfigDescriptionRegistry | mandatory | - -**Channel Groups:** - -| Property | Description | | -|-----------------------|------------------------------------------------------------------------|-----------| -| channel-group-type.id | An identifier for the channel group type | mandatory | -| label | A human-readable label for the channel group | mandatory | -| description | A human-readable description for the channel group | optional | -| category | The category for the channel group, e.g. TEMPERATURE | optional | -| channels | The channels the bridge/Thing provides | mandatory | -| channel.id | An identifier of the channel the bridge/Thing provides | mandatory | -| channel.typeId | An identifier of the channel type definition the bridge/Thing provides | mandatory | - -The full XML schema for Thing type descriptions is specified in the [https://openhab.org/schemas/thing-description-1.0.0.xsd](https://openhab.org/schemas/thing-description-1.0.0.xsd) openHAB thing description XSD file. - -**Hints:** - -- Any identifiers of the types are automatically mapped to unique identifiers: `bindingID:id`. -- The attribute `uri` in the section `config-description` is optional, it _should not_ be specified in bridge/_Thing_/channel type definition files because it's an embedded configuration. - If the `uri` is _not_ specified, the configuration description is registered as `thing-type:bindingID:id` or `channel-type:bindingID:id` otherwise the given `uri` is used.s -- If a configuration description is already specified somewhere else and the bridge/_Thing_/channel type wants to (re-)use it, a `config-description-ref` should be used instead. - -### Updating Thing Types - -Sometimes, when bindings evolve, thing-types need to be modified. -Since managed things store their structure in a database at the time they are created, only updating the XML is not sufficient. -Developers can add instructions for the framework to update these things during initialization. - -The instructions are provided as XML in the `OH-INF/update` folder. -The file name can be freely chosen and the file itself can contain instructions for one or more thing-types. -Instructions for the same thing-type MUST NOT be added in different files. - -Update instructions are available for adding, removing or updating channels or channel-groups. -Changes to configuration parameters don't need update instructions and are performed automatically. - -The following update instruction changes the channel-type for the `battery-level` channel to `system:battery-level`. - -```xml - - - - - - - system:battery-level - - - - - -``` - -Different instructions can be combined in one instruction-set. -The following removes the `water_level` channel from `foo:pool` things and adds a new `chlorine` level - -```xml - - - - - - - - - foo:concentration - - - - - - -``` - -In addition to the update instructions, the thing-type definition needs to add a property `thingTypeVersion` to prevent newly created things from being modified: - -```xml - - - - - - - - - - - 1 - - uid - - -``` - -Modifying or removing update instructions after they have been merged is not permitted, only additions are allowed. -Each new contribution of update instructions MUST increase the `thingTypeVersion`, even if there was no release. -The `thingTypeVersion` is bound to a thing-type, different thing types may have different versions. - -The full XML schema for update instructions can be found here: [https://www.openhab.org/schemas/update-description-1.0.0.xsd](https://www.openhab.org/schemas/update-description-1.0.0.xsd). +--- +layout: developersguide +title: Thing Descriptions +--- + +# Binding Definitions + +In order to work with _Things_ and _Channels_, some meta information about them is needed. + +These are provided through 'ThingType' and 'ChannelType' definitions, +which describe details about their functionality and configuration options. + +[[toc]] + +## ThingTypeProvider / ChannelTypeProvider + +Technically, the thing types are provided by `ThingTypeProvider`s (`org.openhab.core.thing.binding.ThingTypeProvider`). + +openHAB comes with an implementation of such a provider that reads XML files from the folder `OH-INF/thing` of bundles. +Although we refer to this XML syntax in the following, you also have the option to provide directly object model instances through your own provider implementation. + +The same applies for the channel types. +The `ChannelTypeProvider` interface can be registered as OSGi service to provide channel types programmatically. +When implementing a dynamic `ThingTypeProvider` you can also refer to the channel types that are defined inside XML files. + +## Things + +Things represent devices or services that can be individually added to, configured or removed from the system. +They either contain a set of channels or a set of channel groups. +A bridge is a specific type of thing as it can additionally provide access to other Things as well. +Which Things can be associated through which bridge type is defined within the description of a thing: + +```xml + + + + + + Some sample description + Lightbulb + ... + +``` + +Bindings may optionally set the listing of a thing type. +By doing do, they indicate to user interfaces whether it should be shown to the users or not, e.g. when pairing things manually: + +```xml + + ... + +``` + +Thing types are listed by default, unless specified otherwise. +Hiding thing types potentially makes sense if they are deprecated and should not be used anymore. +Also, this can be useful if users should not be bothered with distinguishing similar devices which for technical reasons have to have separate thing types. +In that way, a generic thing type could be listed for users and a corresponding thing handler would change the thing type immediately to a more concrete one, handing over control to the correct specialized handler. + +### Thing Categories + +Categories are used to provide meta information about Things. Thing categories describe how the physical device **looks like**. UIs can use this information e.g. to render icons. +The available categories correspond with the [available icons of the classic iconset]({{base}}/configuration/iconsets/classic/), however categories are written in Java class-naming style, e.g. `FrontDoor` instead of lowercase `frontdoor`. + +## Channels + +A channel describes a specific functionality of a thing and can be linked to an item. +So the basic information is, which command types the channel can handle and which state it sends to the linked item. +This can be specified by the accepted item type. +Inside the thing type description XML file a list of channels can be referenced. +The channel type definition is specified on the same level as the thing type definition. +That way channels can be reused in different things. + +The granularity of channel types should be on its semantic level, i.e. very fine-grained: +If a Thing measures two temperature values, one for indoor and one for outdoor, this should be modelled as two different channel types. +Overriding labels of a channel type must only be done if the very same functionality is offered multiple times, e.g. having an actuator with 5 relays, which each is a simple "switch", but you want to individually name the channels (1-5). + +### State Channel Types + +The following XML snippet shows a thing type definition with three channels and two referenced channel types: + +```xml + + + Some sample description + + + + + + + + Number + + Temperature + + + + Number:Dimensionless + + + +``` + +The `item-type` element defines the [item type](../../configuration/items.md#type) to be used when a linked item is created. +If the `item-type` is a `Number:`, then a `unitHint` attribute may be provided to suggest the measurement unit to be used when a linked item is created. + +In order to reuse identical channels in different bindings a channel type can be system-wide. +A channel type can be declared as system-wide by setting its `system` property to true and can then be referenced using a `system.` prefix in a `channel` `typeId` attribute in any binding - note that this should only be done in the core framework, but not by individual bindings! + +The following XML snippet shows a system channel type definition and thing type definition that references it: + +```xml + + + Some sample description + + + + + + Number + + QualityOfService + +``` + +### System State Channel Types + +There exist system-wide channel types that are available by default and which should be used whenever possible: + +| Channel Type ID | Reference typeId | Item Type | Category | Tags | Description | +|-----------------------|------------------------------|--------------------------|------------------|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| signal-strength | system.signal-strength | Number | QualityOfService | Measurement, Level | Represents signal strength of a device as a Number with values 0, 1, 2, 3 or 4; 0 being worst strength and 4 being best strength. | +| low-battery | system.low-battery | Switch | LowBattery | LowBattery, Energy | Represents a low battery warning with possible values on (low battery) and off (battery ok). | +| battery-level | system.battery-level | Number | Battery | Measurement, Energy | Represents the battery level as a percentage (0-100%). Bindings for things supporting battery level in a different format (e.g. 4 levels) should convert to a percentage to provide a consistent battery level reading. | +| power | system.power | Switch | Switch | Switch, Power | Turn a device on/off. | +| brightness | system.brightness | Dimmer | Light | Control, Light | Brightness of a bulb (0-100%). | +| color | system.color | Color | ColorLight | Control, Light | Color of a bulb. | +| color-temperature | system.color-temperature | Dimmer | ColorLight | Control, ColorTemperature | Color temperature of a bulb (0-100%). 0% should be the coldest setting (highest Kelvin value), 100 the warmest. | +| color-temperature-abs | system.color-temperature-abs | Number | ColorLight | Control, ColorTemperature | Color temperature of a bulb in Kelvin (1000K-10000K). | +| location | system.location | Location | - | Measurement | Location in lat.,lon.,height coordinates. | +| motion | system.motion | Switch | Motion | Status, Presence | Motion detected by the device (ON if motion is detected). | +| mute | system.mute | Switch | SoundVolume | Switch, SoundVolume | Turn on/off the volume of a device. | +| volume | system.volume | Dimmer | SoundVolume | Control, SoundVolume | Change the sound volume of a device (0-100%). | +| media-control | system.media-control | Player | MediaControl | Control | Control for a media player. | +| media-title | system.media-title | String | - | Status | Title of a (played) media file. | +| media-artist | system.media-artist | String | - | Status | Artist of a (played) media file. | +| outdoor-temperature | system.outdoor-temperature | Number:Temperature | Temperature | Measurement, Temperature | Current outdoor temperature. | +| indoor-temperature | system.indoor-temperature | Number:Temperature | Temperature | Measurement, Temperature | Current indoor temperature. | +| wind-direction | system.wind-direction | Number:Angle | Wind | Measurement, Wind | Wind direction in degrees (0-360°). | +| wind-speed | system.wind-speed | Number:Speed | Wind | Measurement, Wind | Wind speed | +| atmospheric-humidity | system.atmospheric-humidity | Number:Dimensionless | Humidity | Measurement, Humidity | Atmospheric humidity in percent. | +| barometric-pressure | system.barometric-pressure | Number:Pressure | Pressure | Measurement, Pressure | Barometric pressure | +| electric-current | system.electric-current | Number:ElectricCurrent | Energy | Measurement, Current | Electric current | +| electric-power | system.electric-power | Number:Power | Energy | Measurement, Power | Electric power | +| electric-voltage | system.electric-voltage | Number:ElectricPotential | Energy | Measurement, Voltage | Electric voltage | +| electrical-energy | system.electric-energy | Number:Energy | Energy | Measurement, Energy | Electrical energy | + +The `advanced` property indicates whether this channel is a basic or a more specific functionality of the thing. +If `advanced` is set to `true` a user interface may hide this channel by default. +The default value is `false` and thus will be taken if the `advanced` attribute is not specified. +Especially for complex devices with a lot of channels, only a small set of channels - the most important ones - should be shown to the user to reduce complexity. +Whether a channel should be declared as `advanced` depends on the device and can be decided by the binding developer. +If a functionality is rarely used it should be better marked as `advanced`. + +### Trigger Channel Types + +The following XML snippet shows a trigger channel: + +```xml + + + Some sample description + + + + + + trigger + + + + + + + + + +``` + +This channel can emit the event payloads `PRESSED`, `RELEASED` and `DOUBLE_PRESSED`. + +If no `` tag is specified, the channel can be triggered, but has no event payload. +If an empty `` tag is specified, the channel can trigger any event payload. + +### System Trigger Channel Types + +There exist system-wide trigger channel types that are available by default: + +| Channel Type ID | Reference typeId | Description | +|-----------------|------------------|---------------------------------------------------------------------------------| +| trigger | system.trigger | Can only trigger, no event payload | +| rawbutton | system.rawbutton | Can trigger `PRESSED` and `RELEASED` | +| button | system.button | Can trigger `SHORT_PRESSED`, `DOUBLE_PRESSED` and `LONG_PRESSED` | +| rawrocker | system.rawrocker | Can trigger `DIR1_PRESSED`, `DIR1_RELEASED`, `DIR2_PRESSED` and `DIR2_RELEASED` | + +In the following sections the declaration and semantics of tags, state descriptions and channel categories will be explained in more detail. +For a complete sample of the thing types XML file and a full list of possible configuration options please see the [XML Configuration Guide](../addons/config-xml.html). + +### Default Tags + +The XML definition of a ChannelType allows to assign default tags to channels. +All items bound to this channel will automatically be tagged with these default tags. +The following snippet shows a 'Control' and 'Light' tags definition: + +```xml + + Control + Light + +``` + +There are two possible types of tag -- namely "Semantic" and "Non Semantic" tags. +The former are used by the openHAB User Interface to create automatic groupings of items according to the [Semantic Model]({{base}}/tutorial/model.html). +The latter are (optionally) be used for any other tagging purpose at the discretion of the user. +Semantic tags are classed into four sub-types `point`, `property`, `equipment` and `location`. + +Addon developers are strongly requested to provide tags in the channel description and thing type XML. +Note: it is also possible to provide tags in instantiated channels and things at run-time. +When providing such tags, developers shall comply with the [Developer Guidelines on Semantic Tags](semantic-tags.md). + +You can view the actual list of [Semantic Tags](https://github.com/openhab/openhab-core/blob/main/bundles/org.openhab.core.semantics/model/SemanticTags.csv). +The contents of this list are dynamic, and it may be extended from time to time. +If you are an addon developer and you think there is something missing from the list please open an [Issue](https://github.com/openhab/openhab-core/issues) or [Pull Request](https://github.com/openhab/openhab-core/pulls) on GitHub. +Please make sure you comply with the [Developer Guidelines on Semantic Tags](semantic-tags.md) and the [Semantic Model]({{base}}/tutorial/model.html). + +### State Description + +The state description allows to specify restrictions and additional information for the state of an item, that is linked to the channel. +Some configuration options are only valid for specific item types. +The following XML snippet shows the definition for a temperature actuator channel: + +```xml + +``` + +- The attributes `min` and `max` can only be declared for channel with the item type `Number`. + It defines the range of the numeric value. + The Java data type is a BigDecimal. + For example user interfaces can create sliders with an appropriate scale based on this information. +- The `step` attribute can be declared for `Number` and `Dimmer` items and defines what is the minimal step size that can be used. +- The `readonly` attribute can be used for all item types and defines if the state of an item can be changed. + For all sensors the `readonly` attribute should be set to `true`. +- The `pattern` attribute can be used for `Number` and `String` items. + It gives user interface a hint how to render the item. + The format of the pattern must be compliant to the [Java Number Format](https://docs.oracle.com/javase/tutorial/java/data/numberformat.html). + The pattern can be localized (see also [Internationalization](../utils/i18n.html)). + The special pattern placeholder `%unit%` is used for channels which bind to items of type `Number:` which define a dimension for unit support. + These channels will send state updates of type [QuantityType](../../concepts/units-of-measurement.html#quantitytype) and the unit is then rendered for the placeholder. + +Some channels might have only a limited and countable set of states. +These states can be specified as options. +A `String` or `Number` item must be used as item type. +In general `String` should be preferred with a meaningful option value. +This prevents the user from having to guess what a value represents if a number is used as option value. +`Number` is useful when the value represents a quantity (e.g. like in the system-wide channel type `signal-strength`). + +The following XML snippet defines a list of predefined state options: + +```xml + + + + + + + +``` + +The user interface can use these values to render labels for values or to provide a selection of states, when the channel is writable. +The option labels can also be localized. + +### Command Description + +If the primary purpose of a channel is to send commands towards a device (i.e. the opposite direction of trigger channels), +it can use command options. + +A `String` item must be used as item type. + +The following XML snippet defines a list of commands: + +```xml + + + + + + +``` + +The user interface can use these values to render + +- a drop down and also represent the current state or +- as push buttons to simply send a command to the ThingHandler. + +The option labels can also be localized. + +#### Dynamic State / Command Description + +In situations where the static definition of a state description is not sufficient a binding would implement a `DynamicStateDescriptionProvider` or a `DynamicCommandDescriptionProvider`. + +These providers allow to provide a `StateDescription` (or `CommandDescription` respectively) based on the specific `Channel`. + +Also implement this interface if you want to provide dynamic state / command options. +The original `StateDescription`/`CommandDescription` is available for modification and enhancement. +The framework provides two abstract implementations for bindings to support translation, publishing `ChannelDescriptionChangedEvent`s and other basic features: `BaseDynamicStateDescriptionProvider` and `BaseDynamicCommandDescriptionProvider`. + +The `StateDescriptionFragmentBuilder` (and `CommandDescriptionBuilder`) can be used to only provide the information which is available at the time of construction. + +##### Example code for a `DynamicStateDescriptionProvider` implementation + +```java +@Component(service = { DynamicStateDescriptionProvider.class, ExampleDynamicStateDescriptionProvider.class }) +public class ExampleDynamicStateDescriptionProvider implements DynamicStateDescriptionProvider { + + private final Map> channelOptionsMap = new ConcurrentHashMap<>(); + + /** + * For a given channel UID, set a {@link List} of {@link StateOption}s that should be used for the channel, instead + * of the one defined statically in the {@link ChannelType}. + * + * @param channelUID the channel UID of the channel + * @param options a {@link List} of {@link StateOption}s + */ + public void setStateOptions(ChannelUID channelUID, List options) { + channelOptionsMap.put(channelUID, options); + } + + @Override + public @Nullable StateDescription getStateDescription(Channel channel, @Nullable StateDescription original, + @Nullable Locale locale) { + List options = channelOptionsMap.get(channel.getUID()); + if (options == null) { + return null; + } + + StateDescriptionFragmentBuilder builder = (original == null) ? StateDescriptionFragmentBuilder.create() + : StateDescriptionFragmentBuilder.create(original); + return builder.withOptions(options).build().toStateDescription(); + } + + @Deactivate + public void deactivate() { + channelOptionsMap.clear(); + } +} +``` + +##### Example code for a `DynamicStateDescriptionProvider` implementation which extends the `BaseDynamicStateDescriptionProvider` + +```java +@Component(service = { DynamicStateDescriptionProvider.class, ExampleDynamicStateDescriptionProvider.class }) +public class ExampleDynamicStateDescriptionProvider extends BaseDynamicStateDescriptionProvider { + + @Activate + public ExampleDynamicStateDescriptionProvider(final @Reference EventPublisher eventPublisher, // + final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry, // + final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { + this.eventPublisher = eventPublisher; + this.itemChannelLinkRegistry = itemChannelLinkRegistry; + this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService; + } +} +``` + +##### Example code for a `DynamicCommandDescriptionProvider` implementation + +```java +@Component(service = { DynamicCommandDescriptionProvider.class, ExampleDynamicCommandDescriptionProvider.class }) +public class ExampleDynamicCommandDescriptionProvider implements DynamicCommandDescriptionProvider { + + private final Map> channelOptionsMap = new ConcurrentHashMap<>(); + + /** + * For a given channel UID, set a {@link List} of {@link CommandOption}s that should be used for the channel, + * instead of the one defined statically in the {@link ChannelType}. + * + * @param channelUID the channel UID of the channel + * @param options a {@link List} of {@link CommandOption}s + */ + public void setCommandOptions(ChannelUID channelUID, List options) { + channelOptionsMap.put(channelUID, options); + } + + @Override + public @Nullable CommandDescription getCommandDescription(Channel channel, + @Nullable CommandDescription originalCommandDescription, @Nullable Locale locale) { + List options = channelOptionsMap.get(channel.getUID()); + if (options == null) { + return null; + } + + return CommandDescriptionBuilder.create().withCommandOptions(options).build(); + } +} +``` + +Most of the times handlers need to modify those dynamic information. +Therefore the `ThingHandlerFactory` has to reference the bundle instance and pass it to the handler. + +```java +public class ExampleHandlerFactory extends BaseThingHandlerFactory { + + private final ExampleDynamicStateDescriptionProvider stateDescriptionProvider; + + @Activate + public ExampleHandlerFactory(final @Reference ExampleDynamicStateDescriptionProvider stateDescriptionProvider) { + this.stateDescriptionProvider = stateDescriptionProvider; + } + + @Override + protected ThingHandler createHandler(Thing thing) { + if (EXAMPLE_THING_TYPE.equals(thing.getThingTypeUID())) { + return new ExampleHandler(thing, stateDescriptionProvider); + } + return null; + } +} +``` + +### Channel Categories + +Channel categories are used to provide meta information about channels. Channel categories describe the **functional purpose** of the channel and are used by the UI to render icons. +The available categories correspond with the [available icons of the classic iconset]({{base}}/configuration/iconsets/classic/), however categories are written in Java class-naming style, e.g. `BatteryLevel` instead of lowercase `batterylevel`. + +### Channel Groups + +Some devices might have a lot of channels. +There are also complex devices like a multi-channel actuator, which is installed inside the switchboard, but controls switches in other rooms. +Therefore channel groups can be used to group a set of channels together into one logical block. +A thing can only have direct channels or channel groups, but not both. + +Inside the thing types XML file channel groups can be defined like this: + +```xml + + + + + + + + +``` + +The channel group type is defined on the same level as the thing types and channel types. +The group type must have a label, an optional description, and an optional category (e.g. used to render an icon).. +Moreover the list of contained channels must be specified: + +```xml + + + This is a single switch actor with a switch channel + Light + + + + +``` + +When a thing will be created for a thing type with channel groups, the channel UID will contain the group ID in the last segment divided by a hash (#). +If an Item should be linked to a channel within a group, the channel UID would be `binding:multiChannelSwitchActor:myDevice:switchActor1#switch` for the XML example before. + +## Properties + +Solutions based on openHAB might require meta data from a device. +These meta data could include: + +- general device information, e.g. the device vendor, the device series or the model ID, ... +- device characteristics, e.g. if it is battery based, which home automation protocol is used, what is the current firmware version or the serial number, ... +- physical descriptions, e.g. what is the size, the weight or the color of the device, ... +- any other meta data that should be made available for the solution by the binding + +Depending on the solution the provided meta data can be used for different purposes. +Among others the one solution could use the data during a device pairing process whereas another solution might use the data to group the devices/things by the vendors or by the home automation protocols on a user interface. +To define such thing meta data the thing type definition provides the possibility to specify so-called `properties`: + +```xml + + ... + + MyThingVendor + thingTypeId + ZigBee + ... + + ... + +``` + +In general each `property` must have a name attribute which should be written in camel case syntax. +The actual property value is defined as plain text and is placed as child node of the property element. +It is recommended that at least the vendor and the model id properties are specified here since they should be definable for the most of the devices. +In contrast to the properties defined in the 'ThingType' definitions the thing handler [documentation](thing-handler.html) explains how properties can be set during runtime. + +### Representation Property + +A thing type can contain a so-called `representation property`. +This optional property contains the **name** of a property whose value can be used to uniquely identify a device. +The `thingUID` cannot be used for this purpose because there can be more than one thing for the same device. + +Each physical device normally has some kind of a technical identifier which is unique. +This could be a MAC address (e.g. Hue bridge, camera, all IP-based devices), a unique device id (e.g. a Hue lamp) or some other property that is unique per device type. +This property is normally part of a discovery result for that specific thing type. +Having this property identified per binding it could be used as the `representation property` for this thing. + +The `representation property` shall be defined in the thing type XML: + +```xml + + ... + + Philips + + uniqueId + ... + +``` + +Note that the `representation property` is normally not listed in the `properties` part of the Thing type XML, as this part contains static properties, that are the same for all instances of this Thing type. +The name of the `representation property` identifies a property or configuration parameter that is added to the Thing in the Thing handler upon successful initialization. + +### Representation Property and Discovery + +The representation property is used to auto-ignore discovery results of Things that already exist in the system. +This can happen if, a) a Thing has been created manually, or b) the Thing has been discovered separately by two mechanisms e.g. by mDNS, and by NetBios, or UPnP. +If this is the case, the Thing in the inbox is automatically ignored. +Note that this Thing is automatically removed when the manually added Thing is removed. +A new discovery would then automatically find this Thing again and add it to the inbox properly. + +See also [Implementing a Discovery Service](index.md#representation-property) + +When comparing representation properties, the auto-ignore service checks for matches between the representation property of the newly discovered Thing, and both the properties and the configuration parameters of existing Things. +If a configuration parameter will be used, then its respective `parameter` shall be declared in the XML `config-description` section or the `config-description` [XML file](../addons/config-xml.md): + +```xml + + ... + uniqueId + ... + + + + The Unique Id for Representation Property + + + ... + +``` + +## Formatting Labels and Descriptions + +The label and descriptions for things, channels and config descriptions should follow the following format. +The label should be short so that for most UIs it does not spread across multiple lines. +Guideline is 2-3 words with up to 25 chars. +Labels should be capitalized using the following rules: + +- Always capitalize the first and the last word. +- Lowercase articles, coordinating conjunctions, and prepositions (`a, an, the, and, as, but, by, for, from, in, into, like, near, nor, of, onto, or, out, over, past, so, till, to, up, upon, with, yet`). +- Capitalize all other words. +- Brand- or product names that starts with a lowercase character can be written using their official spelling. + +The description can contain longer text to describe the thing in more detail. +Limited use of HTML tags is permitted to enhance the description - if a long description is provided, the first line should be kept short, and a line break (```
      ```) placed at the end of the line to allow UIs to display a short description in limited space. + +Configuration options should be kept short so that they are displayable in a single line in most UIs. +If you want to provide a longer description of the options provided by a particular parameter, then this should be placed into the `````` of the parameter to keep the option label short. +The description can include limited HTML to enhance the display of this information. + +The following HTML tags are allowed : ```,
      , ,

      ,

      ,

      ,

      ,

      ,
      , ,

      , , , , ,

        ,
          ,
        1. ```. +These must be inside the XML escape sequence - e.g. ``````. + +## Auto Update Policies + +Channel types can optionally define a policy with respect to the auto update handling. +This influences the decision within the framework if an auto-update of the item's state should be sent in case a command is received for it. +The auto update policy typically is inherited by the channel from its channel type. +Nevertheless, this value can be overridden in the channel definition. + +In this example, an auto update policy is defined for the channel type, but is overridden in the channel definition: + +```xml + + + recommend + + + + + Thing type which overrides the auto update policy of a channel + + + default + + + +``` + +The following policies are supported: + +- **veto**: No automatic state update should be sent by the framework. + The thing handler will make sure it sends a state update and it can do it better than just converting the command to a state. +- **default**: The binding does not care and the framework may do what it deems to be right. + The state update which the framework will send out normally will correspond the command state anyway. + This is the default if no other policy is set explicitly. +- **recommend**: An automatic state update should be sent by the framework because no updates are sent by the binding. + This usually is the case when devices don't expose their current state to the handler. + +## Bridges and Thing Descriptions + +Every binding has to provide meta information about which bridges and/or _Thing_s it provides and how their relations to each other are structured. +In that way a binding could describe that it requires specific bridges to be operational or define which channels (e.g. temperature, color, etc.) it provides. + +Every bridge or _Thing_ has to provide meta information such as label or description. +The meta information of all bridges and _Thing_s is accessible through the `org.openhab.core.thing.binding.ThingTypeProvider` service. + +Bridge and _Thing_ descriptions must be placed as XML file(s) (with the ending `.xml`) in the bundle's folder `/OH-INF/thing/`. +The full Java API for bridge and _Thing_ descriptions can be found in the Java package `org.openhab.core.thing.type`. + +### XML Structure for Thing Descriptions + +```xml + + + + + + + ... + + + + String + String + + + + OR + + + String + + ... + + OR + + + OR + + + String + + ... + + + + propertyValue + ... + + propertyName + + + ... + + OR + + + + + + + ... + + + + String + String + + + + OR + + + String + + ... + + OR + + + OR + + + String + + ... + + + + propertyValue + ... + + propertyName + + + ... + + OR + + + + + Dimmer + OR + trigger + + String + String + + + String + ... + + + + + + ... + + + OR + + + + ... + + + + + + + ... + + + + + ... + + OR + + + + + + String + String + + + + ... + + + + ... + + +``` + +| Property | Description | | +|------------------------------|----------------------------------------------------|-----------| +| thing-descriptions.bindingId | The identifier of the binding this types belong to | mandatory | + +**Bridges and Things:** + +| Property | Description | | +|------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------| +| bridge-type.id / thing-type.id | An identifier for the bridge/Thing type | mandatory | +| bridge-type.listed / thing-type.listed | Denotes if user interfaces should list the bridge/Thing, e.g. for pairing | optional, defaults to true | +| bridge-type.extensible / thing-type.extensible | If the bridge/Thing supports a generic number of channels the allowed channelTypeIds can be listed here. This provides a hint for UIs to support adding/removing channels. Channel groups are not supported. | optional | +| supported-bridge-type-refs | The identifiers of the bridges this bridge/Thing can connect to | optional | +| bridge-type-ref.id | The identifier of a bridge this bridge/Thing can connect to | mandatory | +| label | A human-readable label for the bridge/Thing | mandatory | +| description | A human-readable description for the bridge/Thing | optional | +| category | Category this bridge/Thing belongs to, see categories) | optional | +| channels | The channels the bridge/Thing provides | optional | +| channel.id | An identifier of the channel the bridge/Thing provides | mandatory | +| channel.typeId | An identifier of the channel type definition the bridge/Thing provides | mandatory | +| label | A human-readable label for the channel | optional | +| description | A human-readable description for the channel | optional | +| channel-groups | The channel groups defining the channels the bridge/Thing provides | optional | +| channel-group.id | An identifier of the channel group the bridge/Thing provides | mandatory | +| channel-group.typeId | An identifier of the channel group type definition the bridge/Thing provides | mandatory | +| properties | Name/value pairs for properties to be set to the thing | optional | +| representation-property | The name of the property that contains a unique identifier of the thing | optional | +| config-description | The configuration description for the bridge/Thing within the ConfigDescriptionRegistry | optional | +| config-description-ref | The reference to a configuration description for the bridge/Thing within the ConfigDescriptionRegistry | optional | +| config-description-ref.uri | The URI of the configuration description for the bridge/Thing within the ConfigDescriptionRegistry | mandatory | + +**Channels:** + +| Property | Description | | +|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------| +| channel-type.id | An identifier for the channel type | mandatory | +| channel-type.advanced | The flag indicating if this channel contains advanced functionalities which should be typically not shown in the basic view of user interfaces | optional, default: false | +| kind | The kind of channel. state for channels which have a state, trigger for trigger channels. state is the default. | | +| item-type | An item type of the channel. All item types are specified in ItemFactory instances. The following items belong to the core: Switch, Rollershutter, Contact, String, Number, Dimmer, DateTime, Color, Image, Location, Player, Call. | mandatory if kind state, which is the default | +| label | A human-readable label for the channel | mandatory | +| description | A human-readable description for the channel | optional | +| category | The category for the channel, e.g. TEMPERATURE | optional | +| tags | A list of default tags to be assigned to bound items | optional | +| tag | A tag semantically describes the feature (typical usage) of the channel e.g. AlarmSystem. See [Default Tags](#default-tags) above. | mandatory | +| state | The restrictions of an item state which gives information how to interpret it | optional | +| state.min | The minimum decimal value of the range for the state | optional | +| state.max | The maximum decimal value of the range for the state | optional | +| state.step | The increasing/decreasing decimal step size within the defined range, specified by the minimum/maximum values | optional | +| state.pattern | The pattern following the printf syntax to render the state | optional | +| state.readOnly | The flag indicating if the state is read-only or can be modified | optional, default: false | +| options | A list restricting all possible values | optional | +| option | The description for the option | optional | +| option.value | The value for the option. Note that the value may be outside of the range specified in the min/max if this is specified. | mandatory | +| command | Commands this channel will send to the binding. This is used to model "write-only" channels and gives UIs a hint to display push-buttons without state | optional | +| options | A list defining the possible commands | optional | +| option | The description for the option | optional | +| option.value | The value for the option. This is the actual command send to the channel. | mandatory | +| event | The restrictions of a trigger event which gives information how to interpret it | optional | +| autoUpdatePolicy | The auto update policy to use | optional | +| config-description | The configuration description for the channel within the ConfigDescriptionRegistry | optional | +| config-description-ref | The reference to a configuration description for the channel within the ConfigDescriptionRegistry | optional | +| config-description-ref.uri | The URI of the configuration description for the channel within the ConfigDescriptionRegistry | mandatory | + +**Channel Groups:** + +| Property | Description | | +|-----------------------|------------------------------------------------------------------------|-----------| +| channel-group-type.id | An identifier for the channel group type | mandatory | +| label | A human-readable label for the channel group | mandatory | +| description | A human-readable description for the channel group | optional | +| category | The category for the channel group, e.g. TEMPERATURE | optional | +| channels | The channels the bridge/Thing provides | mandatory | +| channel.id | An identifier of the channel the bridge/Thing provides | mandatory | +| channel.typeId | An identifier of the channel type definition the bridge/Thing provides | mandatory | + +The full XML schema for Thing type descriptions is specified in the [https://openhab.org/schemas/thing-description-1.0.0.xsd](https://openhab.org/schemas/thing-description-1.0.0.xsd) openHAB thing description XSD file. + +**Hints:** + +- Any identifiers of the types are automatically mapped to unique identifiers: `bindingID:id`. +- The attribute `uri` in the section `config-description` is optional, it _should not_ be specified in bridge/_Thing_/channel type definition files because it's an embedded configuration. + If the `uri` is _not_ specified, the configuration description is registered as `thing-type:bindingID:id` or `channel-type:bindingID:id` otherwise the given `uri` is used.s +- If a configuration description is already specified somewhere else and the bridge/_Thing_/channel type wants to (re-)use it, a `config-description-ref` should be used instead. + +### Updating Thing Types + +Sometimes, when bindings evolve, thing-types need to be modified. +Since managed things store their structure in a database at the time they are created, only updating the XML is not sufficient. +Developers can add instructions for the framework to update these things during initialization. + +The instructions are provided as XML in the `OH-INF/update` folder. +The file name can be freely chosen and the file itself can contain instructions for one or more thing-types. +Instructions for the same thing-type MUST NOT be added in different files. + +Update instructions are available for adding, removing or updating channels or channel-groups. +Changes to configuration parameters don't need update instructions and are performed automatically. + +The following update instruction changes the channel-type for the `battery-level` channel to `system:battery-level`. + +```xml + + + + + + + system:battery-level + + + + + +``` + +Different instructions can be combined in one instruction-set. +The following removes the `water_level` channel from `foo:pool` things and adds a new `chlorine` level + +```xml + + + + + + + + + foo:concentration + + + + + + +``` + +In addition to the update instructions, the thing-type definition needs to add a property `thingTypeVersion` to prevent newly created things from being modified: + +```xml + + + + + + + + + + + 1 + + uid + + +``` + +Modifying or removing update instructions after they have been merged is not permitted, only additions are allowed. +Each new contribution of update instructions MUST increase the `thingTypeVersion`, even if there was no release. +The `thingTypeVersion` is bound to a thing-type, different thing types may have different versions. + +The full XML schema for update instructions can be found here: [https://www.openhab.org/schemas/update-description-1.0.0.xsd](https://www.openhab.org/schemas/update-description-1.0.0.xsd).