]> git.basschouten.com Git - openhab-addons.git/commitdiff
[velbus] New functionality and bug fix (#15661)
authorDaniel Rosengarten <github@praetorians.be>
Sun, 28 Apr 2024 20:55:54 +0000 (22:55 +0200)
committerGitHub <noreply@github.com>
Sun, 28 Apr 2024 20:55:54 +0000 (22:55 +0200)
* [velbus] New functionnality & Bug fix

Signed-off-by: Daniel Rosengarten <github@praetorians.be>
Co-authored-by: Simonas Kazlauskas <github@kazlauskas.me>
Co-authored-by: lsiepel <leosiepel@gmail.com>
36 files changed:
bundles/org.openhab.binding.velbus/README.md
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/VelbusBindingConstants.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/VelbusColorChannel.java [new file with mode: 0644]
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/VelbusHandlerFactory.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/VelbusModuleAddress.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/VelbusPacketListener.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/VelbusVirtualColorChannel.java [new file with mode: 0644]
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/discovery/VelbusThingDiscoveryService.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusBlindsHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusBridgeHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusDimmerHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusRelayHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusRelayWithInputHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusSensorHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusSensorWithAlarmClockHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusTemperatureSensorHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusThermostatHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusThingHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusVMB4ANHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusVMB7INHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusVMBDALIHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusVMBELHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusVMBELOHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusVMBGPHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusVMBGPOHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusVMBMeteoHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusVMBPIROHandler.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusDaliRequestPacket.java [new file with mode: 0644]
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusRelayPacket.java
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusSetColorPacket.java [new file with mode: 0644]
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusSetDimPacket.java [new file with mode: 0644]
bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusSetScenePacket.java [new file with mode: 0644]
bundles/org.openhab.binding.velbus/src/main/resources/OH-INF/config/config.xml
bundles/org.openhab.binding.velbus/src/main/resources/OH-INF/i18n/velbus.properties
bundles/org.openhab.binding.velbus/src/main/resources/OH-INF/thing/thing-types.xml
bundles/org.openhab.binding.velbus/src/main/resources/OH-INF/update/instructions.xml [new file with mode: 0644]

index 873babc8d8f106db5207f4c4b3d535c10a7e8dbc..8f9bc74c66092019a7bdcab81a45b5e2bf9a0a5a 100644 (file)
@@ -31,59 +31,75 @@ xidel -e \
 ```
 -->
 
-| Type        | Description                                                                                |
-|-------------|--------------------------------------------------------------------------------------------|
-| vmb1bl      | 1-channel blind control module for din rail                                                |
-| vmb1bls     | 1-channel blind control module for universal mounting                                      |
-| vmb1dm      | Dimmer module for inductive/resistive and capacitive load                                  |
-| vmb1led     | 1-channel 0-10V controlled PWM dimmer for led strips                                       |
-| vmb1ry      | 1-channel relay module                                                                     |
-| vmb1ryno    | 1-channel relay module with potential-free changeover contact                              |
-| vmb1rynos   | 1-channel relay module with potential-free changeover contact                              |
-| vmb1rys     | 1-channel relay module with input                                                          |
-| vmb1ts      | Temperature Sensor Module                                                                  |
-| vmb2bl      | 2-channel blind control module                                                             |
-| vmb2ble     | 2-channel blind control module with extended possibilities                                 |
-| vmb2pbn     | Push-button interface for Niko 1- or 2-fold push-buttons                                   |
-| vmb4an      | Analog I/O module                                                                          |
-| vmb4dc      | 4-channel 0/1-10V dimmer controller                                                        |
-| vmb4pb      | 4 button interface module                                                                  |
-| vmb4ry      | 4-channel relay module                                                                     |
-| vmb4ryld    | 4-channel relay module with voltage outputs                                                |
-| vmb4ryno    | 4-channel relay module with potential-free contacts                                        |
-| vmb6in      | 6-channel input module                                                                     |
-| vmb6pbn     | Push-button interface module for Niko 4- or 6-fold push-button                             |
-| vmb7in      | 7-channel input module (potentialfree + pulse)                                             |
-| vmb8ir      | Infrared remote control receiver module                                                    |
-| vmb8pb      | 8-Channel Push Button module                                                               |
-| vmb8pbu     | Push-button interface with 8 channels for universal mounting                               |
-| vmbdme      | Dimmer for electronic/resistive load                                                       |
-| vmbdmir     | Single channel triac dimmer for resistive and inductive loads                              |
-| vmbdmi      | Single channel triac dimmer for resistive and inductive loads                              |
-| vmbel1      | Edge-lit one touch button module                                                           |
-| vmbel2      | Edge-lit two touch buttons module                                                          |
-| vmbel4      | Edge-lit four touch buttons module                                                         |
-| vmbelo      | Edge-lit touch panel with Oled display                                                     |
-| vmbelpir    | Edge-lit Motion detector with one touch button                                             |
-| vmbgp1-2    | Glass control module with 1 touch key (Edition 2)                                          |
-| vmbgp1      | Glass control module with 1 touch key                                                      |
-| vmbgp2-2    | Glass control module with 2 touch keys (Edition 2)                                         |
-| vmbgp2      | Glass control module with 2 touch keys                                                     |
-| vmbgp4-2    | Glass control module with 4 touch keys (Edition 2)                                         |
-| vmbgp4      | Glass control module with 4 touch keys                                                     |
-| vmbgp4pir-2 | Glass control module with 4 touch keys and built-in motion and twilight sensor (Edition 2) |
-| vmbgp4pir   | Glass control module with 4 touch keys and built-in motion and twilight sensor             |
-| vmbgpod-2   | Glass control module with oled display and temperature controller (Edition 2)              |
-| vmbgpod     | Glass control module with oled display and temperature controller                          |
-| vmbgpo      | Glass control module with oled display                                                     |
-| vmbin       | 1-channel input module                                                                     |
-| vmbkp       | Keypad interface module                                                                    |
-| vmbmeteo    | Weather station with thermometer, anemometer, rain sensor and light sensor                 |
-| vmbpirc     | Motion and twilight sensor for ceiling mounting                                            |
-| vmbpirm     | Mini motion and twilight sensor for recessed or surface mounting                           |
-| vmbpiro     | Outdoor motion, twilight and temperature sensor, Theben                                    |
-| vmbrfr8s    | 8 channel RF receiver module                                                               |
-| vmbvp1      | Doorbird interface module                                                                  |
+| Type         | Description                                                                                |
+|--------------|--------------------------------------------------------------------------------------------|
+| vmb1bl       | 1-channel blind control module for din rail                                                |
+| vmb1bls      | 1-channel blind control module for universal mounting                                      |
+| vmb1dm       | Dimmer module for inductive/resistive and capacitive load                                  |
+| vmb1led      | 1-channel 0-10V controlled PWM dimmer for led strips                                       |
+| vmb1ry       | 1-channel relay module                                                                     |
+| vmb1ryno     | 1-channel relay module with potential-free changeover contact                              |
+| vmb1rynos    | 1-channel relay module with potential-free changeover contact                              |
+| vmb1rys      | 1-channel relay module with input                                                          |
+| vmb1ts       | Temperature Sensor Module                                                                  |
+| vmb2bl       | 2-channel blind control module                                                             |
+| vmb2ble-10   | 2-channel blind control module with extended possibilities                                 |
+| vmb2ble      | 2-channel blind control module with extended possibilities                                 |
+| vmb2pbn      | Push-button interface for Niko 1- or 2-fold push-buttons                                   |
+| vmb4an       | Analog I/O module                                                                          |
+| vmb4dc       | 4-channel 0/1-10V dimmer controller                                                        |
+| vmb4pb       | 4 button interface module                                                                  |
+| vmb4ry       | 4-channel relay module                                                                     |
+| vmb4ryld-10  | 4-channel relay module with voltage outputs                                                |
+| vmb4ryld     | 4-channel relay module with voltage outputs                                                |
+| vmb4ryno-10  | 4-channel relay module with potential-free contacts                                        |
+| vmb4ryno     | 4-channel relay module with potential-free contacts                                        |
+| vmb6in       | 6-channel input module                                                                     |
+| vmb6pb-20    | 6-channel input module                                                                     |
+| vmb6pbn      | Push-button interface module for Niko 4- or 6-fold push-button                             |
+| vmb7in       | 7-channel input module (potentialfree + pulse)                                             |
+| vmb8ir       | Infrared remote control receiver module                                                    |
+| vmb8pb       | 8-Channel Push Button module                                                               |
+| vmb8pbu      | Push-button interface with 8 channels for universal mounting                               |
+| vmbdali-20   | DALI gateway module                                                                        |
+| vmbdali      | DALI gateway module                                                                        |
+| vmbdme       | Dimmer for electronic/resistive load                                                       |
+| vmbdmir      | Single channel triac dimmer for resistive and inductive loads                              |
+| vmbdmi       | Single channel triac dimmer for resistive and inductive loads                              |
+| vmbel1-20    | Edge-lit one touch button module                                                           |
+| vmbel1       | Edge-lit one touch button module                                                           |
+| vmbel2-20    | Edge-lit two touch buttons module                                                          |
+| vmbel2       | Edge-lit two touch buttons module                                                          |
+| vmbel4pir-20 | Edge-lit Motion detector with four touch buttons                                            |
+| vmbel4-20    | Edge-lit four touch buttons module                                                         |
+| vmbel4       | Edge-lit four touch buttons module                                                         |
+| vmbelo-20    | Edge-lit touch panel with Oled display                                                     |
+| vmbelo       | Edge-lit touch panel with Oled display                                                     |
+| vmbelpir     | Edge-lit Motion detector with one touch button                                             |
+| vmbgp1-20    | Glass control module with 1 touch key                                                      |
+| vmbgp1-2     | Glass control module with 1 touch key (Edition 2)                                          |
+| vmbgp1       | Glass control module with 1 touch key                                                      |
+| vmbgp2-20    | Glass control module with 2 touch keys                                                     |
+| vmbgp2-2     | Glass control module with 2 touch keys (Edition 2)                                         |
+| vmbgp2       | Glass control module with 2 touch keys                                                     |
+| vmbgp4-20    | Glass control module with 4 touch keys                                                     |
+| vmbgp4-2     | Glass control module with 4 touch keys (Edition 2)                                         |
+| vmbgp4       | Glass control module with 4 touch keys                                                     |
+| vmbgp4pir-20 | Glass control module with 4 touch keys and built-in motion and twilight sensor             |
+| vmbgp4pir-2  | Glass control module with 4 touch keys and built-in motion and twilight sensor (Edition 2) |
+| vmbgp4pir    | Glass control module with 4 touch keys and built-in motion and twilight sensor             |
+| vmbgpod-2    | Glass control module with oled display and temperature controller (Edition 2)              |
+| vmbgpod      | Glass control module with oled display and temperature controller                          |
+| vmbgpo-20    | Glass control module with oled display and temperature controller                          |
+| vmbgpo       | Glass control module with oled display                                                     |
+| vmbin        | 1-channel input module                                                                     |
+| vmbkp        | Keypad interface module                                                                    |
+| vmbmeteo     | Weather station with thermometer, anemometer, rain sensor and light sensor                 |
+| vmbpirc      | Motion and twilight sensor for ceiling mounting                                            |
+| vmbpirm      | Mini motion and twilight sensor for recessed or surface mounting                           |
+| vmbpiro      | Outdoor motion, twilight and temperature sensor, Theben                                    |
+| vmbrfr8s     | 8 channel RF receiver module                                                               |
+| vmbvp1       | Doorbird interface module                                                                  |
 
 ## Discovery
 
@@ -242,8 +258,29 @@ xidel -e 'let $refs := (
 | `dimspeed`                | `vmb1dm`, `vmb1led`, `vmb4dc`, `vmbdme`, `vmbdmi`, `vmbdmir`                                                                                                                                                      | The time (in seconds) needed for dimming from 0 to 100%.                                                                     |
 | `refresh`                 | `vmb1ts`, `vmb4an`, `vmb7in`, `vmbel1`, `vmbel2`, `vmbel4`, `vmbelpir`, `vmbgp1`, `vmbgp1-2`, `vmbgp2`, `vmbgp2-2`, `vmbgp4`, `vmbgp4-2`, `vmbgp4pir`, `vmbgp4pir-2`, `vmbmeteo`, `vmbpirc`, `vmbpirm`, `vmbpiro` | Refresh interval for sensors or counters (in seconds), default 300. If set to 0 or left empty, no refresh will be scheduled. |
 
+The `vmbdali` and `vmbdali-20` things have 16 virtual light channels. 
+A virtual light combines 3 or 4 VMBDALI module channels into an openHAB channel to control RGB or RGBW lights.
+This is because an RGBW DALI light is configured on the VMBDALI module with 4 channels (Red channel, Green channel, Blue channel, White channel).
+The channels of the virtual light can be identified by a module channel `CH1` ... `CH64` or a DALI address `A0` ... `A63`.
+
+The configuration is set like this:
+
+```java
+Thing velbus:vmbdali:<bridgeId>:<thingId> [VL1="R,G,B,W"]
+```
+
+The white channel is optional.
+
+e.g.:
+
+```java
+Thing velbus:vmbdali:1:01 [VL1="CH1,CH2,CH3,CH4", VL2="A4,A5,A6"]
+```
+
 ## Channels
 
+The bridges have a number of channels to set the global alarms: `bridgeClockAlarm#clockAlarm1Enabled`,  `bridgeClockAlarm#clockAlarm1WakeupHour`, `bridgeClockAlarm#clockAlarm1WakeupMinute`, `bridgeClockAlarm#clockAlarm1BedtimeHour`, `bridgeClockAlarm#clockAlarm1BedtimeMinute`, `bridgeClockAlarm#clockAlarm2Enabled`,  `bridgeClockAlarm#clockAlarm2WakeupHour`, `bridgeClockAlarm#clockAlarm2WakeupMinute`, `bridgeClockAlarm#clockAlarm2BedtimeHour` and `bridgeClockAlarm#clockAlarm2BedtimeMinute`.
+
 For thing types `vmb1bl` and `vmb1bls` the supported channel is `CH1`.
 UpDown, StopMove and Percent command types are supported.
 
@@ -257,7 +294,7 @@ OnOff command types are supported.
 For thing type `vmb4ry` 4 channels are available `CH1` ... `CH4`.
 OnOff command types are supported.
 
-For thing types `vmb1ryno`, `vmb1rynos`, `vmb4ryld` and `vmb4ryno` 5 channels are available `CH1` ... `CH5`.
+For thing types `vmb1ryno`, `vmb1rynos`, `vmb4ryld`, `vmb4ryld-10`, `vmb4ryno` and `vmb4ryno-10` 5 channels are available `CH1` ... `CH5`.
 OnOff command types are supported.
 
 For thing types `vmb1rys` 6 channels are available `CH1` ... `CH6`.
@@ -265,9 +302,9 @@ OnOff command types are supported on channels `CH1` ... `CH5`.
 Pressed and Long_Pressed command types are supported on channel `CH6`.
 1 trigger channel on `CH6t`.
 
-The module `vmb1ts` has a number of channels to set the module's thermostat (`thermostat:currentTemperatureSetpoint`, `thermostat:heatingModeComfortTemperatureSetpoint`, `thermostat:heatingModeDayTemperatureSetpoint`, `thermostat:heatingModeNightTemperatureSetpoint`, `thermostat:heatingModeAntiFrostTemperatureSetpoint`, `thermostat:coolingModeComfortTemperatureSetpoint`, `thermostat:coolingModeDayTemperatureSetpoint`, `thermostat:coolingModeNightTemperatureSetpoint`, `thermostat:coolingModeSafeTemperatureSetpoint`, `operatingMode` and `thermostat:mode`) and thermostat trigger channels: `thermostat:heater`, `thermostat:boost`, `thermostat:pump`, `thermostat:cooler`, `thermostat:alarm1`, `thermostat:alarm2`, `thermostat:alarm3`, `thermostat:alarm4`.
+The module `vmb1ts` has a number of channels to set the module's thermostat (`thermostat#currentTemperatureSetpoint`, `thermostat#heatingModeComfortTemperatureSetpoint`, `thermostat#heatingModeDayTemperatureSetpoint`, `thermostat#heatingModeNightTemperatureSetpoint`, `thermostat#heatingModeAntiFrostTemperatureSetpoint`, `thermostat#coolingModeComfortTemperatureSetpoint`, `thermostat#coolingModeDayTemperatureSetpoint`, `thermostat#coolingModeNightTemperatureSetpoint`, `thermostat#coolingModeSafeTemperatureSetpoint`, `operatingMode` and `thermostat#mode`) and thermostat trigger channels: `thermostat#heater`, `thermostat#boost`, `thermostat#pump`, `thermostat#cooler`, `thermostat#alarm1`, `thermostat#alarm2`, `thermostat#alarm3`, `thermostat#alarm4`.
 
-For thing types `vmb2bl` and `vmb2ble` the supported channels are `CH1` and `CH2`. UpDown, StopMove and Percent command types are supported.
+For thing types `vmb2bl`, `vmb2ble` and `vmb2ble-10` the supported channels are `CH1` and `CH2`. UpDown, StopMove and Percent command types are supported.
 
 For thing type `vmb6in` 6 channels are available `CH1` ... `CH6`.
 Pressed and Long_Pressed command types are supported on channels `button#CH1` ... `button#CH6`.
@@ -277,17 +314,16 @@ For thing type `vmb7in` 8 channels are available `CH1` ... `CH8`.
 Pressed and Long_Pressed command types are supported on channels `button#CH1` ... `button#CH8`.
 8 trigger channels on channels `input#CH1` ... `input#CH8`.
 
-For thing types `vmb2pbn`, `vmb6pbn`, `vmb7in`, `vmb8ir`, `vmb8pb`, `vmb8pbu`, `vmbrfr8s` and `vmbvp1`  8 channels are available `CH1` ... `CH8`.
+For thing types `vmb2pbn`, `vmb6pbn`, `vmb7in`, `vmb8ir`, `vmb8pb`, `vmb8pbu`, `vmbrfr8s`, `vmbvp1` and `vmb6pb-20` 8 channels are available `CH1` ... `CH8`.
 Pressed and Long_Pressed command types are supported on channels `button#CH1` ... `button#CH8`.
-8 trigger channels on channels `input:CH1` ... `input:CH8`.
-
-Thing types `vmb2pbn`, `vmb6pbn`, `vmb7in`, `vmb8pb`, `vmb8pbu`, `vmbrfr8s` and `vmbvp1` also have and 2 channels to steer the button LED feedback (`feedback:CH1` and `feedback:CH2`).
-Additionally, the modules `vmb2pbn`, `vmb6pbn`, `vmb7in`, `vmb8pbu`, `vmbrfr8s` and `vmbvp1` have a number of channels to set the module's alarms: `clockAlarm:clockAlarm1Enabled`, `clockAlarm:clockAlarm1Type`, `clockAlarm:clockAlarm1WakeupHour`, `clockAlarm:clockAlarm1WakeupMinute`, `clockAlarm:clockAlarm1BedtimeHour`, `clockAlarm:clockAlarm1BedtimeMinute`, `clockAlarm:clockAlarm2Enabled`, `clockAlarm:clockAlarm2Type`, `clockAlarm:clockAlarm2WakeupHour`, `clockAlarm:clockAlarm2WakeupMinute`, `clockAlarm:clockAlarm2BedtimeHour` and `clockAlarm:clockAlarm2BedtimeMinute`.
+8 trigger channels on channels `input#CH1` ... `input#CH8`.
+Thing types `vmb2pbn`, `vmb6pbn`, `vmb7in`, `vmb8pb`, `vmb8pbu`, `vmbrfr8s` and `vmbvp1` also have 8 channels to steer the button LED feedback `feedback#CH1` ... `feedback#CH8`.
+Additionally, the modules `vmb2pbn`, `vmb6pbn`, `vmb7in`, `vmb8pbu`, `vmbrfr8s`, `vmbvp1` and `vmb6pb-20` have a number of channels to set the module's alarms: `clockAlarm#clockAlarm1Enabled`,  `clockAlarm#clockAlarm1WakeupHour`, `clockAlarm#clockAlarm1WakeupMinute`, `clockAlarm#clockAlarm1BedtimeHour`, `clockAlarm#clockAlarm1BedtimeMinute`, `clockAlarm#clockAlarm2Enabled`,  `clockAlarm#clockAlarm2WakeupHour`, `clockAlarm#clockAlarm2WakeupMinute`, `clockAlarm#clockAlarm2BedtimeHour` and `clockAlarm#clockAlarm2BedtimeMinute`.
 
-For thing type`vmb4an` 8 trigger channels are avaiable `input:CH1` ... `input:CH8`.
+For thing type`vmb4an` 8 trigger channels are avaiable `input#CH1` ... `input#CH8`.
 These channels will be triggered by the module's alarms.
 Four pairs of channels are available to retrieve the module's analog inputs.
-Each pair has a channel to retrieve the raw analog value (`analogInput:CH9Raw` ... `analogInput:CH12Raw`) and a channel to retrieve the textual analog value (`analogInput:CH9` ... `analogInput:CH12`).
+Each pair has a channel to retrieve the raw analog value (`analoginput#CH9Raw` ... `analoginput#CH12Raw`) and a channel to retrieve the textual analog value (`analoginput#CH9` ... `analoginput#CH12`).
 Four channels are available to set the module's analog outputs `analogOutput:CH13` ... `analogOutput:CH16`.
 
 For thing type `vmb4dc` 4 channels are available `CH1` ... `CH4`.
@@ -297,29 +333,41 @@ Sending an ON command will switch the dimmer to the value stored when last turni
 For thing type `vmb4ry` 4 channels are available `CH1` ... `CH4`.
 OnOff command types are supported.
 
-Thing types `vmbel1`, `vmbel2`, `vmbel4`, `vmbelpir`, `vmbgp1`, `vmbgp2`, `vmbgp4`, `vmbgp4pir` and `vmbpiro` have 8 trigger channels `input:CH1` ... `input:CH8` and one temperature channel `input:CH9`.
+Thing types `vmbel1`, `vmbel1-20`, `vmbel2`, `vmbel2-20`, `vmbel4`, `vmbel4-20`, `vmbelpir`, `vmbel4pir-20`, `vmbgp1`, `vmbgp2`, `vmbgp4`, `vmbgp4pir`, `vmbgp4pir-20` and `vmbpiro` have 8 trigger channels `input:CH1` ... `input:CH8` and one temperature channel `input:CH9`.
 Pressed and Long_Pressed command types are supported on channels `button#CH1` and `button#CH2` for the thing type `vmbelpir`.
-Pressed and Long_Pressed command types are supported on channels `button#CH1` ... `button#CH8` for the thing types `vmbel1`, `vmbel2`, `vmbel4`, `vmbgp1`, `vmbgp2`, `vmbgp4`, `vmbgp4pir` and `vmbpiro`.
-The thing types `vmbel1` and `vmbgp1` have one channel to steer the button LED feedback `feedback:CH1`.
-The thing types `vmbel2` and `vmbgp2` have two channels to steer the button LED feedback `feedback:CH1` and `feedback:CH2`.
-The thing types `vmbel4`, `vmbgp4` and `vmbgp4pir` have four channels to steer the button LED feedback `feedback:CH1` ... `feedback:CH4`.
-The thing type `vmbpiro` has a channel `input:LIGHT` indicating the illuminance.
-Thing types `vmbel1`, `vmbel2`, `vmbel4`, `vmbelpir`, `vmbgp1`, `vmbgp2`, `vmbgp4` and `vmbgp4pir` have a number of channels to set the module's alarms: `clockAlarm:clockAlarm1Enabled`, `clockAlarm:clockAlarm1Type`, `clockAlarm:clockAlarm1WakeupHour`, `clockAlarm:clockAlarm1WakeupMinute`, `clockAlarm:clockAlarm1BedtimeHour`, `clockAlarm:clockAlarm1BedtimeMinute`, `clockAlarm:clockAlarm2Enabled`, `clockAlarm:clockAlarm2Type`, `clockAlarm:clockAlarm2WakeupHour`, `clockAlarm:clockAlarm2WakeupMinute`, `clockAlarm:clockAlarm2BedtimeHour` and `clockAlarm:clockAlarm2BedtimeMinute`.
-Thing types `vmbel1`, `vmbel2`, `vmbel4`, `vmbelpir`, `vmbgp1`, `vmbgp2`, `vmbgp4` and `vmbgp4pir` also have a number of channels to set the module's thermostat (`thermostat:currentTemperatureSetpoint`, `thermostat:heatingModeComfortTemperatureSetpoint`, `thermostat:heatingModeDayTemperatureSetpoint`, `thermostat:heatingModeNightTemperatureSetpoint`, `thermostat:heatingModeAntiFrostTemperatureSetpoint`, `thermostat:coolingModeComfortTemperatureSetpoint`, `thermostat:coolingModeDayTemperatureSetpoint`, `thermostat:coolingModeNightTemperatureSetpoint`, `thermostat:coolingModeSafeTemperatureSetpoint`, `operatingMode` and `thermostat:mode`) and thermostat trigger channels: `thermostat:heater`, `thermostat:boost`, `thermostat:pump`, `thermostat:cooler`, `thermostat:alarm1`, `thermostat:alarm2`, `thermostat:alarm3`, `thermostat:alarm4`.
-
-Thing types `vmbelo`, `vmbgpo` and `vmbgpod` have 32 trigger channels `input:CH1` ... `input:CH32` and one temperature channel `input:CH33`.
+Pressed and Long_Pressed command types are supported on channels `button#CH1` ... `button#CH4` for the thing type `vmbel4pir-20`.
+Pressed and Long_Pressed command types are supported on channels `button#CH1` ... `button#CH8` for the thing types `vmbel1`, `vmbel1-20`, `vmbel2`, `vmbel2-20`, `vmbel4`, `vmbel4-20`, `vmbgp1`, `vmbgp2`, `vmbgp4`, `vmbgp4pir`, `vmbgp4pir-20` and `vmbpiro`.
+The thing types `vmbel1`, `vmbel1-20` and `vmbgp1` have one channel to steer the button LED feedback `feedback#CH1`.
+The thing types `vmbel2`, `vmbel2-20` and `vmbgp2` have two channels to steer the button LED feedback `feedback#CH1` and `feedback#CH2`.
+The thing types `vmbel4`, `vmbel4-20`, `vmbel4pir-20`, `vmbgp4`, `vmbgp4pir` and `vmbgp4pir-20` have four channels to steer the button LED feedback `feedback#CH1` ... `feedback#CH4`.
+The thing type `vmbpiro` has a channel `input#LIGHT` indicating the illuminance.
+The thing types `vmbel1`, `vmbel1-20`, `vmbel2`, `vmbel2-20`, `vmbel4`, `vmbel4-20`, `vmbelpir` and `vmbel4pir-20` have one output channel `output#output`.
+Thing types `vmbel1`, `vmbel1-20`, `vmbel2`, `vmbel2-20`, `vmbel4`, `vmbel4-20`, `vmbelpir`, `vmbel4pir-20`, `vmbgp1`, `vmbgp2`, `vmbgp4`, `vmbgp4pir` and `vmbgp4pir-20` have a number of channels to set the module's alarms: `clockAlarm#clockAlarm1Enabled`,  `clockAlarm#clockAlarm1WakeupHour`, `clockAlarm#clockAlarm1WakeupMinute`, `clockAlarm#clockAlarm1BedtimeHour`, `clockAlarm#clockAlarm1BedtimeMinute`, `clockAlarm#clockAlarm2Enabled`,  `clockAlarm#clockAlarm2WakeupHour`, `clockAlarm#clockAlarm2WakeupMinute`, `clockAlarm#clockAlarm2BedtimeHour` and `clockAlarm#clockAlarm2BedtimeMinute`.
+Thing types `vmbel1`, `vmbel1-20`, `vmbel2`, `vmbel2-20`, `vmbel4`, `vmbel4-20`, `vmbelpir`, `vmbel4pir-20`, `vmbgp1`, `vmbgp2`, `vmbgp4`, `vmbgp4pir` and `vmbgp4pir-20` also have a number of channels to set the module's thermostat (`thermostat#currentTemperatureSetpoint`, `thermostat#heatingModeComfortTemperatureSetpoint`, `thermostat#heatingModeDayTemperatureSetpoint`, `thermostat#heatingModeNightTemperatureSetpoint`, `thermostat#heatingModeAntiFrostTemperatureSetpoint`, `thermostat#coolingModeComfortTemperatureSetpoint`, `thermostat#coolingModeDayTemperatureSetpoint`, `thermostat#coolingModeNightTemperatureSetpoint`, `thermostat#coolingModeSafeTemperatureSetpoint`, `operatingMode` and `thermostat#mode`) and thermostat trigger channels: `thermostat#heater`, `thermostat#boost`, `thermostat#pump`, `thermostat#cooler`, `thermostat#alarm1`, `thermostat#alarm2`, `thermostat#alarm3`, `thermostat#alarm4`.
+
+Thing types `vmbelo`, `vmbelo-20`, `vmbgpo`, `vmbgpo-20`, `vmbgpod` and `vmbgpod-2` have 32 trigger channels `input#CH1` ... `input#CH32` and one temperature channel `input#CH33`.
 Pressed and Long_Pressed command types are supported on channels `button#CH1` ... `button#CH32`.
-They have have 32 channels to steer the button LED feedback `feedback:CH1` ... `feedback:CH32`.
-They have a number of channels to set the module's alarms: `clockAlarm:clockAlarm1Enabled`, `clockAlarm:clockAlarm1Type`, `clockAlarm:clockAlarm1WakeupHour`, `clockAlarm:clockAlarm1WakeupMinute`, `clockAlarm:clockAlarm1BedtimeHour`, `clockAlarm:clockAlarm1BedtimeMinute`, `clockAlarm:clockAlarm2Enabled`, `clockAlarm:clockAlarm2Type`, `clockAlarm:clockAlarm2WakeupHour`, `clockAlarm:clockAlarm2WakeupMinute`, `clockAlarm:clockAlarm2BedtimeHour` and `clockAlarm:clockAlarm2BedtimeMinute`.
-They have a number of channels to set the module's thermostat thermostat (`thermostat:currentTemperatureSetpoint`, `thermostat:heatingModeComfortTemperatureSetpoint`, `thermostat:heatingModeDayTemperatureSetpoint`, `thermostat:heatingModeNightTemperatureSetpoint`, `thermostat:heatingModeAntiFrostTemperatureSetpoint`, `thermostat:coolingModeComfortTemperatureSetpoint`, `thermostat:coolingModeDayTemperatureSetpoint`, `thermostat:coolingModeNightTemperatureSetpoint`, `thermostat:coolingModeSafeTemperatureSetpoint`, `operatingMode` and `thermostat:mode`) and thermostat trigger channels: `thermostat:heater`, `thermostat:boost`, `thermostat:pump`, `thermostat:cooler`, `thermostat:alarm1`, `thermostat:alarm2`, `thermostat:alarm3`, `thermostat:alarm4`.
+They have have 32 channels to steer the button LED feedback `feedback#CH1` ... `feedback#CH32`.
+The thing type `vmbelo` and `vmbelo-20` have one output channel `output#output`.
+They have a number of channels to set the module's alarms: `clockAlarm#clockAlarm1Enabled`,  `clockAlarm#clockAlarm1WakeupHour`, `clockAlarm#clockAlarm1WakeupMinute`, `clockAlarm#clockAlarm1BedtimeHour`, `clockAlarm#clockAlarm1BedtimeMinute`, `clockAlarm#clockAlarm2Enabled`,  `clockAlarm#clockAlarm2WakeupHour`, `clockAlarm#clockAlarm2WakeupMinute`, `clockAlarm#clockAlarm2BedtimeHour` and `clockAlarm#clockAlarm2BedtimeMinute`.
+They have a number of channels to set the module's thermostat thermostat (`thermostat#currentTemperatureSetpoint`, `thermostat#heatingModeComfortTemperatureSetpoint`, `thermostat#heatingModeDayTemperatureSetpoint`, `thermostat#heatingModeNightTemperatureSetpoint`, `thermostat#heatingModeAntiFrostTemperatureSetpoint`, `thermostat#coolingModeComfortTemperatureSetpoint`, `thermostat#coolingModeDayTemperatureSetpoint`, `thermostat#coolingModeNightTemperatureSetpoint`, `thermostat#coolingModeSafeTemperatureSetpoint`, `operatingMode` and `thermostat#mode`) and thermostat trigger channels: `thermostat#heater`, `thermostat#boost`, `thermostat#pump`, `thermostat#cooler`, `thermostat#alarm1`, `thermostat#alarm2`, `thermostat#alarm3`, `thermostat#alarm4`.
 They also have two channels to control the module's display `oledDisplay:MEMO` and `oledDisplay:SCREENSAVER`.
 
-Thing type `vmbmeteo`has 8 trigger channels (`input:CH1` ... `input:CH8`). These channels will be triggered by the module's alarms.
-It has a number of channels to set the module's alarms: `clockAlarm:clockAlarm1Enabled`, `clockAlarm:clockAlarm1Type`, `clockAlarm:clockAlarm1WakeupHour`, `clockAlarm:clockAlarm1WakeupMinute`, `clockAlarm:clockAlarm1BedtimeHour`, `clockAlarm:clockAlarm1BedtimeMinute`, `clockAlarm:clockAlarm2Enabled`, `clockAlarm:clockAlarm2Type`, `clockAlarm:clockAlarm2WakeupHour`, `clockAlarm:clockAlarm2WakeupMinute`, `clockAlarm:clockAlarm2BedtimeHour` and `clockAlarm:clockAlarm2BedtimeMinute`.
+Thing type `vmbmeteo`has 8 trigger channels (`input#CH1` ... `input#CH8`). These channels will be triggered by the module's alarms.
+It has a number of channels to set the module's alarms: `clockAlarm#clockAlarm1Enabled`,  `clockAlarm#clockAlarm1WakeupHour`, `clockAlarm#clockAlarm1WakeupMinute`, `clockAlarm#clockAlarm1BedtimeHour`, `clockAlarm#clockAlarm1BedtimeMinute`, `clockAlarm#clockAlarm2Enabled`,  `clockAlarm#clockAlarm2WakeupHour`, `clockAlarm#clockAlarm2WakeupMinute`, `clockAlarm#clockAlarm2BedtimeHour` and `clockAlarm#clockAlarm2BedtimeMinute`.
 It also has a number of channels to read out the weather station's sensors: `weatherStation:temperature`, `weatherStation:rainfall`, `weatherStation:illuminance` and `weatherStation:windspeed`.
 
-Thing types `vmbpirc` and `vmbpirm` have 7 trigger channels `input:CH1` ... `input:CH7`.
-Additionally, these modules have a number of channels to set the module's alarms: `clockAlarm:clockAlarm1Enabled`, `clockAlarm:clockAlarm1Type`, `clockAlarm:clockAlarm1WakeupHour`, `clockAlarm:clockAlarm1WakeupMinute`, `clockAlarm:clockAlarm1BedtimeHour`, `clockAlarm:clockAlarm1BedtimeMinute`, `clockAlarm:clockAlarm2Enabled`, `clockAlarm:clockAlarm2Type`, `clockAlarm:clockAlarm2WakeupHour`, `clockAlarm:clockAlarm2WakeupMinute`, `clockAlarm:clockAlarm2BedtimeHour` and `clockAlarm:clockAlarm2BedtimeMinute`.
+Thing types `vmbpirc` and `vmbpirm` have 7 trigger channels `input#CH1` ... `input#CH7`.
+Additionally, these modules have a number of channels to set the module's alarms: `clockAlarm#clockAlarm1Enabled`,  `clockAlarm#clockAlarm1WakeupHour`, `clockAlarm#clockAlarm1WakeupMinute`, `clockAlarm#clockAlarm1BedtimeHour`, `clockAlarm#clockAlarm1BedtimeMinute`, `clockAlarm#clockAlarm2Enabled`,  `clockAlarm#clockAlarm2WakeupHour`, `clockAlarm#clockAlarm2WakeupMinute`, `clockAlarm#clockAlarm2BedtimeHour` and `clockAlarm#clockAlarm2BedtimeMinute`.
+
+Thing types `vmbdali` and `vmbdali-20` have 81 trigger channels `input#CH1` ... `input#CH81`.
+They have 81 channels to steer the button LED feedback `feedback#CH1` ... `feedback#CH81`.
+hsbColor command type is supported on channels `color#CH1` ... `color#CH64` (A1 ... A64), `color#CH65` ... `color#CH80` (G1 ... G16) and `color#CH81` (broadcast). This is to set the color on the channels.
+Percent command type is supported on channels `brightness#CH1` ... `brightness#CH64` (A1 ... A64), `brightness#CH65` ... `brightness#CH80` (G1 ... G16) and `brightness#CH81` (broadcast). This is to set the brightness on the channels.
+Percent command type is supported on channels `white#CH1` ... `white#CH64` (A1 ... A64), `white#CH65` ... `white#CH80` (G1 ... G16) and `white#CH81` (broadcast). This is to set the white on the channels.
+Values 1 to 15 are supported on channels `scene#CH1` ... `scene#CH64` (A1 ... A64), `scene#CH65` ... `scene#CH80` (G1 ... G16) and `scene#CH81` (broadcast). This is to set the scene on the channels.
+hsbColor command type is supported on channels `virtual-light#VL1` ... `virtual-light#VL16`. This is to set the color on the virtual light.
+They have a number of channels to set the module's alarms: `clockAlarm#clockAlarm1Enabled`,  `clockAlarm#clockAlarm1WakeupHour`, `clockAlarm#clockAlarm1WakeupMinute`, `clockAlarm#clockAlarm1BedtimeHour`, `clockAlarm#clockAlarm1BedtimeMinute`, `clockAlarm#clockAlarm2Enabled`,  `clockAlarm#clockAlarm2WakeupHour`, `clockAlarm#clockAlarm2WakeupMinute`, `clockAlarm#clockAlarm2BedtimeHour` and `clockAlarm#clockAlarm2BedtimeMinute`.
 
 The trigger channels can be used as a trigger to rules. The event message can be `PRESSED`, `RELEASED`or `LONG_PRESSED`.
 
@@ -386,7 +434,7 @@ Example trigger rule:
 ```java
 rule "example trigger rule"
 when
-    Channel 'velbus:vmb7in:1:05:CH5' triggered PRESSED
+    Channel 'velbus:vmb7in:1:05:input#CH5' triggered PRESSED
 then
     var message = receivedEvent.getEvent()
     logInfo("velbusTriggerExample", "Message: {}", message)
index b9a8bd870654839e39563b3e21a126342594122e..6504119e2c03f30aa5fabd580adc4537b6443c79 100644 (file)
@@ -84,6 +84,22 @@ public class VelbusBindingConstants {
     public static final ThingTypeUID THING_TYPE_VMBKP = new ThingTypeUID(BINDING_ID, "vmbkp");
     public static final ThingTypeUID THING_TYPE_VMBIN = new ThingTypeUID(BINDING_ID, "vmbin");
     public static final ThingTypeUID THING_TYPE_VMB4PB = new ThingTypeUID(BINDING_ID, "vmb4pb");
+    public static final ThingTypeUID THING_TYPE_VMBDALI = new ThingTypeUID(BINDING_ID, "vmbdali");
+    public static final ThingTypeUID THING_TYPE_VMB4RYLD_10 = new ThingTypeUID(BINDING_ID, "vmb4ryld-10");
+    public static final ThingTypeUID THING_TYPE_VMB4RYNO_10 = new ThingTypeUID(BINDING_ID, "vmb4ryno-10");
+    public static final ThingTypeUID THING_TYPE_VMB2BLE_10 = new ThingTypeUID(BINDING_ID, "vmb2ble-10");
+    public static final ThingTypeUID THING_TYPE_VMB6PB_20 = new ThingTypeUID(BINDING_ID, "vmb6pb-20");
+    public static final ThingTypeUID THING_TYPE_VMBEL1_20 = new ThingTypeUID(BINDING_ID, "vmbel1-20");
+    public static final ThingTypeUID THING_TYPE_VMBEL2_20 = new ThingTypeUID(BINDING_ID, "vmbel2-20");
+    public static final ThingTypeUID THING_TYPE_VMBEL4_20 = new ThingTypeUID(BINDING_ID, "vmbel4-20");
+    public static final ThingTypeUID THING_TYPE_VMBELO_20 = new ThingTypeUID(BINDING_ID, "vmbelo-20");
+    public static final ThingTypeUID THING_TYPE_VMBGP1_20 = new ThingTypeUID(BINDING_ID, "vmbgp1-20");
+    public static final ThingTypeUID THING_TYPE_VMBGP2_20 = new ThingTypeUID(BINDING_ID, "vmbgp2-20");
+    public static final ThingTypeUID THING_TYPE_VMBGP4_20 = new ThingTypeUID(BINDING_ID, "vmbgp4-20");
+    public static final ThingTypeUID THING_TYPE_VMBGPO_20 = new ThingTypeUID(BINDING_ID, "vmbgpo-20");
+    public static final ThingTypeUID THING_TYPE_VMBDALI_20 = new ThingTypeUID(BINDING_ID, "vmbdali-20");
+    public static final ThingTypeUID THING_TYPE_VMBEL4PIR_20 = new ThingTypeUID(BINDING_ID, "vmbel4pir-20");
+    public static final ThingTypeUID THING_TYPE_VMBGP4PIR_20 = new ThingTypeUID(BINDING_ID, "vmbgp4pir-20");
 
     // thing type sets
     public static final Set<ThingTypeUID> BRIDGE_THING_TYPES_UIDS = Set.of(BRIDGE_THING_TYPE,
@@ -98,7 +114,11 @@ public class VelbusBindingConstants {
             THING_TYPE_VMBGP1_2, THING_TYPE_VMBGP2, THING_TYPE_VMBGP2_2, THING_TYPE_VMBGP4, THING_TYPE_VMBGP4_2,
             THING_TYPE_VMBGP4PIR, THING_TYPE_VMBGP4PIR_2, THING_TYPE_VMBGPO, THING_TYPE_VMBGPOD, THING_TYPE_VMBGPOD_2,
             THING_TYPE_VMBMETEO, THING_TYPE_VMBPIRC, THING_TYPE_VMBPIRM, THING_TYPE_VMBPIRO, THING_TYPE_VMBRFR8S,
-            THING_TYPE_VMBVP1, THING_TYPE_VMBKP, THING_TYPE_VMBIN, THING_TYPE_VMB4PB);
+            THING_TYPE_VMBVP1, THING_TYPE_VMBKP, THING_TYPE_VMBIN, THING_TYPE_VMB4PB, THING_TYPE_VMBDALI,
+            THING_TYPE_VMB4RYLD_10, THING_TYPE_VMB4RYNO_10, THING_TYPE_VMB2BLE_10, THING_TYPE_VMB6PB_20,
+            THING_TYPE_VMBEL1_20, THING_TYPE_VMBEL2_20, THING_TYPE_VMBEL4_20, THING_TYPE_VMBELO_20,
+            THING_TYPE_VMBGP1_20, THING_TYPE_VMBGP2_20, THING_TYPE_VMBGP4_20, THING_TYPE_VMBGPO_20,
+            THING_TYPE_VMBDALI_20, THING_TYPE_VMBEL4PIR_20, THING_TYPE_VMBGP4PIR_20);
 
     // Velbus module types
     public static final byte MODULE_TYPE_VMB8PB = 0x01;
@@ -114,6 +134,7 @@ public class VelbusBindingConstants {
     public static final byte MODULE_TYPE_VMB4RYLD = 0x10;
     public static final byte MODULE_TYPE_VMB4RYNO = 0x11;
     public static final byte MODULE_TYPE_VMB4DC = 0x12;
+    public static final byte MODULE_TYPE_VMBLCDWB = 0x13;
     public static final byte MODULE_TYPE_VMBDME = 0x14;
     public static final byte MODULE_TYPE_VMBDMI = 0x15;
     public static final byte MODULE_TYPE_VMB8PBU = 0x16;
@@ -152,6 +173,22 @@ public class VelbusBindingConstants {
     public static final byte MODULE_TYPE_VMBKP = 0x42;
     public static final byte MODULE_TYPE_VMBIN = 0x43;
     public static final byte MODULE_TYPE_VMB4PB = 0x44;
+    public static final byte MODULE_TYPE_VMBDALI = 0x45;
+    public static final byte MODULE_TYPE_VMB4RYLD_10 = 0x48;
+    public static final byte MODULE_TYPE_VMB4RYNO_10 = 0x49;
+    public static final byte MODULE_TYPE_VMB2BLE_10 = 0x4A;
+    public static final byte MODULE_TYPE_VMB6PB_20 = 0x4C;
+    public static final byte MODULE_TYPE_VMBEL1_20 = 0x4F;
+    public static final byte MODULE_TYPE_VMBEL2_20 = 0x50;
+    public static final byte MODULE_TYPE_VMBEL4_20 = 0x51;
+    public static final byte MODULE_TYPE_VMBELO_20 = 0x52;
+    public static final byte MODULE_TYPE_VMBGP1_20 = 0x54;
+    public static final byte MODULE_TYPE_VMBGP2_20 = 0x55;
+    public static final byte MODULE_TYPE_VMBGP4_20 = 0x56;
+    public static final byte MODULE_TYPE_VMBGPO_20 = 0x57;
+    public static final byte MODULE_TYPE_VMBDALI_20 = 0x5A;
+    public static final byte MODULE_TYPE_VMBEL4PIR_20 = 0x5C;
+    public static final byte MODULE_TYPE_VMBGP4PIR_20 = 0x5F;
 
     // Velbus commands
     public static final byte COMMAND_PUSH_BUTTON_STATUS = 0x00;
@@ -161,11 +198,24 @@ public class VelbusBindingConstants {
     public static final byte COMMAND_BLIND_UP = 0x05;
     public static final byte COMMAND_BLIND_DOWN = 0x06;
     public static final byte COMMAND_SET_VALUE = 0x07;
+    public static final byte COMMAND_SET_DIMVALUE = 0x07;
     public static final byte COMMAND_SLIDER_STATUS = 0x0F;
     public static final byte COMMAND_RESTORE_LAST_DIMVALUE = 0x11;
+    public static final byte COMMAND_FORCED_OFF = 0x12;
+    public static final byte COMMAND_CANCEL_FORCED_OFF = 0x13;
+    public static final byte COMMAND_FORCED_ON = 0x14;
+    public static final byte COMMAND_CANCEL_FORCED_ON = 0x15;
+    public static final byte COMMAND_INHIBIT = 0x16;
+    public static final byte COMMAND_CANCEL_INHIBIT = 0x17;
     public static final byte COMMAND_BLIND_POS = 0x1C;
+    public static final byte COMMAND_SET_DIMSCENE = (byte) 0x1D;
+    public static final byte COMMAND_SET_COLOR = (byte) 0x1E;
+    public static final byte COMMAND_DIMVALUE_STATUS = (byte) 0xA5;
+    public static final byte COMMAND_SUBTYPE_3 = (byte) 0xA6;
+    public static final byte COMMAND_SUBTYPE_2 = (byte) 0xA7;
     public static final byte COMMAND_SENSOR_RAW_DATA = (byte) 0xA9;
     public static final byte COMMAND_LIGHT_VALUE_REQUEST = (byte) 0xAA;
+    public static final byte COMMAND_POWER_UP = (byte) 0xAB;
     public static final byte COMMAND_TEXT = (byte) 0xAC;
     public static final byte COMMAND_DAYLIGHT_SAVING_STATUS = (byte) 0xAF;
     public static final byte COMMAND_SUBTYPE = (byte) 0xB0;
@@ -210,7 +260,14 @@ public class VelbusBindingConstants {
     public static final byte COMMAND_READ_DATA_FROM_MEMORY = (byte) 0xFD;
     public static final byte COMMAND_MEMORY_DATA = (byte) 0xFE;
     public static final byte COMMAND_MODULE_TYPE = (byte) 0xFF;
+
+    // Useful values
     public static final byte ALL_CHANNELS = (byte) 0xFF;
+    public static final byte ALL_DALI_CHANNELS = (byte) 0x51;
+    public static final byte SUB_ADDRESS_DISABLED = (byte) 0xFF;
+    public static final byte VALUE_UNCHANGED = (byte) 0xFF;
+    public static final byte DALI_SETTING_ACTUAL_LEVEL = (byte) 0x1A;
+    public static final byte DALI_MAX_VALUE = (byte) 0xFE;
 
     // Module properties
     public static final String PORT = "port";
@@ -226,32 +283,60 @@ public class VelbusBindingConstants {
     public static final String MODULE_MEMORY_MAP_VERSION = "memory map version";
     public static final String MODULE_BUILD = "build";
     public static final String CHANNEL = "CH";
+    public static final String DALI_ADDRESS = "A";
+    public static final String VIRTUAL_LIGHT = "VL";
     public static final String SUB_ADDRESS = "subaddress";
     public static final String DIMSPEED = "dimspeed";
 
+    // Channel group ids
+    public static final String CHANNEL_GROUP_BRIDGE_CLOCK_ALARM = "bridgeClockAlarm";
+    public static final String CHANNEL_GROUP_MODULE_CLOCK_ALARM = "clockAlarm";
+    public static final String CHANNEL_GROUP_INPUT = "input";
+    public static final String CHANNEL_GROUP_FEEDBACK = "feedback";
+    public static final String CHANNEL_GROUP_BUTTON = "button";
+    public static final String CHANNEL_GROUP_OUTPUT = "output";
+    public static final String CHANNEL_GROUP_THERMOSTAT = "thermostat";
+    public static final String CHANNEL_GROUP_COLOR = "color";
+    public static final String CHANNEL_GROUP_BRIGHTNESS = "brightness";
+    public static final String CHANNEL_GROUP_WHITE = "white";
+    public static final String CHANNEL_GROUP_SCENE = "scene";
+    public static final String CHANNEL_GROUP_VIRTUAL_LIGHT = "virtual-light";
+
     // Channels ids
-    public static final String CHANNEL_BRIDGE_CLOCK_ALARM1_ENABLED = "bridgeClockAlarm#clockAlarm1Enabled";
-    public static final String CHANNEL_BRIDGE_CLOCK_ALARM1_WAKEUP_HOUR = "bridgeClockAlarm#clockAlarm1WakeupHour";
-    public static final String CHANNEL_BRIDGE_CLOCK_ALARM1_WAKEUP_MINUTE = "bridgeClockAlarm#clockAlarm1WakeupMinute";
-    public static final String CHANNEL_BRIDGE_CLOCK_ALARM1_BEDTIME_HOUR = "bridgeClockAlarm#clockAlarm1BedtimeHour";
-    public static final String CHANNEL_BRIDGE_CLOCK_ALARM1_BEDTIME_MINUTE = "bridgeClockAlarm#clockAlarm1BedtimeMinute";
-    public static final String CHANNEL_BRIDGE_CLOCK_ALARM2_ENABLED = "bridgeClockAlarm#clockAlarm2Enabled";
-    public static final String CHANNEL_BRIDGE_CLOCK_ALARM2_WAKEUP_HOUR = "bridgeClockAlarm#clockAlarm2WakeupHour";
-    public static final String CHANNEL_BRIDGE_CLOCK_ALARM2_WAKEUP_MINUTE = "bridgeClockAlarm#clockAlarm2WakeupMinute";
-    public static final String CHANNEL_BRIDGE_CLOCK_ALARM2_BEDTIME_HOUR = "bridgeClockAlarm#clockAlarm2BedtimeHour";
-    public static final String CHANNEL_BRIDGE_CLOCK_ALARM2_BEDTIME_MINUTE = "bridgeClockAlarm#clockAlarm2BedtimeMinute";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM1_ENABLED = "clockAlarm#clockAlarm1Enabled";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM1_TYPE = "clockAlarm#clockAlarm1Type";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM1_WAKEUP_HOUR = "clockAlarm#clockAlarm1WakeupHour";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM1_WAKEUP_MINUTE = "clockAlarm#clockAlarm1WakeupMinute";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM1_BEDTIME_HOUR = "clockAlarm#clockAlarm1BedtimeHour";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM1_BEDTIME_MINUTE = "clockAlarm#clockAlarm1BedtimeMinute";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM2_ENABLED = "clockAlarm#clockAlarm2Enabled";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM2_TYPE = "clockAlarm#clockAlarm2Type";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM2_WAKEUP_HOUR = "clockAlarm#clockAlarm2WakeupHour";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM2_WAKEUP_MINUTE = "clockAlarm#clockAlarm2WakeupMinute";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM2_BEDTIME_HOUR = "clockAlarm#clockAlarm2BedtimeHour";
-    public static final String CHANNEL_MODULE_CLOCK_ALARM2_BEDTIME_MINUTE = "clockAlarm#clockAlarm2BedtimeMinute";
+    public static final String CHANNEL_CLOCK_ALARM1_TYPE = "clockAlarm1Type";
+    public static final String CHANNEL_CLOCK_ALARM1_ENABLED = "clockAlarm1Enabled";
+    public static final String CHANNEL_CLOCK_ALARM1_WAKEUP_HOUR = "clockAlarm1WakeupHour";
+    public static final String CHANNEL_CLOCK_ALARM1_WAKEUP_MINUTE = "clockAlarm1WakeupMinute";
+    public static final String CHANNEL_CLOCK_ALARM1_BEDTIME_HOUR = "clockAlarm1BedtimeHour";
+    public static final String CHANNEL_CLOCK_ALARM1_BEDTIME_MINUTE = "clockAlarm1BedtimeMinute";
+    public static final String CHANNEL_CLOCK_ALARM2_TYPE = "clockAlarm2Type";
+    public static final String CHANNEL_CLOCK_ALARM2_ENABLED = "clockAlarm2Enabled";
+    public static final String CHANNEL_CLOCK_ALARM2_WAKEUP_HOUR = "clockAlarm2WakeupHour";
+    public static final String CHANNEL_CLOCK_ALARM2_WAKEUP_MINUTE = "clockAlarm2WakeupMinute";
+    public static final String CHANNEL_CLOCK_ALARM2_BEDTIME_HOUR = "clockAlarm2BedtimeHour";
+    public static final String CHANNEL_CLOCK_ALARM2_BEDTIME_MINUTE = "clockAlarm2BedtimeMinute";
+
+    public static final String CHANNEL_THERMOSTAT_CURRENT_TEMPERATURE = "currentTemperatureSetpoint";
+    public static final String CHANNEL_THERMOSTAT_HEATING_COMFORT = "heatingModeComfortTemperatureSetpoint";
+    public static final String CHANNEL_THERMOSTAT_HEATING_DAY = "heatingModeDayTemperatureSetpoint";
+    public static final String CHANNEL_THERMOSTAT_HEATING_NIGHT = "heatingModeNightTemperatureSetpoint";
+    public static final String CHANNEL_THERMOSTAT_HEATING_ANTI_FROST = "heatingModeAntiFrostTemperatureSetpoint";
+    public static final String CHANNEL_THERMOSTAT_COOLING_COMFORT = "coolingModeComfortTemperatureSetpoint";
+    public static final String CHANNEL_THERMOSTAT_COOLING_DAY = "coolingModeDayTemperatureSetpoint";
+    public static final String CHANNEL_THERMOSTAT_COOLING_NIGHT = "coolingModeNightTemperatureSetpoint";
+    public static final String CHANNEL_THERMOSTAT_COOLING_SAFE = "coolingModeSafeTemperatureSetpoint";
+    public static final String CHANNEL_THERMOSTAT_OPERATING_MODE = "operatingMode";
+    public static final String CHANNEL_THERMOSTAT_MODE = "mode";
+    public static final String CHANNEL_THERMOSTAT_HEATER = "heater";
+    public static final String CHANNEL_THERMOSTAT_BOOST = "boost";
+    public static final String CHANNEL_THERMOSTAT_PUMP = "pump";
+    public static final String CHANNEL_THERMOSTAT_COOLER = "cooler";
+    public static final String CHANNEL_THERMOSTAT_ALARM1 = "alarm1";
+    public static final String CHANNEL_THERMOSTAT_ALARM2 = "alarm2";
+    public static final String CHANNEL_THERMOSTAT_ALARM3 = "alarm3";
+    public static final String CHANNEL_THERMOSTAT_ALARM4 = "alarm4";
+
+    public static final String CHANNEL_OUTPUT = "output";
 
     // Delay
     public static final Integer DELAY_SEND_CLOCK_ALARM_UPDATE = 10000;
diff --git a/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/VelbusColorChannel.java b/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/VelbusColorChannel.java
new file mode 100644 (file)
index 0000000..8af7148
--- /dev/null
@@ -0,0 +1,263 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.velbus.internal;
+
+import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.library.types.HSBType;
+import org.openhab.core.library.types.PercentType;
+import org.openhab.core.util.ColorUtil;
+
+/**
+ * The {@link VelbusDALIConverter} represents a class with properties that manage DALI color channel.
+ *
+ * @author Daniel Rosengarten - Initial contribution
+ */
+@NonNullByDefault
+public class VelbusColorChannel {
+    protected final int BRIGHTNESS_MIN_VALUE = 0;
+    protected final int BRIGHTNESS_MAX_VALUE = 100;
+
+    protected final int COLOR_MIN_VALUE = 0;
+    protected final int COLOR_MAX_VALUE = 255;
+
+    protected final int WHITE_MIN_VALUE = 0;
+    protected final int WHITE_MAX_VALUE = 100;
+
+    private int brightness = 100;
+    private int[] color = { 255, 255, 255 };
+    private int white = 100;
+
+    /**
+     * @param brightness the brightness to set
+     */
+    public void setBrightness(int brightness) {
+        this.brightness = (brightness < BRIGHTNESS_MIN_VALUE) ? BRIGHTNESS_MIN_VALUE : brightness;
+        this.brightness = (brightness > BRIGHTNESS_MAX_VALUE) ? BRIGHTNESS_MAX_VALUE : brightness;
+    }
+
+    /**
+     * @param brightnessState the brightness to set
+     */
+    public void setBrightness(PercentType brightnessState) {
+        setBrightness(brightnessState.intValue());
+    }
+
+    /**
+     * @param brightnessState the brightness to set
+     */
+    public void setBrightness(HSBType brightnessState) {
+        setBrightness(brightnessState.getBrightness());
+    }
+
+    /**
+     * @param brightness the brightness to set from velbus packet
+     */
+    public void setBrightness(byte brightness) {
+        if (brightness != VALUE_UNCHANGED) {
+            this.brightness = convertFromVelbus(Byte.toUnsignedInt(brightness), Byte.toUnsignedInt(DALI_MAX_VALUE),
+                    BRIGHTNESS_MAX_VALUE);
+        }
+    }
+
+    /**
+     * @return the brightness
+     */
+    public int getBrightness() {
+        return this.brightness;
+    }
+
+    /**
+     * @return the brightness in PercentType format
+     */
+    public PercentType getBrightnessPercent() {
+        return new PercentType(getBrightness());
+    }
+
+    /**
+     * @return the brightness for velbus packet
+     */
+    public byte getBrightnessVelbus() {
+        return convertToVelbus(this.brightness, BRIGHTNESS_MAX_VALUE, Byte.toUnsignedInt(DALI_MAX_VALUE));
+    }
+
+    /**
+     * @param rgb the color to set in RGB
+     */
+    public void setColor(int[] rgb) {
+        if (rgb.length == 3) {
+            this.color[0] = (rgb[0] < COLOR_MIN_VALUE) ? COLOR_MIN_VALUE : rgb[0];
+            this.color[0] = (rgb[0] > COLOR_MAX_VALUE) ? COLOR_MAX_VALUE : rgb[0];
+            this.color[1] = (rgb[1] < COLOR_MIN_VALUE) ? COLOR_MIN_VALUE : rgb[1];
+            this.color[1] = (rgb[1] > COLOR_MAX_VALUE) ? COLOR_MAX_VALUE : rgb[1];
+            this.color[2] = (rgb[2] < COLOR_MIN_VALUE) ? COLOR_MIN_VALUE : rgb[2];
+            this.color[2] = (rgb[2] > COLOR_MAX_VALUE) ? COLOR_MAX_VALUE : rgb[2];
+        }
+    }
+
+    /**
+     * @param hsbState the color to set in HSB
+     */
+    public void setColor(HSBType hsbState) {
+        setColor(ColorUtil.hsbToRgb(hsbState));
+    }
+
+    /**
+     * @param rgb the color to set in RGB from velbus packet
+     */
+    public void setColor(byte[] rgb) {
+        if (rgb.length == 3) {
+            if (rgb[0] != VALUE_UNCHANGED) {
+                this.color[0] = (rgb[0] == DALI_MAX_VALUE) ? COLOR_MAX_VALUE : Byte.toUnsignedInt(rgb[0]);
+            }
+            if (rgb[1] != VALUE_UNCHANGED) {
+                this.color[1] = (rgb[1] == DALI_MAX_VALUE) ? COLOR_MAX_VALUE : Byte.toUnsignedInt(rgb[1]);
+            }
+            if (rgb[2] != VALUE_UNCHANGED) {
+                this.color[2] = (rgb[2] == DALI_MAX_VALUE) ? COLOR_MAX_VALUE : Byte.toUnsignedInt(rgb[2]);
+            }
+        }
+    }
+
+    /**
+     * @param red the red value to set from velbus packet
+     */
+    public void setRedColor(byte red) {
+        if (red != VALUE_UNCHANGED) {
+            this.color[0] = convertFromVelbus(Byte.toUnsignedInt(red), DALI_MAX_VALUE, COLOR_MAX_VALUE);
+        }
+    }
+
+    /**
+     * @param green the green value to set from velbus packet
+     */
+    public void setGreenColor(byte green) {
+        if (green != VALUE_UNCHANGED) {
+            this.color[1] = convertFromVelbus(Byte.toUnsignedInt(green), DALI_MAX_VALUE, COLOR_MAX_VALUE);
+        }
+    }
+
+    /**
+     * @param blue the blue value to set from velbus packet
+     */
+    public void setBlueColor(byte blue) {
+        if (blue != VALUE_UNCHANGED) {
+            this.color[2] = convertFromVelbus(Byte.toUnsignedInt(blue), DALI_MAX_VALUE, COLOR_MAX_VALUE);
+        }
+    }
+
+    /**
+     * @return the color in RGB
+     */
+    public int[] getColor() {
+        return this.color;
+    }
+
+    /**
+     * @return the color in HSBType format
+     */
+    public HSBType getColorHSB() {
+        return ColorUtil.rgbToHsb(this.color);
+    }
+
+    /**
+     * @return the color for velbus packet
+     */
+    public byte[] getColorVelbus() {
+        byte[] rgb = { VALUE_UNCHANGED, VALUE_UNCHANGED, VALUE_UNCHANGED };
+
+        rgb[0] = convertToVelbus(this.color[0], COLOR_MAX_VALUE, DALI_MAX_VALUE);
+        rgb[1] = convertToVelbus(this.color[1], COLOR_MAX_VALUE, DALI_MAX_VALUE);
+        rgb[2] = convertToVelbus(this.color[2], COLOR_MAX_VALUE, DALI_MAX_VALUE);
+
+        return rgb;
+    }
+
+    /**
+     * @param white the white to set
+     */
+    public void setWhite(int white) {
+        this.white = (white < WHITE_MIN_VALUE) ? WHITE_MIN_VALUE : white;
+        this.white = (white > WHITE_MAX_VALUE) ? WHITE_MAX_VALUE : white;
+    }
+
+    /**
+     * @param whiteState the white to set
+     */
+    public void setWhite(PercentType whiteState) {
+        setWhite(whiteState.intValue());
+    }
+
+    /**
+     * @param white the white to set from velbus packet
+     */
+    public void setWhite(byte white) {
+        if (white != VALUE_UNCHANGED) {
+            this.white = convertFromVelbus(Byte.toUnsignedInt(white), Byte.toUnsignedInt(DALI_MAX_VALUE),
+                    WHITE_MAX_VALUE);
+        }
+    }
+
+    /**
+     * @return the white
+     */
+    public int getWhite() {
+        return this.white;
+    }
+
+    /**
+     * @return the white in PercentType format
+     */
+    public PercentType getWhitePercent() {
+        return new PercentType(this.white);
+    }
+
+    /**
+     * @return the white value for velbus packet
+     */
+    public byte getWhiteVelbus() {
+        return convertToVelbus(this.white, WHITE_MAX_VALUE, Byte.toUnsignedInt(DALI_MAX_VALUE));
+    }
+
+    /**
+     * @param value the value to rescale
+     * @param from_max the maximum value of the first parameter
+     * @param to_max the maximum value supported by the returned value
+     * @return the value rescaled
+     */
+    private int rescale(int value, int from_max, int to_max) {
+        return value * to_max / from_max;
+    }
+
+    /**
+     * @param value the value to convert
+     * @param from_max the maximum value of the first parameter
+     * @param to_max the maximum value supported by the Velbus module
+     * @return the value rescaled for the velbus packet
+     */
+    private byte convertToVelbus(int value, int from_max, int to_max) {
+        return (value >= from_max) ? Integer.valueOf(to_max).byteValue()
+                : Integer.valueOf(rescale(value, from_max, to_max)).byteValue();
+    }
+
+    /**
+     * @param value the value to convert
+     * @param from_max the maximum value supported by the Velbus module
+     * @param to_max the maximum value supported by the returned value
+     * @return the value rescaled from the packet
+     */
+    private int convertFromVelbus(int value, int from_max, int to_max) {
+        return (value >= from_max) ? to_max : rescale(value, from_max, to_max);
+    }
+}
index ba48a7f86293d2f37288f1d94f6fe7c041835830..bcbb9510afc3fb1e8e0221a5341d36f9340e0060 100644 (file)
@@ -28,6 +28,7 @@ import org.openhab.binding.velbus.internal.handler.VelbusSerialBridgeHandler;
 import org.openhab.binding.velbus.internal.handler.VelbusVMB1TSHandler;
 import org.openhab.binding.velbus.internal.handler.VelbusVMB4ANHandler;
 import org.openhab.binding.velbus.internal.handler.VelbusVMB7INHandler;
+import org.openhab.binding.velbus.internal.handler.VelbusVMBDALIHandler;
 import org.openhab.binding.velbus.internal.handler.VelbusVMBELHandler;
 import org.openhab.binding.velbus.internal.handler.VelbusVMBELOHandler;
 import org.openhab.binding.velbus.internal.handler.VelbusVMBGPHandler;
@@ -50,6 +51,7 @@ import org.osgi.service.component.annotations.Reference;
  * handlers.
  *
  * @author Cedric Boon - Initial contribution
+ * @author Daniel Rosengarten - Add VMB1RYS, VMBDALI
  */
 @NonNullByDefault
 @Component(service = ThingHandlerFactory.class, configurationPid = "binding.velbus")
@@ -106,6 +108,8 @@ public class VelbusHandlerFactory extends BaseThingHandlerFactory {
             thingHandler = new VelbusVMB4ANHandler(thing);
         } else if (VelbusVMB1TSHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
             thingHandler = new VelbusVMB1TSHandler(thing);
+        } else if (VelbusVMBDALIHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
+            thingHandler = new VelbusVMBDALIHandler(thing);
         }
 
         return thingHandler;
index 3e8d13979ad6eca4dec6e5761e6e7ec9d5ca7f40..9196738f8c8a335c1ddae022872a4c242d9b07fe 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.velbus.internal;
 
+import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -22,6 +24,7 @@ import org.openhab.core.thing.ChannelUID;
  * The {@link VelbusModuleAddress} represents the address and possible subaddresses of a Velbus module.
  *
  * @author Cedric Boon - Initial contribution
+ * @author Daniel Rosengarten - Review sub-addresses management
  */
 @NonNullByDefault
 public class VelbusModuleAddress {
@@ -45,6 +48,18 @@ public class VelbusModuleAddress {
         this.subAddresses = subAddresses;
     }
 
+    public void setSubAddresses(byte[] subAddresses, int subTypeNumber) {
+        int srcLength = subAddresses.length;
+        int destPos = srcLength * (subTypeNumber - 1);
+        int copyLength = srcLength - ((4 * subTypeNumber) - this.subAddresses.length);
+
+        if (copyLength > srcLength) {
+            copyLength = srcLength;
+        }
+
+        System.arraycopy(subAddresses, 0, this.subAddresses, destPos, copyLength);
+    }
+
     public byte[] getSubAddresses() {
         return subAddresses;
     }
@@ -68,6 +83,23 @@ public class VelbusModuleAddress {
         return result;
     }
 
+    public byte[] getAllAddresses() {
+        List<Byte> activeAddresses = new ArrayList<>();
+        activeAddresses.add(address);
+
+        for (int i = 0; i < subAddresses.length; i++) {
+            activeAddresses.add(subAddresses[i]);
+        }
+
+        byte[] result = new byte[activeAddresses.size()];
+
+        for (int i = 0; i < activeAddresses.size(); i++) {
+            result[i] = activeAddresses.get(i);
+        }
+
+        return result;
+    }
+
     public VelbusChannelIdentifier getChannelIdentifier(ChannelUID channelUID) {
         int channelIndex = getChannelIndex(channelUID);
 
@@ -83,7 +115,7 @@ public class VelbusModuleAddress {
     }
 
     public String getChannelId(VelbusChannelIdentifier velbusChannelIdentifier) {
-        return "CH" + getChannelNumber(velbusChannelIdentifier);
+        return CHANNEL + getChannelNumber(velbusChannelIdentifier);
     }
 
     public int getChannelIndex(VelbusChannelIdentifier velbusChannelIdentifier) {
@@ -91,10 +123,11 @@ public class VelbusModuleAddress {
     }
 
     public int getChannelNumber(VelbusChannelIdentifier velbusChannelIdentifier) {
-        byte[] activeAddresses = getActiveAddresses();
+        byte[] allAddresses = getAllAddresses();
 
-        for (int i = 0; i < activeAddresses.length; i++) {
-            if (velbusChannelIdentifier.getAddress() == activeAddresses[i]) {
+        for (int i = 0; i < allAddresses.length; i++) {
+            if ((allAddresses[i] != SUB_ADDRESS_DISABLED)
+                    && (velbusChannelIdentifier.getAddress() == allAddresses[i])) {
                 return (i * 8) + velbusChannelIdentifier.getChannelNumberFromBitNumber();
             }
         }
index 9ce91362ebc58b083832f66cc6046be2b2b638e1..0d1a0846fdd3a871560824530a8dc76482698d51 100644 (file)
@@ -26,6 +26,7 @@ public interface VelbusPacketListener {
      * This method is called whenever the state of the given relay has changed.
      *
      * @param packet The bytes of the received packet.
+     * @return false if handler is disposed, otherwise true.
      */
-    void onPacketReceived(byte[] packet);
+    boolean onPacketReceived(byte[] packet);
 }
diff --git a/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/VelbusVirtualColorChannel.java b/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/VelbusVirtualColorChannel.java
new file mode 100644 (file)
index 0000000..f910283
--- /dev/null
@@ -0,0 +1,170 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.velbus.internal;
+
+import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
+
+import java.util.InvalidPropertiesFormatException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link VelbusVirtualColorChannel} represents a class with properties that manage DALI virtual color channel.
+ *
+ * @author Daniel Rosengarten - Initial contribution
+ */
+@NonNullByDefault
+public class VelbusVirtualColorChannel extends VelbusColorChannel {
+    private final byte NOT_CONFIGURED = (byte) 0x00;
+
+    private byte redChannel;
+    private byte greenChannel;
+    private byte blueChannel;
+    private byte whiteChannel;
+
+    public VelbusVirtualColorChannel() {
+        redChannel = NOT_CONFIGURED;
+        greenChannel = NOT_CONFIGURED;
+        blueChannel = NOT_CONFIGURED;
+        whiteChannel = NOT_CONFIGURED;
+    }
+
+    public VelbusVirtualColorChannel(int r, int g, int b, int w) {
+        redChannel = getByteValue(r);
+        greenChannel = getByteValue(g);
+        blueChannel = getByteValue(b);
+        whiteChannel = getByteValue(w);
+    }
+
+    public VelbusVirtualColorChannel(String r, String g, String b, String w)
+            throws InvalidPropertiesFormatException, NumberFormatException {
+        String virtualChannel[] = r.split("^\\s*([a-zA-Z]*)(\\d+)?\\s*$");
+        redChannel = getChannelNumber(virtualChannel[0], virtualChannel[1]);
+        virtualChannel = g.split("^\\s*([a-zA-Z]*)(\\d+)?\\s*$");
+        greenChannel = getChannelNumber(virtualChannel[0], virtualChannel[1]);
+        virtualChannel = b.split("^\\s*([a-zA-Z]*)(\\d+)?\\s*$");
+        blueChannel = getChannelNumber(virtualChannel[0], virtualChannel[1]);
+        virtualChannel = w.split("^\\s*([a-zA-Z]*)(\\d+)?\\s*$");
+        whiteChannel = getChannelNumber(virtualChannel[0], virtualChannel[1]);
+    }
+
+    public VelbusVirtualColorChannel(String rgbw) throws InvalidPropertiesFormatException, NumberFormatException {
+        String virtualChannels[] = rgbw.split(
+                "/^\\s*([a-zA-Z]*)(\\d+)\\s*,\\s*([a-zA-Z]*)(\\d+)\\s*,\\s*([a-zA-Z]*)(\\d+)(?:\\s*,\\s*([a-zA-Z]*)(\\d+))?\\s*$/gm");
+        if (virtualChannels.length == 8) {
+            redChannel = getChannelNumber(virtualChannels[0], virtualChannels[1]);
+            greenChannel = getChannelNumber(virtualChannels[2], virtualChannels[3]);
+            blueChannel = getChannelNumber(virtualChannels[4], virtualChannels[5]);
+            whiteChannel = getChannelNumber(virtualChannels[6], virtualChannels[7]);
+        } else if (virtualChannels.length == 6) {
+            redChannel = getChannelNumber(virtualChannels[0], virtualChannels[1]);
+            greenChannel = getChannelNumber(virtualChannels[2], virtualChannels[3]);
+            blueChannel = getChannelNumber(virtualChannels[4], virtualChannels[5]);
+        } else {
+            throw new InvalidPropertiesFormatException("Wrong number of channels, must be 3 or 4.");
+        }
+    }
+
+    private byte getChannelNumber(String type, String number)
+            throws InvalidPropertiesFormatException, NumberFormatException {
+        if (DALI_ADDRESS.equals(type.toUpperCase())) {
+            return Integer.valueOf(Integer.valueOf(number) + 1).byteValue();
+        } else if (CHANNEL.equals(type.toUpperCase())) {
+            return Integer.valueOf(number).byteValue();
+        }
+        throw new InvalidPropertiesFormatException("Wrong channel type identifier, must be CH or A.");
+    }
+
+    private byte getByteValue(int channel) {
+        return Integer.valueOf(channel).byteValue();
+    }
+
+    public byte getRedChannel() {
+        return redChannel;
+    }
+
+    public byte getGreenChannel() {
+        return greenChannel;
+    }
+
+    public byte getBlueChannel() {
+        return blueChannel;
+    }
+
+    public byte getWhiteChannel() {
+        return whiteChannel;
+    }
+
+    public boolean isVirtualColorChannel(int channel) {
+        byte c = getByteValue(channel);
+
+        return c == redChannel || c == greenChannel || c == blueChannel || c == whiteChannel;
+    }
+
+    public boolean isColorChannel(int channel) {
+        byte c = getByteValue(channel);
+
+        return c == redChannel || c == greenChannel || c == blueChannel;
+    }
+
+    public boolean isWhiteChannel(int channel) {
+        byte c = getByteValue(channel);
+
+        return c == whiteChannel;
+    }
+
+    public boolean isRGBConfigured() {
+        return redChannel != NOT_CONFIGURED && greenChannel != NOT_CONFIGURED && blueChannel != NOT_CONFIGURED;
+    }
+
+    public boolean isWhiteConfigured() {
+        return whiteChannel != NOT_CONFIGURED;
+    }
+
+    public int getRedColor() {
+        return super.getColor()[0];
+    }
+
+    public int getGreenColor() {
+        return super.getColor()[1];
+    }
+
+    public int getBlueColor() {
+        return super.getColor()[2];
+    }
+
+    public byte getRedColorVelbus() {
+        return super.getColorVelbus()[0];
+    }
+
+    public byte getGreenColorVelbus() {
+        return super.getColorVelbus()[1];
+    }
+
+    public byte getBlueColorVelbus() {
+        return super.getColorVelbus()[2];
+    }
+
+    public void setColor(byte color, int channel) {
+        byte c = getByteValue(channel);
+        if (c == redChannel) {
+            setRedColor(color);
+        } else if (c == greenChannel) {
+            setGreenColor(color);
+        } else if (c == blueChannel) {
+            setBlueColor(color);
+        } else if (c == whiteChannel) {
+            setWhite(color);
+        }
+    }
+}
index fd024d2201d2fe18da5cd354b88043da34978209..a276a8dbba6a1b772c5bb8ab3b6158bc91d9f206 100644 (file)
@@ -43,6 +43,7 @@ import org.slf4j.LoggerFactory;
  * is used to return Velbus Modules as things to the framework.
  *
  * @author Cedric Boon - Initial contribution
+ * @author Daniel Rosengarten - Review sub-addresses management, add VMB1RYS, VMBDALI
  */
 @Component(scope = ServiceScope.PROTOTYPE, service = VelbusThingDiscoveryService.class)
 @NonNullByDefault
@@ -76,7 +77,7 @@ public class VelbusThingDiscoveryService extends AbstractThingHandlerDiscoverySe
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
+    public boolean onPacketReceived(byte[] packet) {
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte address = packet[2];
             byte length = packet[3];
@@ -91,12 +92,17 @@ public class VelbusThingDiscoveryService extends AbstractThingHandlerDiscoverySe
             } else if (command == COMMAND_MODULE_NAME_PART3 && packet.length >= 4 + length) {
                 handleChannelNameCommand(packet, address, length, 3);
             } else if (command == COMMAND_SUBTYPE && packet.length >= 4 + length) {
-                handleModuleSubtypeCommand(packet, address);
+                handleModuleSubtypeCommand(packet, address, 1);
+            } else if (command == COMMAND_SUBTYPE_2 && packet.length >= 4 + length) {
+                handleModuleSubtypeCommand(packet, address, 2);
+            } else if (command == COMMAND_SUBTYPE_3 && packet.length >= 4 + length) {
+                handleModuleSubtypeCommand(packet, address, 3);
             } else {
                 logger.debug("Unknown command '{}' to address '{}'.", String.format("%02X", command),
                         String.format("%02X", address));
             }
         }
+        return true;
     }
 
     private void handleModuleTypeCommand(byte[] packet, byte address) {
@@ -155,6 +161,10 @@ public class VelbusThingDiscoveryService extends AbstractThingHandlerDiscoverySe
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB2BLE, 2);
                 break;
+            case MODULE_TYPE_VMB2BLE_10:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB2BLE_10, 2);
+                break;
             case MODULE_TYPE_VMB2PBN:
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB2PBN, 8);
@@ -175,10 +185,18 @@ public class VelbusThingDiscoveryService extends AbstractThingHandlerDiscoverySe
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB4RYLD, 5);
                 break;
+            case MODULE_TYPE_VMB4RYLD_10:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB4RYLD_10, 5);
+                break;
             case MODULE_TYPE_VMB4RYNO:
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB4RYNO, 5);
                 break;
+            case MODULE_TYPE_VMB4RYNO_10:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB4RYNO_10, 5);
+                break;
             case MODULE_TYPE_VMB6IN:
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB6IN, 6);
@@ -187,6 +205,10 @@ public class VelbusThingDiscoveryService extends AbstractThingHandlerDiscoverySe
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB6PBN, 8);
                 break;
+            case MODULE_TYPE_VMB6PB_20:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB6PB_20, 8);
+                break;
             case MODULE_TYPE_VMB7IN:
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB7IN, 8);
@@ -216,57 +238,93 @@ public class VelbusThingDiscoveryService extends AbstractThingHandlerDiscoverySe
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBDMIR, 1);
                 break;
             case MODULE_TYPE_VMBEL1:
-                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBEL1, 9);
                 break;
+            case MODULE_TYPE_VMBEL1_20:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBEL1_20, 9);
+                break;
             case MODULE_TYPE_VMBEL2:
-                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBEL2, 9);
                 break;
+            case MODULE_TYPE_VMBEL2_20:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBEL2_20, 9);
+                break;
             case MODULE_TYPE_VMBEL4:
-                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBEL4, 9);
                 break;
+            case MODULE_TYPE_VMBEL4_20:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBEL4_20, 9);
+                break;
             case MODULE_TYPE_VMBELO:
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBELO, 33);
                 break;
-            case MODULE_TYPE_VMBELPIR:
+            case MODULE_TYPE_VMBELO_20:
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBELO_20, 33);
+                break;
+            case MODULE_TYPE_VMBELPIR:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBELPIR, 9);
                 break;
+            case MODULE_TYPE_VMBEL4PIR_20:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBEL4PIR_20, 9);
+                break;
             case MODULE_TYPE_VMBGP1:
-                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP1, 9);
                 break;
             case MODULE_TYPE_VMBGP1_2:
-                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP1_2, 9);
                 break;
+            case MODULE_TYPE_VMBGP1_20:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP1_20, 9);
+                break;
             case MODULE_TYPE_VMBGP2:
-                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP2, 9);
                 break;
             case MODULE_TYPE_VMBGP2_2:
-                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP2_2, 9);
                 break;
+            case MODULE_TYPE_VMBGP2_20:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP2_20, 9);
+                break;
             case MODULE_TYPE_VMBGP4:
-                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP4, 9);
                 break;
             case MODULE_TYPE_VMBGP4_2:
-                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP4_2, 9);
                 break;
+            case MODULE_TYPE_VMBGP4_20:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP4_20, 9);
+                break;
             case MODULE_TYPE_VMBGP4PIR:
-                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP4PIR, 9);
                 break;
             case MODULE_TYPE_VMBGP4PIR_2:
-                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP4PIR_2, 9);
                 break;
+            case MODULE_TYPE_VMBGP4PIR_20:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 1), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGP4PIR_20, 9);
+                break;
             case MODULE_TYPE_VMBGPO:
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGPO, 33);
@@ -279,6 +337,10 @@ public class VelbusThingDiscoveryService extends AbstractThingHandlerDiscoverySe
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGPOD_2, 33);
                 break;
+            case MODULE_TYPE_VMBGPO_20:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 4), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBGPO_20, 33);
+                break;
             case MODULE_TYPE_VMBMETEO:
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBMETEO, 13);
@@ -315,6 +377,14 @@ public class VelbusThingDiscoveryService extends AbstractThingHandlerDiscoverySe
                 velbusModule = new VelbusModule(new VelbusModuleAddress(address, 0), moduleType, highByteOfSerialNumber,
                         lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMB4PB, 8);
                 break;
+            case MODULE_TYPE_VMBDALI:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 9), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBDALI, 81);
+                break;
+            case MODULE_TYPE_VMBDALI_20:
+                velbusModule = new VelbusModule(new VelbusModuleAddress(address, 9), moduleType, highByteOfSerialNumber,
+                        lowByteOfSerialNumber, memoryMapVersion, buildYear, buildWeek, THING_TYPE_VMBDALI_20, 81);
+                break;
         }
 
         if (velbusModule != null) {
@@ -322,14 +392,14 @@ public class VelbusThingDiscoveryService extends AbstractThingHandlerDiscoverySe
         }
     }
 
-    private void handleModuleSubtypeCommand(byte[] packet, byte address) {
+    private void handleModuleSubtypeCommand(byte[] packet, byte address, int subTypeNumber) {
         if (velbusModules.containsKey(address)) {
             VelbusModule velbusModule = velbusModules.get(address);
 
             byte[] subAddresses = new byte[4];
             System.arraycopy(packet, 8, subAddresses, 0, 4);
 
-            velbusModule.getModuleAddress().setSubAddresses(subAddresses);
+            velbusModule.getModuleAddress().setSubAddresses(subAddresses, subTypeNumber);
 
             for (int i = 0; i < subAddresses.length; i++) {
                 if (subAddresses[i] != (byte) 0xFF) {
index 5566ee8dc9aae53e5bffb00bbda8f37fa20bf371..090f7fe757ba8b139a6d89cd59b88e058b0532dc 100644 (file)
@@ -48,8 +48,8 @@ import org.openhab.core.types.RefreshType;
  */
 @NonNullByDefault
 public class VelbusBlindsHandler extends VelbusThingHandler {
-    public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(
-            Arrays.asList(THING_TYPE_VMB1BL, THING_TYPE_VMB1BLS, THING_TYPE_VMB2BL, THING_TYPE_VMB2BLE));
+    public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(Arrays.asList(THING_TYPE_VMB1BL,
+            THING_TYPE_VMB1BLS, THING_TYPE_VMB2BL, THING_TYPE_VMB2BLE, THING_TYPE_VMB2BLE_10));
 
     public VelbusBlindsHandler(Thing thing) {
         super(thing, 0);
@@ -128,8 +128,10 @@ public class VelbusBlindsHandler extends VelbusThingHandler {
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        logger.trace("onPacketReceived() was called");
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte command = packet[4];
@@ -144,5 +146,7 @@ public class VelbusBlindsHandler extends VelbusThingHandler {
                 updateState(getModuleAddress().getChannelId(velbusChannelIdentifier), state);
             }
         }
+
+        return true;
     }
 }
index 3453870fd39959d749b0e16d436f740baca36fb6..e0cead60cd0cced8d110e48987f940a0c5cbbf03 100644 (file)
@@ -161,41 +161,41 @@ public abstract class VelbusBridgeHandler extends BaseBridgeHandler {
 
             alarmClock.setLocal(false);
 
-            switch (channelUID.getId()) {
-                case CHANNEL_BRIDGE_CLOCK_ALARM1_ENABLED:
-                case CHANNEL_BRIDGE_CLOCK_ALARM2_ENABLED: {
+            switch (channelUID.getIdWithoutGroup()) {
+                case CHANNEL_CLOCK_ALARM1_ENABLED:
+                case CHANNEL_CLOCK_ALARM2_ENABLED: {
                     if (command instanceof OnOffType) {
                         boolean enabled = command == OnOffType.ON;
                         alarmClock.setEnabled(enabled);
                     }
                     break;
                 }
-                case CHANNEL_BRIDGE_CLOCK_ALARM1_WAKEUP_HOUR:
-                case CHANNEL_BRIDGE_CLOCK_ALARM2_WAKEUP_HOUR: {
+                case CHANNEL_CLOCK_ALARM1_WAKEUP_HOUR:
+                case CHANNEL_CLOCK_ALARM2_WAKEUP_HOUR: {
                     if (command instanceof DecimalType decimalCommand) {
                         byte wakeupHour = decimalCommand.byteValue();
                         alarmClock.setWakeupHour(wakeupHour);
                     }
                     break;
                 }
-                case CHANNEL_BRIDGE_CLOCK_ALARM1_WAKEUP_MINUTE:
-                case CHANNEL_BRIDGE_CLOCK_ALARM2_WAKEUP_MINUTE: {
+                case CHANNEL_CLOCK_ALARM1_WAKEUP_MINUTE:
+                case CHANNEL_CLOCK_ALARM2_WAKEUP_MINUTE: {
                     if (command instanceof DecimalType decimalCommand) {
                         byte wakeupMinute = decimalCommand.byteValue();
                         alarmClock.setWakeupMinute(wakeupMinute);
                     }
                     break;
                 }
-                case CHANNEL_BRIDGE_CLOCK_ALARM1_BEDTIME_HOUR:
-                case CHANNEL_BRIDGE_CLOCK_ALARM2_BEDTIME_HOUR: {
+                case CHANNEL_CLOCK_ALARM1_BEDTIME_HOUR:
+                case CHANNEL_CLOCK_ALARM2_BEDTIME_HOUR: {
                     if (command instanceof DecimalType decimalCommand) {
                         byte bedTimeHour = decimalCommand.byteValue();
                         alarmClock.setBedtimeHour(bedTimeHour);
                     }
                     break;
                 }
-                case CHANNEL_BRIDGE_CLOCK_ALARM1_BEDTIME_MINUTE:
-                case CHANNEL_BRIDGE_CLOCK_ALARM2_BEDTIME_MINUTE: {
+                case CHANNEL_CLOCK_ALARM1_BEDTIME_MINUTE:
+                case CHANNEL_CLOCK_ALARM2_BEDTIME_MINUTE: {
                     if (command instanceof DecimalType decimalCommand) {
                         byte bedTimeMinute = decimalCommand.byteValue();
                         alarmClock.setBedtimeMinute(bedTimeMinute);
@@ -381,35 +381,22 @@ public abstract class VelbusBridgeHandler extends BaseBridgeHandler {
     }
 
     protected boolean isAlarmClockChannel(ChannelUID channelUID) {
-        switch (channelUID.getId()) {
-            case CHANNEL_BRIDGE_CLOCK_ALARM1_ENABLED:
-            case CHANNEL_BRIDGE_CLOCK_ALARM1_WAKEUP_HOUR:
-            case CHANNEL_BRIDGE_CLOCK_ALARM1_WAKEUP_MINUTE:
-            case CHANNEL_BRIDGE_CLOCK_ALARM1_BEDTIME_HOUR:
-            case CHANNEL_BRIDGE_CLOCK_ALARM1_BEDTIME_MINUTE:
-            case CHANNEL_BRIDGE_CLOCK_ALARM2_ENABLED:
-            case CHANNEL_BRIDGE_CLOCK_ALARM2_WAKEUP_HOUR:
-            case CHANNEL_BRIDGE_CLOCK_ALARM2_WAKEUP_MINUTE:
-            case CHANNEL_BRIDGE_CLOCK_ALARM2_BEDTIME_HOUR:
-            case CHANNEL_BRIDGE_CLOCK_ALARM2_BEDTIME_MINUTE:
-                return true;
-        }
-        return false;
+        return CHANNEL_GROUP_BRIDGE_CLOCK_ALARM.equals(channelUID.getGroupId());
     }
 
     protected byte determineAlarmNumber(ChannelUID channelUID) {
-        switch (channelUID.getId()) {
-            case CHANNEL_BRIDGE_CLOCK_ALARM1_ENABLED:
-            case CHANNEL_BRIDGE_CLOCK_ALARM1_WAKEUP_HOUR:
-            case CHANNEL_BRIDGE_CLOCK_ALARM1_WAKEUP_MINUTE:
-            case CHANNEL_BRIDGE_CLOCK_ALARM1_BEDTIME_HOUR:
-            case CHANNEL_BRIDGE_CLOCK_ALARM1_BEDTIME_MINUTE:
+        switch (channelUID.getIdWithoutGroup()) {
+            case CHANNEL_CLOCK_ALARM1_ENABLED:
+            case CHANNEL_CLOCK_ALARM1_WAKEUP_HOUR:
+            case CHANNEL_CLOCK_ALARM1_WAKEUP_MINUTE:
+            case CHANNEL_CLOCK_ALARM1_BEDTIME_HOUR:
+            case CHANNEL_CLOCK_ALARM1_BEDTIME_MINUTE:
                 return 1;
-            case CHANNEL_BRIDGE_CLOCK_ALARM2_ENABLED:
-            case CHANNEL_BRIDGE_CLOCK_ALARM2_WAKEUP_HOUR:
-            case CHANNEL_BRIDGE_CLOCK_ALARM2_WAKEUP_MINUTE:
-            case CHANNEL_BRIDGE_CLOCK_ALARM2_BEDTIME_HOUR:
-            case CHANNEL_BRIDGE_CLOCK_ALARM2_BEDTIME_MINUTE:
+            case CHANNEL_CLOCK_ALARM2_ENABLED:
+            case CHANNEL_CLOCK_ALARM2_WAKEUP_HOUR:
+            case CHANNEL_CLOCK_ALARM2_WAKEUP_MINUTE:
+            case CHANNEL_CLOCK_ALARM2_BEDTIME_HOUR:
+            case CHANNEL_CLOCK_ALARM2_BEDTIME_MINUTE:
                 return 2;
         }
 
index a6621d3276980e24675ea6999876dffe4ecb62b5..42892ac7546774bf833defa0ec2e200aca72652d 100644 (file)
@@ -104,8 +104,10 @@ public class VelbusDimmerHandler extends VelbusThingHandler {
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        logger.trace("onPacketReceived() was called");
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte address = packet[2];
@@ -126,5 +128,7 @@ public class VelbusDimmerHandler extends VelbusThingHandler {
                 updateState(getModuleAddress().getChannelId(velbusChannelIdentifier), state);
             }
         }
+
+        return true;
     }
 }
index 18cbe39aceae84111ad81468db2319b3daa09d75..5265d4803f7bcc4356afb8172bf2e0a1ce37fc10 100644 (file)
@@ -40,8 +40,9 @@ import org.openhab.core.types.RefreshType;
  */
 @NonNullByDefault
 public class VelbusRelayHandler extends VelbusThingHandler {
-    public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(Arrays.asList(THING_TYPE_VMB1RY,
-            THING_TYPE_VMB1RYNO, THING_TYPE_VMB1RYNOS, THING_TYPE_VMB4RY, THING_TYPE_VMB4RYLD, THING_TYPE_VMB4RYNO));
+    public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(
+            Arrays.asList(THING_TYPE_VMB1RY, THING_TYPE_VMB1RYNO, THING_TYPE_VMB1RYNOS, THING_TYPE_VMB4RY,
+                    THING_TYPE_VMB4RYLD, THING_TYPE_VMB4RYNO, THING_TYPE_VMB4RYLD_10, THING_TYPE_VMB4RYNO_10));
 
     public VelbusRelayHandler(Thing thing) {
         super(thing, 0);
@@ -79,8 +80,10 @@ public class VelbusRelayHandler extends VelbusThingHandler {
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        logger.trace("onPacketReceived() was called");
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte command = packet[4];
@@ -95,5 +98,7 @@ public class VelbusRelayHandler extends VelbusThingHandler {
                 updateState(getModuleAddress().getChannelId(velbusChannelIdentifier), state);
             }
         }
+
+        return true;
     }
 }
index 9b30f797d7435ae1f07521a322944ad270065db6..9fb4a66d6be6541b2c6f18481378a476cd78e9c0 100644 (file)
@@ -93,8 +93,10 @@ public class VelbusRelayWithInputHandler extends VelbusRelayHandler {
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        super.onPacketReceived(packet);
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte command = packet[4];
@@ -118,5 +120,7 @@ public class VelbusRelayWithInputHandler extends VelbusRelayHandler {
                 }
             }
         }
+
+        return true;
     }
 }
index 3d9e2abdf51ef8337476de062a5697431dff1ce9..8c541d2af47c94f802396161849667a5fda5f3d0 100644 (file)
@@ -99,19 +99,19 @@ public class VelbusSensorHandler extends VelbusThingHandler {
 
                 packet.Pressed();
                 velbusBridgeHandler.sendPacket(packet.getBytes());
-                triggerChannel("input#CH" + getModuleAddress().getChannelNumber(channelUID),
+                triggerChannel(CHANNEL_GROUP_INPUT + "#CH" + getModuleAddress().getChannelNumber(channelUID),
                         CommonTriggerEvents.PRESSED);
 
                 if (stringCommand.equals(LONG_PRESSED)) {
                     packet.LongPressed();
                     velbusBridgeHandler.sendPacket(packet.getBytes());
-                    triggerChannel("input#CH" + getModuleAddress().getChannelNumber(channelUID),
+                    triggerChannel(CHANNEL_GROUP_INPUT + "#CH" + getModuleAddress().getChannelNumber(channelUID),
                             CommonTriggerEvents.LONG_PRESSED);
                 }
 
                 packet.Released();
                 velbusBridgeHandler.sendPacket(packet.getBytes());
-                triggerChannel("input#CH" + getModuleAddress().getChannelNumber(channelUID),
+                triggerChannel(CHANNEL_GROUP_INPUT + "#CH" + getModuleAddress().getChannelNumber(channelUID),
                         CommonTriggerEvents.RELEASED);
             } else {
                 throw new UnsupportedOperationException(
@@ -121,15 +121,19 @@ public class VelbusSensorHandler extends VelbusThingHandler {
     }
 
     private boolean isFeedbackChannel(ChannelUID channelUID) {
-        return "feedback".equals(channelUID.getGroupId());
+        return CHANNEL_GROUP_FEEDBACK.equals(channelUID.getGroupId());
     }
 
     private boolean isButtonChannel(ChannelUID channelUID) {
-        return "button".equals(channelUID.getGroupId());
+        return CHANNEL_GROUP_BUTTON.equals(channelUID.getGroupId());
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
+
         logger.trace("onPacketReceived() was called");
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
@@ -144,7 +148,8 @@ public class VelbusSensorHandler extends VelbusThingHandler {
                     if (channelJustPressed != 0) {
                         VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address,
                                 channelJustPressed);
-                        triggerChannel("input#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
+                        triggerChannel(
+                                CHANNEL_GROUP_INPUT + "#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
                                 CommonTriggerEvents.PRESSED);
                     }
 
@@ -152,7 +157,8 @@ public class VelbusSensorHandler extends VelbusThingHandler {
                     if (channelJustReleased != 0) {
                         VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address,
                                 channelJustReleased);
-                        triggerChannel("input#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
+                        triggerChannel(
+                                CHANNEL_GROUP_INPUT + "#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
                                 CommonTriggerEvents.RELEASED);
                     }
 
@@ -160,11 +166,14 @@ public class VelbusSensorHandler extends VelbusThingHandler {
                     if (channelLongPressed != 0) {
                         VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address,
                                 channelLongPressed);
-                        triggerChannel("input#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
+                        triggerChannel(
+                                CHANNEL_GROUP_INPUT + "#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
                                 CommonTriggerEvents.LONG_PRESSED);
                     }
                 }
             }
         }
+
+        return true;
     }
 }
index aadd8621dee33d725c02a2a59d82ff95805d6392..f4933c13bff6648075992b0922138e6014622c4a 100644 (file)
@@ -48,7 +48,7 @@ import org.openhab.core.types.RefreshType;
 public class VelbusSensorWithAlarmClockHandler extends VelbusSensorHandler {
     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(Arrays.asList(THING_TYPE_VMB2PBN,
             THING_TYPE_VMB6PBN, THING_TYPE_VMB8PBU, THING_TYPE_VMBPIRC, THING_TYPE_VMBPIRM, THING_TYPE_VMBRFR8S,
-            THING_TYPE_VMBVP1, THING_TYPE_VMBKP, THING_TYPE_VMBIN, THING_TYPE_VMB4PB));
+            THING_TYPE_VMBVP1, THING_TYPE_VMBKP, THING_TYPE_VMBIN, THING_TYPE_VMB4PB, THING_TYPE_VMB6PB_20));
     private static final HashMap<ThingTypeUID, Integer> ALARM_CONFIGURATION_MEMORY_ADDRESSES = new HashMap<>();
 
     static {
@@ -60,7 +60,7 @@ public class VelbusSensorWithAlarmClockHandler extends VelbusSensorHandler {
         ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBEL1, 0x0357);
         ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBEL2, 0x0357);
         ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBEL4, 0x0357);
-        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBELO, 0x0593);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBELO, 0x05A3);
         ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBELPIR, 0x030F);
         ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBPIRC, 0x0031);
         ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBPIRM, 0x0031);
@@ -82,6 +82,19 @@ public class VelbusSensorWithAlarmClockHandler extends VelbusSensorHandler {
         ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBKP, 0x00A7);
         ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBIN, 0x00A7);
         ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMB4PB, 0x00A7);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBDALI, 0x0513);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMB6PB_20, 0x00A7);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBEL1_20, 0x0357);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBEL2_20, 0x0357);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBEL4_20, 0x0357);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBELO_20, 0x05A3);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBGP1_20, 0x0357);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBGP2_20, 0x0357);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBGP4_20, 0x0357);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBGPO_20, 0x05A3);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBDALI_20, 0x0513);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBEL4PIR_20, 0x032B);
+        ALARM_CONFIGURATION_MEMORY_ADDRESSES.put(THING_TYPE_VMBGP4PIR_20, 0x032B);
     }
 
     private static final byte ALARM_CONFIGURATION_MEMORY_SIZE = 0x09;
@@ -93,26 +106,30 @@ public class VelbusSensorWithAlarmClockHandler extends VelbusSensorHandler {
     private static final StringType ALARM_TYPE_LOCAL = new StringType("LOCAL");
     private static final StringType ALARM_TYPE_GLOBAL = new StringType("GLOBAL");
 
-    private final ChannelUID clockAlarm1Enabled = new ChannelUID(thing.getUID(), "clockAlarm", "clockAlarm1Enabled");
-    private final ChannelUID clockAlarm1Type = new ChannelUID(thing.getUID(), "clockAlarm", "clockAlarm1Type");
-    private final ChannelUID clockAlarm1WakeupHour = new ChannelUID(thing.getUID(), "clockAlarm",
-            "clockAlarm1WakeupHour");
-    private final ChannelUID clockAlarm1WakeupMinute = new ChannelUID(thing.getUID(), "clockAlarm",
-            "clockAlarm1WakeupMinute");
-    private final ChannelUID clockAlarm1BedtimeHour = new ChannelUID(thing.getUID(), "clockAlarm",
-            "clockAlarm1BedtimeHour");
-    private final ChannelUID clockAlarm1BedtimeMinute = new ChannelUID(thing.getUID(), "clockAlarm",
-            "clockAlarm1BedtimeMinute");
-    private final ChannelUID clockAlarm2Enabled = new ChannelUID(thing.getUID(), "clockAlarm", "clockAlarm2Enabled");
-    private final ChannelUID clockAlarm2Type = new ChannelUID(thing.getUID(), "clockAlarm", "clockAlarm2Type");
-    private final ChannelUID clockAlarm2WakeupHour = new ChannelUID(thing.getUID(), "clockAlarm",
-            "clockAlarm2WakeupHour");
-    private final ChannelUID clockAlarm2WakeupMinute = new ChannelUID(thing.getUID(), "clockAlarm",
-            "clockAlarm2WakeupMinute");
-    private final ChannelUID clockAlarm2BedtimeHour = new ChannelUID(thing.getUID(), "clockAlarm",
-            "clockAlarm2BedtimeHour");
-    private final ChannelUID clockAlarm2BedtimeMinute = new ChannelUID(thing.getUID(), "clockAlarm",
-            "clockAlarm2BedtimeMinute");
+    private final ChannelUID clockAlarm1Enabled = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM1_ENABLED);
+    private final ChannelUID clockAlarm1Type = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM1_TYPE);
+    private final ChannelUID clockAlarm1WakeupHour = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM1_WAKEUP_HOUR);
+    private final ChannelUID clockAlarm1WakeupMinute = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM1_WAKEUP_MINUTE);
+    private final ChannelUID clockAlarm1BedtimeHour = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM1_BEDTIME_HOUR);
+    private final ChannelUID clockAlarm1BedtimeMinute = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM1_BEDTIME_MINUTE);
+    private final ChannelUID clockAlarm2Enabled = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM2_ENABLED);
+    private final ChannelUID clockAlarm2Type = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM2_TYPE);
+    private final ChannelUID clockAlarm2WakeupHour = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM2_WAKEUP_HOUR);
+    private final ChannelUID clockAlarm2WakeupMinute = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM2_WAKEUP_MINUTE);
+    private final ChannelUID clockAlarm2BedtimeHour = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM2_BEDTIME_HOUR);
+    private final ChannelUID clockAlarm2BedtimeMinute = new ChannelUID(thing.getUID(), CHANNEL_GROUP_MODULE_CLOCK_ALARM,
+            CHANNEL_CLOCK_ALARM2_BEDTIME_MINUTE);
 
     private int clockAlarmConfigurationMemoryAddress;
     private VelbusClockAlarmConfiguration alarmClockConfiguration = new VelbusClockAlarmConfiguration();
@@ -158,52 +175,52 @@ public class VelbusSensorWithAlarmClockHandler extends VelbusSensorHandler {
 
             alarmClock.setLocal(true);
 
-            switch (channelUID.getId()) {
-                case CHANNEL_MODULE_CLOCK_ALARM1_TYPE:
-                case CHANNEL_MODULE_CLOCK_ALARM2_TYPE: {
+            switch (channelUID.getIdWithoutGroup()) {
+                case CHANNEL_CLOCK_ALARM1_TYPE:
+                case CHANNEL_CLOCK_ALARM2_TYPE: {
                     if (command instanceof OnOffType) {
                         // If AlarmType is not read only, it's an old implementation of the module, warn user and
                         // discard the command
                         logger.warn(
-                                "Old implementation of thing '{}', still works, but it's better to remove and recreate the thing.",
+                                "Old implementation of thing '{}'. Only local alarm on module, global alarm only on bridge. To avoid problem, remove and recreate the thing.",
                                 getThing().getUID());
                     }
                     return;
                 }
-                case CHANNEL_MODULE_CLOCK_ALARM1_ENABLED:
-                case CHANNEL_MODULE_CLOCK_ALARM2_ENABLED: {
+                case CHANNEL_CLOCK_ALARM1_ENABLED:
+                case CHANNEL_CLOCK_ALARM2_ENABLED: {
                     if (command instanceof OnOffType) {
                         boolean enabled = command == OnOffType.ON;
                         alarmClock.setEnabled(enabled);
                     }
                     break;
                 }
-                case CHANNEL_MODULE_CLOCK_ALARM1_WAKEUP_HOUR:
-                case CHANNEL_MODULE_CLOCK_ALARM2_WAKEUP_HOUR: {
+                case CHANNEL_CLOCK_ALARM1_WAKEUP_HOUR:
+                case CHANNEL_CLOCK_ALARM2_WAKEUP_HOUR: {
                     if (command instanceof DecimalType decimalCommand) {
                         byte wakeupHour = decimalCommand.byteValue();
                         alarmClock.setWakeupHour(wakeupHour);
                     }
                     break;
                 }
-                case CHANNEL_MODULE_CLOCK_ALARM1_WAKEUP_MINUTE:
-                case CHANNEL_MODULE_CLOCK_ALARM2_WAKEUP_MINUTE: {
+                case CHANNEL_CLOCK_ALARM1_WAKEUP_MINUTE:
+                case CHANNEL_CLOCK_ALARM2_WAKEUP_MINUTE: {
                     if (command instanceof DecimalType decimalCommand) {
                         byte wakeupMinute = decimalCommand.byteValue();
                         alarmClock.setWakeupMinute(wakeupMinute);
                     }
                     break;
                 }
-                case CHANNEL_MODULE_CLOCK_ALARM1_BEDTIME_HOUR:
-                case CHANNEL_MODULE_CLOCK_ALARM2_BEDTIME_HOUR: {
+                case CHANNEL_CLOCK_ALARM1_BEDTIME_HOUR:
+                case CHANNEL_CLOCK_ALARM2_BEDTIME_HOUR: {
                     if (command instanceof DecimalType decimalCommand) {
                         byte bedTimeHour = decimalCommand.byteValue();
                         alarmClock.setBedtimeHour(bedTimeHour);
                     }
                     break;
                 }
-                case CHANNEL_MODULE_CLOCK_ALARM1_BEDTIME_MINUTE:
-                case CHANNEL_MODULE_CLOCK_ALARM2_BEDTIME_MINUTE: {
+                case CHANNEL_CLOCK_ALARM1_BEDTIME_MINUTE:
+                case CHANNEL_CLOCK_ALARM2_BEDTIME_MINUTE: {
                     if (command instanceof DecimalType decimalCommand) {
                         byte bedTimeMinute = decimalCommand.byteValue();
                         alarmClock.setBedtimeMinute(bedTimeMinute);
@@ -256,10 +273,10 @@ public class VelbusSensorWithAlarmClockHandler extends VelbusSensorHandler {
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        super.onPacketReceived(packet);
-
-        logger.trace("onPacketReceived() was called");
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte command = packet[4];
@@ -303,6 +320,8 @@ public class VelbusSensorWithAlarmClockHandler extends VelbusSensorHandler {
                 }
             }
         }
+
+        return true;
     }
 
     public Boolean isClockAlarmConfigurationByte(int memoryAddress) {
@@ -368,43 +387,28 @@ public class VelbusSensorWithAlarmClockHandler extends VelbusSensorHandler {
     }
 
     protected boolean isAlarmClockChannel(ChannelUID channelUID) {
-        switch (channelUID.getId()) {
-            case CHANNEL_MODULE_CLOCK_ALARM1_ENABLED:
-            case CHANNEL_MODULE_CLOCK_ALARM1_TYPE:
-            case CHANNEL_MODULE_CLOCK_ALARM1_WAKEUP_HOUR:
-            case CHANNEL_MODULE_CLOCK_ALARM1_WAKEUP_MINUTE:
-            case CHANNEL_MODULE_CLOCK_ALARM1_BEDTIME_HOUR:
-            case CHANNEL_MODULE_CLOCK_ALARM1_BEDTIME_MINUTE:
-            case CHANNEL_MODULE_CLOCK_ALARM2_ENABLED:
-            case CHANNEL_MODULE_CLOCK_ALARM2_TYPE:
-            case CHANNEL_MODULE_CLOCK_ALARM2_WAKEUP_HOUR:
-            case CHANNEL_MODULE_CLOCK_ALARM2_WAKEUP_MINUTE:
-            case CHANNEL_MODULE_CLOCK_ALARM2_BEDTIME_HOUR:
-            case CHANNEL_MODULE_CLOCK_ALARM2_BEDTIME_MINUTE:
-                return true;
-        }
-        return false;
+        return CHANNEL_GROUP_MODULE_CLOCK_ALARM.equals(channelUID.getGroupId());
     }
 
     protected byte determineAlarmNumber(ChannelUID channelUID) {
-        switch (channelUID.getId()) {
-            case CHANNEL_MODULE_CLOCK_ALARM1_ENABLED:
-            case CHANNEL_MODULE_CLOCK_ALARM1_TYPE:
-            case CHANNEL_MODULE_CLOCK_ALARM1_WAKEUP_HOUR:
-            case CHANNEL_MODULE_CLOCK_ALARM1_WAKEUP_MINUTE:
-            case CHANNEL_MODULE_CLOCK_ALARM1_BEDTIME_HOUR:
-            case CHANNEL_MODULE_CLOCK_ALARM1_BEDTIME_MINUTE:
+        switch (channelUID.getIdWithoutGroup()) {
+            case CHANNEL_CLOCK_ALARM1_ENABLED:
+            case CHANNEL_CLOCK_ALARM1_TYPE:
+            case CHANNEL_CLOCK_ALARM1_WAKEUP_HOUR:
+            case CHANNEL_CLOCK_ALARM1_WAKEUP_MINUTE:
+            case CHANNEL_CLOCK_ALARM1_BEDTIME_HOUR:
+            case CHANNEL_CLOCK_ALARM1_BEDTIME_MINUTE:
                 return 1;
-            case CHANNEL_MODULE_CLOCK_ALARM2_ENABLED:
-            case CHANNEL_MODULE_CLOCK_ALARM2_TYPE:
-            case CHANNEL_MODULE_CLOCK_ALARM2_WAKEUP_HOUR:
-            case CHANNEL_MODULE_CLOCK_ALARM2_WAKEUP_MINUTE:
-            case CHANNEL_MODULE_CLOCK_ALARM2_BEDTIME_HOUR:
-            case CHANNEL_MODULE_CLOCK_ALARM2_BEDTIME_MINUTE:
+            case CHANNEL_CLOCK_ALARM2_ENABLED:
+            case CHANNEL_CLOCK_ALARM2_TYPE:
+            case CHANNEL_CLOCK_ALARM2_WAKEUP_HOUR:
+            case CHANNEL_CLOCK_ALARM2_WAKEUP_MINUTE:
+            case CHANNEL_CLOCK_ALARM2_BEDTIME_HOUR:
+            case CHANNEL_CLOCK_ALARM2_BEDTIME_MINUTE:
                 return 2;
         }
 
-        throw new IllegalArgumentException("The given channelUID is not an alarm clock channel: " + channelUID);
+        throw new IllegalArgumentException("The given channelUID is not a module alarm clock channel: " + channelUID);
     }
 
     protected int getClockAlarmAndProgramSelectionIndexInModuleStatus() {
index f6d652575ee1318fd200130740a6b5e9f392a34d..a98304d74f480c428f198d3b69813d15c18d02bd 100644 (file)
@@ -74,6 +74,7 @@ public abstract class VelbusTemperatureSensorHandler extends VelbusSensorWithAla
         if (refreshJob != null) {
             refreshJob.cancel(true);
         }
+        super.dispose();
     }
 
     private void startAutomaticRefresh(int refreshInterval) {
@@ -114,10 +115,10 @@ public abstract class VelbusTemperatureSensorHandler extends VelbusSensorWithAla
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        super.onPacketReceived(packet);
-
-        logger.trace("onPacketReceived() was called");
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte command = packet[4];
@@ -133,5 +134,7 @@ public abstract class VelbusTemperatureSensorHandler extends VelbusSensorWithAla
                 updateState(temperatureChannel, state);
             }
         }
+
+        return true;
     }
 }
index 0e8a03c7f183ec77272b91682e9e77654aff2cda..08603c83199fc8ab2fbdb2f71ef1e3f0939becb3 100644 (file)
@@ -29,6 +29,7 @@ import org.openhab.core.thing.CommonTriggerEvents;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingStatus;
 import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.ThingTypeUID;
 import org.openhab.core.types.Command;
 import org.openhab.core.types.RefreshType;
 
@@ -58,34 +59,44 @@ public abstract class VelbusThermostatHandler extends VelbusTemperatureSensorHan
     private static final byte DAY_MODE_MASK = (byte) 0x20;
     private static final byte NIGHT_MODE_MASK = (byte) 0x10;
 
-    private final ChannelUID currentTemperatureSetpointChannel = new ChannelUID(thing.getUID(), "thermostat",
-            "currentTemperatureSetpoint");
-    private final ChannelUID heatingModeComfortTemperatureSetpointChannel = new ChannelUID(thing.getUID(), "thermostat",
-            "heatingModeComfortTemperatureSetpoint");
-    private final ChannelUID heatingModeDayTemperatureSetpointChannel = new ChannelUID(thing.getUID(), "thermostat",
-            "heatingModeDayTemperatureSetpoint");
-    private final ChannelUID heatingModeNightTemperatureSetpointChannel = new ChannelUID(thing.getUID(), "thermostat",
-            "heatingModeNightTemperatureSetpoint");
+    private final ChannelUID currentTemperatureSetpointChannel = new ChannelUID(thing.getUID(),
+            CHANNEL_GROUP_THERMOSTAT, CHANNEL_THERMOSTAT_CURRENT_TEMPERATURE);
+    private final ChannelUID heatingModeComfortTemperatureSetpointChannel = new ChannelUID(thing.getUID(),
+            CHANNEL_GROUP_THERMOSTAT, CHANNEL_THERMOSTAT_HEATING_COMFORT);
+    private final ChannelUID heatingModeDayTemperatureSetpointChannel = new ChannelUID(thing.getUID(),
+            CHANNEL_GROUP_THERMOSTAT, CHANNEL_THERMOSTAT_HEATING_DAY);
+    private final ChannelUID heatingModeNightTemperatureSetpointChannel = new ChannelUID(thing.getUID(),
+            CHANNEL_GROUP_THERMOSTAT, CHANNEL_THERMOSTAT_HEATING_NIGHT);
     private final ChannelUID heatingModeAntifrostTemperatureSetpointChannel = new ChannelUID(thing.getUID(),
-            "thermostat", "heatingModeAntiFrostTemperatureSetpoint");
-    private final ChannelUID coolingModeComfortTemperatureSetpointChannel = new ChannelUID(thing.getUID(), "thermostat",
-            "coolingModeComfortTemperatureSetpoint");
-    private final ChannelUID coolingModeDayTemperatureSetpointChannel = new ChannelUID(thing.getUID(), "thermostat",
-            "coolingModeDayTemperatureSetpoint");
-    private final ChannelUID coolingModeNightTemperatureSetpointChannel = new ChannelUID(thing.getUID(), "thermostat",
-            "coolingModeNightTemperatureSetpoint");
-    private final ChannelUID coolingModeSafeTemperatureSetpointChannel = new ChannelUID(thing.getUID(), "thermostat",
-            "coolingModeSafeTemperatureSetpoint");
-    private final ChannelUID operatingModeChannel = new ChannelUID(thing.getUID(), "thermostat", "operatingMode");
-    private final ChannelUID modeChannel = new ChannelUID(thing.getUID(), "thermostat", "mode");
-    private final ChannelUID heaterChannel = new ChannelUID(thing.getUID(), "thermostat", "heater");
-    private final ChannelUID boostChannel = new ChannelUID(thing.getUID(), "thermostat", "boost");
-    private final ChannelUID pumpChannel = new ChannelUID(thing.getUID(), "thermostat", "pump");
-    private final ChannelUID coolerChannel = new ChannelUID(thing.getUID(), "thermostat", "cooler");
-    private final ChannelUID alarm1Channel = new ChannelUID(thing.getUID(), "thermostat", "alarm1");
-    private final ChannelUID alarm2Channel = new ChannelUID(thing.getUID(), "thermostat", "alarm2");
-    private final ChannelUID alarm3Channel = new ChannelUID(thing.getUID(), "thermostat", "alarm3");
-    private final ChannelUID alarm4Channel = new ChannelUID(thing.getUID(), "thermostat", "alarm4");
+            CHANNEL_GROUP_THERMOSTAT, CHANNEL_THERMOSTAT_HEATING_ANTI_FROST);
+    private final ChannelUID coolingModeComfortTemperatureSetpointChannel = new ChannelUID(thing.getUID(),
+            CHANNEL_GROUP_THERMOSTAT, CHANNEL_THERMOSTAT_COOLING_COMFORT);
+    private final ChannelUID coolingModeDayTemperatureSetpointChannel = new ChannelUID(thing.getUID(),
+            CHANNEL_GROUP_THERMOSTAT, CHANNEL_THERMOSTAT_COOLING_DAY);
+    private final ChannelUID coolingModeNightTemperatureSetpointChannel = new ChannelUID(thing.getUID(),
+            CHANNEL_GROUP_THERMOSTAT, CHANNEL_THERMOSTAT_COOLING_NIGHT);
+    private final ChannelUID coolingModeSafeTemperatureSetpointChannel = new ChannelUID(thing.getUID(),
+            CHANNEL_GROUP_THERMOSTAT, CHANNEL_THERMOSTAT_COOLING_SAFE);
+    private final ChannelUID operatingModeChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_THERMOSTAT,
+            CHANNEL_THERMOSTAT_OPERATING_MODE);
+    private final ChannelUID modeChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_THERMOSTAT,
+            CHANNEL_THERMOSTAT_MODE);
+    private final ChannelUID heaterChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_THERMOSTAT,
+            CHANNEL_THERMOSTAT_HEATER);
+    private final ChannelUID boostChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_THERMOSTAT,
+            CHANNEL_THERMOSTAT_BOOST);
+    private final ChannelUID pumpChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_THERMOSTAT,
+            CHANNEL_THERMOSTAT_PUMP);
+    private final ChannelUID coolerChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_THERMOSTAT,
+            CHANNEL_THERMOSTAT_COOLER);
+    private final ChannelUID alarm1Channel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_THERMOSTAT,
+            CHANNEL_THERMOSTAT_ALARM1);
+    private final ChannelUID alarm2Channel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_THERMOSTAT,
+            CHANNEL_THERMOSTAT_ALARM2);
+    private final ChannelUID alarm3Channel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_THERMOSTAT,
+            CHANNEL_THERMOSTAT_ALARM3);
+    private final ChannelUID alarm4Channel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_THERMOSTAT,
+            CHANNEL_THERMOSTAT_ALARM4);
 
     public VelbusThermostatHandler(Thing thing, int numberOfSubAddresses, ChannelUID temperatureChannel) {
         super(thing, numberOfSubAddresses, temperatureChannel);
@@ -154,8 +165,10 @@ public abstract class VelbusThermostatHandler extends VelbusTemperatureSensorHan
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        super.onPacketReceived(packet);
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         logger.trace("onPacketReceived() was called");
 
@@ -238,14 +251,47 @@ public abstract class VelbusThermostatHandler extends VelbusTemperatureSensorHan
                         THERMOSTAT_TEMPERATURE_SETPOINT_RESOLUTION);
                 updateState(currentTemperatureSetpointChannel,
                         new QuantityType<>(targetTemperatureValue, SIUnits.CELSIUS));
-            } else if (address != this.getModuleAddress().getAddress() && command == COMMAND_PUSH_BUTTON_STATUS) {
-                byte outputChannelsJustActivated = packet[5];
-                byte outputChannelsJustDeactivated = packet[6];
+            } else if (command == COMMAND_PUSH_BUTTON_STATUS) {
+                ThingTypeUID thingTypeUID = this.thing.getThingTypeUID();
+                if (thingTypeUID.equals(THING_TYPE_VMBELO) || thingTypeUID.equals(THING_TYPE_VMBGPO)
+                        || thingTypeUID.equals(THING_TYPE_VMBGPOD) || thingTypeUID.equals(THING_TYPE_VMBGPOD_2)
+                        || thingTypeUID.equals(THING_TYPE_VMBGPO_20)) {
+                    // modules VMBELO, VMBGPO, VMBGPOD, VMBGPOD_2, VMBGPO_20 use sub-address 4 for sensor
+                    if (address == this.getModuleAddress().getSubAddresses()[3]) {
+                        byte outputChannelsJustActivated = packet[5];
+                        byte outputChannelsJustDeactivated = packet[6];
+
+                        triggerThermostatChannels(outputChannelsJustActivated, CommonTriggerEvents.PRESSED);
+                        triggerThermostatChannels(outputChannelsJustDeactivated, CommonTriggerEvents.RELEASED);
+                    }
+                    // modules VMBEL1, VMBEL2, VMBEL4, VMBELPIR, VMBGP1, VMBGP1-2, VMBGP2, VMBGP2-2, VMBGP4, VMBGP4-2,
+                    // VMBGP4PIR, VMBGP4PIR-2, VMBEL1-20, VMBEL2-20, VMBEL4-20, VMBELO-20, VMBGP1-20, VMBGP2-20,
+                    // VMBGP4-20, VMBEL4PIR-20, VMBGP4PIR-20 use sub-address 1 for sensor, wich is not usable as push
+                    // button
+                } else if (thingTypeUID.equals(THING_TYPE_VMBEL1) || thingTypeUID.equals(THING_TYPE_VMBEL2)
+                        || thingTypeUID.equals(THING_TYPE_VMBEL4) || thingTypeUID.equals(THING_TYPE_VMBELPIR)
+                        || thingTypeUID.equals(THING_TYPE_VMBGP1) || thingTypeUID.equals(THING_TYPE_VMBGP1_2)
+                        || thingTypeUID.equals(THING_TYPE_VMBGP2) || thingTypeUID.equals(THING_TYPE_VMBGP2_2)
+                        || thingTypeUID.equals(THING_TYPE_VMBGP4) || thingTypeUID.equals(THING_TYPE_VMBGP4_2)
+                        || thingTypeUID.equals(THING_TYPE_VMBGP4PIR) || thingTypeUID.equals(THING_TYPE_VMBGP4PIR_2)
+                        || thingTypeUID.equals(THING_TYPE_VMBEL1_20) || thingTypeUID.equals(THING_TYPE_VMBEL2_20)
+                        || thingTypeUID.equals(THING_TYPE_VMBEL4_20) || thingTypeUID.equals(THING_TYPE_VMBELO_20)
+                        || thingTypeUID.equals(THING_TYPE_VMBGP1_20) || thingTypeUID.equals(THING_TYPE_VMBGP2_20)
+                        || thingTypeUID.equals(THING_TYPE_VMBGP4_20) || thingTypeUID.equals(THING_TYPE_VMBEL4PIR_20)
+                        || thingTypeUID.equals(THING_TYPE_VMBGP4PIR_20)) {
+                    if (address != this.getModuleAddress().getAddress()) {
+                        byte outputChannelsJustActivated = packet[5];
+                        byte outputChannelsJustDeactivated = packet[6];
+
+                        triggerThermostatChannels(outputChannelsJustActivated, CommonTriggerEvents.PRESSED);
+                        triggerThermostatChannels(outputChannelsJustDeactivated, CommonTriggerEvents.RELEASED);
+                    }
+                }
 
-                triggerThermostatChannels(outputChannelsJustActivated, CommonTriggerEvents.PRESSED);
-                triggerThermostatChannels(outputChannelsJustDeactivated, CommonTriggerEvents.RELEASED);
             }
         }
+
+        return true;
     }
 
     private void triggerThermostatChannels(byte outputChannels, String event) {
index 00d6e577867690af59665c48b2af1d78054f59ce..a68f87662b9e28835a4748d29745160fbe616963 100644 (file)
@@ -60,6 +60,8 @@ public abstract class VelbusThingHandler extends BaseThingHandler implements Vel
 
     private int numberOfSubAddresses;
 
+    private volatile boolean disposed = true;
+
     public VelbusThingHandler(Thing thing, int numberOfSubAddresses) {
         super(thing);
 
@@ -76,6 +78,14 @@ public abstract class VelbusThingHandler extends BaseThingHandler implements Vel
         initializeThing(bridge == null ? ThingStatus.OFFLINE : bridge.getStatus());
         initializeChannelNames();
         initializeChannelStates();
+        disposed = false;
+    }
+
+    @Override
+    public void dispose() {
+        super.dispose();
+
+        disposed = true;
     }
 
     @Override
@@ -152,7 +162,14 @@ public abstract class VelbusThingHandler extends BaseThingHandler implements Vel
                 if (subAddress != null) {
                     subAddresses[i] = hexToByte(subAddress);
                 } else {
-                    subAddresses[i] = (byte) 0xFF;
+                    if (getConfig().get(propertyKey) != null) {
+                        subAddress = getConfig().get(propertyKey).toString();
+                        if (subAddress != null) {
+                            subAddresses[i] = hexToByte(subAddress);
+                        }
+                    } else {
+                        subAddresses[i] = (byte) 0xFF;
+                    }
                 }
             }
 
@@ -237,4 +254,14 @@ public abstract class VelbusThingHandler extends BaseThingHandler implements Vel
 
         return this.velbusBridgeHandler;
     }
+
+    @Override
+    public boolean onPacketReceived(byte[] packet) {
+        logger.trace("onPacketReceived() was called");
+
+        if (disposed) {
+            return false;
+        }
+        return true;
+    }
 }
index b827ad63052fb84cd1649db01ca55c3ea52f07aa..39c0d9b75053ae7d052f82b0aa6cae6badb5b192 100644 (file)
@@ -93,6 +93,7 @@ public class VelbusVMB4ANHandler extends VelbusSensorWithAlarmClockHandler {
         if (refreshJob != null) {
             refreshJob.cancel(true);
         }
+        super.dispose();
     }
 
     private void startAutomaticRefresh(int refreshInterval) {
@@ -143,10 +144,10 @@ public class VelbusVMB4ANHandler extends VelbusSensorWithAlarmClockHandler {
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        super.onPacketReceived(packet);
-
-        logger.trace("onPacketReceived() was called");
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte command = packet[4];
@@ -210,6 +211,8 @@ public class VelbusVMB4ANHandler extends VelbusSensorWithAlarmClockHandler {
                 updateState(channelUID, new StringType(channelText[channel - 9]));
             }
         }
+
+        return true;
     }
 
     protected byte convertChannelUIDToChannelByte(ChannelUID channelUID) {
index a0e40d27bc6c40b1449237c4cddae34a8a47b1f8..29e8e6c5a723235f7770e6d49500787d04e4c110 100644 (file)
@@ -85,6 +85,7 @@ public class VelbusVMB7INHandler extends VelbusSensorWithAlarmClockHandler {
         if (refreshJob != null) {
             refreshJob.cancel(true);
         }
+        super.dispose();
     }
 
     private void startAutomaticRefresh(int refreshInterval) {
@@ -131,10 +132,10 @@ public class VelbusVMB7INHandler extends VelbusSensorWithAlarmClockHandler {
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        super.onPacketReceived(packet);
-
-        logger.trace("onPacketReceived() was called");
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte command = packet[4];
@@ -175,5 +176,7 @@ public class VelbusVMB7INHandler extends VelbusSensorWithAlarmClockHandler {
                 }
             }
         }
+
+        return true;
     }
 }
diff --git a/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusVMBDALIHandler.java b/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/handler/VelbusVMBDALIHandler.java
new file mode 100644 (file)
index 0000000..e8c6bcb
--- /dev/null
@@ -0,0 +1,400 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.velbus.internal.handler;
+
+import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.velbus.internal.VelbusColorChannel;
+import org.openhab.binding.velbus.internal.VelbusVirtualColorChannel;
+import org.openhab.binding.velbus.internal.config.VelbusSensorConfig;
+import org.openhab.binding.velbus.internal.packets.VelbusDaliRequestPacket;
+import org.openhab.binding.velbus.internal.packets.VelbusPacket;
+import org.openhab.binding.velbus.internal.packets.VelbusSetColorPacket;
+import org.openhab.binding.velbus.internal.packets.VelbusSetDimPacket;
+import org.openhab.binding.velbus.internal.packets.VelbusSetScenePacket;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.HSBType;
+import org.openhab.core.library.types.PercentType;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.types.Command;
+import org.openhab.core.types.RefreshType;
+
+/**
+ * The {@link VelbusVMBDALIHandler} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Daniel Rosengarten - Initial contribution
+ */
+@NonNullByDefault
+public class VelbusVMBDALIHandler extends VelbusSensorWithAlarmClockHandler {
+    public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(
+            Arrays.asList(THING_TYPE_VMBDALI, THING_TYPE_VMBDALI_20));
+    private @Nullable ScheduledFuture<?> refreshJob;
+    private @NonNullByDefault({}) VelbusSensorConfig sensorConfig;
+
+    private VelbusColorChannel[] colorChannels;
+    private VelbusVirtualColorChannel[] virtualColorChannels;
+
+    public VelbusVMBDALIHandler(Thing thing) {
+        super(thing, 9);
+
+        colorChannels = new VelbusColorChannel[81];
+        virtualColorChannels = new VelbusVirtualColorChannel[16];
+    }
+
+    @Override
+    public void initialize() {
+        this.sensorConfig = getConfigAs(VelbusSensorConfig.class);
+
+        super.initialize();
+
+        initializeAutomaticRefresh();
+        initializeColorChannel();
+        initializeVirtualLight();
+        initializeChannelStates();
+    }
+
+    private void initializeAutomaticRefresh() {
+        int refreshInterval = this.sensorConfig.refresh;
+
+        if (refreshInterval > 0) {
+            startAutomaticRefresh(refreshInterval);
+        }
+    }
+
+    private void initializeColorChannel() {
+        for (int i = 0; i <= 80; i++) {
+            colorChannels[i] = new VelbusColorChannel();
+        }
+    }
+
+    private void initializeVirtualLight() {
+        String virtualLight;
+
+        for (int i = 1; i <= 16; i++) {
+            if (getConfig().containsKey(VIRTUAL_LIGHT + i)) {
+                virtualLight = getConfig().get(VIRTUAL_LIGHT + i).toString();
+                if (virtualLight.length() > 0) {
+                    try {
+                        virtualColorChannels[i - 1] = new VelbusVirtualColorChannel(virtualLight);
+                    } catch (Exception e) {
+                        logger.warn("VMBDALI on address {} : Virtual Light {} has wrong channel format '{}'. {}",
+                                getModuleAddress().getAddress(), i, virtualLight, e.getMessage());
+                    }
+                }
+            }
+            if (virtualColorChannels[i - 1] == null) {
+                virtualColorChannels[i - 1] = new VelbusVirtualColorChannel();
+            }
+        }
+    }
+
+    private void initializeChannelStates() {
+        VelbusBridgeHandler velbusBridgeHandler = getVelbusBridgeHandler();
+        if (velbusBridgeHandler == null) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
+            return;
+        }
+
+        sendDaliReadoutRequest(velbusBridgeHandler, ALL_DALI_CHANNELS);
+    }
+
+    @Override
+    public void dispose() {
+        final ScheduledFuture<?> refreshJob = this.refreshJob;
+        if (refreshJob != null) {
+            refreshJob.cancel(true);
+            this.refreshJob = null;
+        }
+    }
+
+    private void startAutomaticRefresh(int refreshInterval) {
+        VelbusBridgeHandler velbusBridgeHandler = getVelbusBridgeHandler();
+        if (velbusBridgeHandler == null) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
+            return;
+        }
+
+        refreshJob = scheduler.scheduleWithFixedDelay(() -> {
+            sendDaliReadoutRequest(velbusBridgeHandler, ALL_DALI_CHANNELS);
+        }, 0, refreshInterval, TimeUnit.SECONDS);
+    }
+
+    protected void sendDaliReadoutRequest(VelbusBridgeHandler velbusBridgeHandler, byte channel) {
+        VelbusDaliRequestPacket packet = new VelbusDaliRequestPacket(getModuleAddress().getAddress(), channel);
+
+        byte[] packetBytes = packet.getBytes();
+        velbusBridgeHandler.sendPacket(packetBytes);
+    }
+
+    @Override
+    public void handleCommand(ChannelUID channelUID, Command command) {
+        super.handleCommand(channelUID, command);
+
+        VelbusBridgeHandler velbusBridgeHandler = getVelbusBridgeHandler();
+        if (velbusBridgeHandler == null) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
+            return;
+        }
+
+        byte address = getModuleAddress().getChannelIdentifier(channelUID).getAddress();
+        byte channel = Integer.valueOf(getModuleAddress().getChannelNumber(channelUID)).byteValue();
+
+        if (command instanceof RefreshType) {
+            if (isColorGroupChannel(channelUID) || isBrightnessGroupChannel(channelUID)
+                    || isWhiteGroupChannel(channelUID)) {
+                sendDaliReadoutRequest(velbusBridgeHandler, channel);
+            }
+        } else if (isSceneGroupChannel(channelUID)) {
+            if (command instanceof DecimalType decimalCommand) {
+                byte scene = decimalCommand.byteValue();
+
+                VelbusSetScenePacket packet = new VelbusSetScenePacket(address, channel, scene);
+                velbusBridgeHandler.sendPacket(packet.getBytes());
+            } else {
+                throw new UnsupportedOperationException(
+                        "The command '" + command + "' is not supported on channel '" + channelUID + "'.");
+            }
+        } else if (isColorGroupChannel(channelUID) || isBrightnessGroupChannel(channelUID)
+                || isWhiteGroupChannel(channelUID) || isVirtualLightChannel(channelUID)) {
+            VelbusColorChannel colorChannel = colorChannels[Byte.toUnsignedInt(channel) - 1];
+
+            if (isBrightnessGroupChannel(channelUID)) {
+                if (command instanceof PercentType percentCommand) {
+                    colorChannel.setBrightness(percentCommand);
+
+                    VelbusSetDimPacket packet = new VelbusSetDimPacket(address, channel);
+                    packet.setDim(colorChannel.getBrightnessVelbus());
+                    velbusBridgeHandler.sendPacket(packet.getBytes());
+                } else {
+                    throw new UnsupportedOperationException(
+                            "The command '" + command + "' is not supported on channel '" + channelUID + "'.");
+                }
+            } else if (isColorGroupChannel(channelUID)) {
+                if (command instanceof HSBType hsbCommand) {
+                    colorChannel.setBrightness(hsbCommand);
+                    colorChannel.setColor(hsbCommand);
+
+                    VelbusSetColorPacket packet = new VelbusSetColorPacket(address, channel);
+                    packet.setBrightness(colorChannel.getBrightnessVelbus());
+                    packet.setColor(colorChannel.getColorVelbus());
+                    velbusBridgeHandler.sendPacket(packet.getBytes());
+                } else {
+                    throw new UnsupportedOperationException(
+                            "The command '" + command + "' is not supported on channel '" + channelUID + "'.");
+                }
+            } else if (isWhiteGroupChannel(channelUID)) {
+                if (command instanceof PercentType percentCommand) {
+                    int channelNumber = getModuleAddress().getChannelNumber(channelUID);
+                    boolean isVirtualLight = false;
+
+                    for (int i = 0; i < 16; i++) {
+                        if (virtualColorChannels[i].isVirtualColorChannel(channelNumber)) {
+                            virtualColorChannels[i].setWhite(percentCommand);
+
+                            VelbusSetDimPacket packet = new VelbusSetDimPacket(address, channel);
+                            packet.setDim(virtualColorChannels[i].getWhiteVelbus());
+                            velbusBridgeHandler.sendPacket(packet.getBytes());
+                            isVirtualLight = true;
+                        }
+                    }
+                    if (!isVirtualLight) {
+                        colorChannel.setWhite(percentCommand);
+
+                        VelbusSetColorPacket packet = new VelbusSetColorPacket(address, channel);
+                        packet.setWhite(colorChannel.getWhiteVelbus());
+                        velbusBridgeHandler.sendPacket(packet.getBytes());
+                    }
+                } else {
+                    throw new UnsupportedOperationException(
+                            "The command '" + command + "' is not supported on channel '" + channelUID + "'.");
+                }
+            } else if (isVirtualLightChannel(channelUID)) {
+                int virtualChannel = getModuleAddress().getChannelNumber(channelUID) - 1;
+                VelbusVirtualColorChannel virtualColorChannel = virtualColorChannels[virtualChannel];
+
+                if (command instanceof HSBType hsbCommand && virtualColorChannel.isRGBConfigured()) {
+                    virtualColorChannel.setBrightness(hsbCommand);
+                    virtualColorChannel.setColor(hsbCommand);
+
+                    VelbusSetDimPacket packet = new VelbusSetDimPacket(address, virtualColorChannel.getRedChannel());
+                    packet.setDim(virtualColorChannel.getRedColorVelbus());
+                    velbusBridgeHandler.sendPacket(packet.getBytes());
+
+                    packet = new VelbusSetDimPacket(address, virtualColorChannel.getGreenChannel());
+                    packet.setDim(virtualColorChannel.getGreenColorVelbus());
+                    velbusBridgeHandler.sendPacket(packet.getBytes());
+
+                    packet = new VelbusSetDimPacket(address, virtualColorChannel.getBlueChannel());
+                    packet.setDim(virtualColorChannel.getBlueColorVelbus());
+                    velbusBridgeHandler.sendPacket(packet.getBytes());
+                } else {
+                    throw new UnsupportedOperationException(
+                            "The command '" + command + "' is not supported on channel '" + channelUID + "'.");
+                }
+            }
+        }
+    }
+
+    private boolean isColorGroupChannel(ChannelUID channelUID) {
+        return CHANNEL_GROUP_COLOR.equals(channelUID.getGroupId());
+    }
+
+    private boolean isBrightnessGroupChannel(ChannelUID channelUID) {
+        return CHANNEL_GROUP_BRIGHTNESS.equals(channelUID.getGroupId());
+    }
+
+    private boolean isWhiteGroupChannel(ChannelUID channelUID) {
+        return CHANNEL_GROUP_WHITE.equals(channelUID.getGroupId());
+    }
+
+    private boolean isSceneGroupChannel(ChannelUID channelUID) {
+        return CHANNEL_GROUP_SCENE.equals(channelUID.getGroupId());
+    }
+
+    private boolean isVirtualLightChannel(ChannelUID channelUID) {
+        return CHANNEL_GROUP_VIRTUAL_LIGHT.equals(channelUID.getGroupId());
+    }
+
+    @Override
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
+
+        if (packet[0] == VelbusPacket.STX && packet.length >= 7) {
+            byte command = packet[4];
+            byte setting = packet[6];
+
+            if (command == COMMAND_TEMP_SENSOR_SETTINGS_PART1 && setting == DALI_SETTING_ACTUAL_LEVEL) {
+                int channel = Byte.toUnsignedInt(packet[5]);
+
+                if (channel >= 1 && channel <= 80) {
+                    VelbusColorChannel colorChannel = colorChannels[channel - 1];
+
+                    if (packet.length >= 8 && packet.length < 12) {
+                        ChannelUID brightness = new ChannelUID(thing.getUID(), CHANNEL_GROUP_BRIGHTNESS,
+                                CHANNEL + channel);
+                        colorChannel.setBrightness(packet[7]);
+                        updateState(brightness, colorChannel.getBrightnessPercent());
+                        updateVirtualLightState(channel, packet[7]);
+                    } else if (packet.length >= 12) {
+                        ChannelUID brightness = new ChannelUID(thing.getUID(), CHANNEL_GROUP_BRIGHTNESS,
+                                CHANNEL + channel);
+                        colorChannel.setBrightness(packet[7]);
+                        updateState(brightness, colorChannel.getBrightnessPercent());
+
+                        ChannelUID color = new ChannelUID(thing.getUID(), CHANNEL_GROUP_COLOR, CHANNEL + channel);
+                        colorChannel.setColor(new byte[] { packet[8], packet[9], packet[10] });
+                        updateState(color, colorChannel.getColorHSB());
+
+                        ChannelUID white = new ChannelUID(thing.getUID(), CHANNEL_GROUP_WHITE, CHANNEL + channel);
+                        colorChannel.setWhite(packet[11]);
+                        updateState(white, colorChannel.getWhitePercent());
+                    }
+                } else if (channel == 81) { // Broadcast
+                    if (packet.length >= 8 && packet.length < 12) {
+                        VelbusColorChannel colorChannel;
+                        ChannelUID brightness;
+
+                        for (int i = 1; i <= 80; i++) {
+                            colorChannel = colorChannels[i - 1];
+                            brightness = new ChannelUID(thing.getUID(), CHANNEL_GROUP_BRIGHTNESS, CHANNEL + i);
+                            colorChannel.setBrightness(packet[7]);
+                            updateState(brightness, colorChannel.getBrightnessPercent());
+                            updateVirtualLightState(i, packet[7]);
+                        }
+                    } else if (packet.length >= 12) {
+                        VelbusColorChannel colorChannel;
+                        ChannelUID brightness;
+                        ChannelUID color;
+                        ChannelUID white;
+                        byte[] rgb = new byte[] { packet[8], packet[9], packet[10] };
+
+                        for (int i = 1; i <= 80; i++) {
+                            colorChannel = colorChannels[i - 1];
+
+                            brightness = new ChannelUID(thing.getUID(), CHANNEL_GROUP_BRIGHTNESS, CHANNEL + i);
+                            colorChannel.setBrightness(packet[7]);
+                            updateState(brightness, colorChannel.getBrightnessPercent());
+
+                            color = new ChannelUID(thing.getUID(), CHANNEL_GROUP_COLOR, CHANNEL + i);
+                            colorChannel.setColor(rgb);
+                            updateState(color, colorChannel.getColorHSB());
+
+                            white = new ChannelUID(thing.getUID(), CHANNEL_GROUP_WHITE, CHANNEL + i);
+                            colorChannel.setWhite(packet[11]);
+                            updateState(white, colorChannel.getWhitePercent());
+                        }
+                    }
+                }
+            } else if (command == COMMAND_DIMVALUE_STATUS && packet.length >= 8) {
+                int channel = Byte.toUnsignedInt(packet[5]);
+
+                if (channel >= 1 && channel <= 80) {
+                    VelbusColorChannel colorChannel = colorChannels[channel - 1];
+
+                    for (int i = 0; i < (packet.length - 8); i++) {
+                        ChannelUID brightness = new ChannelUID(thing.getUID(), CHANNEL_GROUP_BRIGHTNESS,
+                                CHANNEL + (channel + i));
+                        colorChannel.setBrightness(packet[6 + i]);
+                        updateState(brightness, colorChannel.getBrightnessPercent());
+                        updateVirtualLightState(channel + i, packet[6 + i]);
+                    }
+                } else if (channel == 81) { // Broadcast
+                    VelbusColorChannel colorChannel;
+                    ChannelUID brightness;
+
+                    for (int i = 1; i <= 80; i++) {
+                        colorChannel = colorChannels[i - 1];
+                        brightness = new ChannelUID(thing.getUID(), CHANNEL_GROUP_BRIGHTNESS, CHANNEL + i);
+                        colorChannel.setBrightness(packet[6]);
+                        updateState(brightness, colorChannel.getBrightnessPercent());
+                        updateVirtualLightState(i, packet[6]);
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private void updateVirtualLightState(int channel, byte dimVal) {
+        for (int i = 0; i < 16; i++) {
+            if (virtualColorChannels[i].isVirtualColorChannel(channel)) {
+                virtualColorChannels[i].setColor(dimVal, channel);
+
+                if (virtualColorChannels[i].isColorChannel(channel)) {
+                    ChannelUID virtualLight = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VIRTUAL_LIGHT,
+                            VIRTUAL_LIGHT + (i + 1));
+                    updateState(virtualLight, virtualColorChannels[i].getColorHSB());
+                } else if (virtualColorChannels[i].isWhiteChannel(channel)) {
+                    ChannelUID whiteChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_WHITE, CHANNEL + channel);
+                    updateState(whiteChannel, virtualColorChannels[i].getWhitePercent());
+                }
+            }
+        }
+    }
+}
index 0948989974f8e6504c2f7a842d9b8709062bf5a2..391d63bb4c086b6428aee34d067d27cb228c25d9 100644 (file)
@@ -19,23 +19,85 @@ import java.util.HashSet;
 import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.velbus.internal.packets.VelbusPacket;
+import org.openhab.binding.velbus.internal.packets.VelbusRelayPacket;
+import org.openhab.binding.velbus.internal.packets.VelbusStatusRequestPacket;
+import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
 import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.types.Command;
+import org.openhab.core.types.RefreshType;
 
 /**
  * The {@link VelbusVMBELHandler} is responsible for handling commands, which are
  * sent to one of the channels.
  *
  * @author Cedric Boon - Initial contribution
- * @author Daniel Rosengarten - Add VMBELPIR support
+ * @author Daniel Rosengarten - Add VMBELPIR support, add output support
  */
 @NonNullByDefault
 public class VelbusVMBELHandler extends VelbusThermostatHandler {
     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(
-            Arrays.asList(THING_TYPE_VMBEL1, THING_TYPE_VMBEL2, THING_TYPE_VMBEL4, THING_TYPE_VMBELPIR));
+            Arrays.asList(THING_TYPE_VMBEL1, THING_TYPE_VMBEL2, THING_TYPE_VMBEL4, THING_TYPE_VMBELPIR,
+                    THING_TYPE_VMBEL1_20, THING_TYPE_VMBEL2_20, THING_TYPE_VMBEL4_20, THING_TYPE_VMBEL4PIR_20));
+
+    private final ChannelUID outputChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_OUTPUT, CHANNEL_OUTPUT);
 
     public VelbusVMBELHandler(Thing thing) {
-        super(thing, 4, new ChannelUID(thing.getUID(), "input", "CH9"));
+        super(thing, 4, new ChannelUID(thing.getUID(), CHANNEL_GROUP_INPUT, "CH9"));
+    }
+
+    @Override
+    public void handleCommand(ChannelUID channelUID, Command command) {
+        super.handleCommand(channelUID, command);
+
+        VelbusBridgeHandler velbusBridgeHandler = getVelbusBridgeHandler();
+        if (velbusBridgeHandler == null) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
+            return;
+        }
+
+        if (command instanceof RefreshType) {
+            VelbusStatusRequestPacket packet = new VelbusStatusRequestPacket(getModuleAddress().getAddress());
+
+            byte[] packetBytes = packet.getBytes();
+            velbusBridgeHandler.sendPacket(packetBytes);
+        } else if (command instanceof OnOffType commandAsOnOffType) {
+            byte commandByte = determineCommandByte(commandAsOnOffType);
+
+            VelbusRelayPacket packet = new VelbusRelayPacket(getModuleAddress(), commandByte);
+
+            byte[] packetBytes = packet.getBytes();
+            velbusBridgeHandler.sendPacket(packetBytes);
+        } else {
+            logger.debug("The command '{}' is not supported by this handler.", command.getClass());
+        }
+    }
+
+    private byte determineCommandByte(OnOffType command) {
+        return (command == OnOffType.ON) ? COMMAND_SWITCH_RELAY_ON : COMMAND_SWITCH_RELAY_OFF;
+    }
+
+    @Override
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
+
+        if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
+            byte command = packet[4];
+
+            if (command == COMMAND_MODULE_STATUS && packet.length >= 7) {
+                boolean on = (packet[7] & (byte) 0x80) == (byte) 0x80;
+
+                OnOffType state = on ? OnOffType.ON : OnOffType.OFF;
+                updateState(outputChannel, state);
+            }
+        }
+
+        return true;
     }
 }
index 1ea9602ca61a350934d18fe38d6dae885fb37ef7..6b6d6d5a23cf981c313d98a9d0d80a82371d4e23 100644 (file)
  */
 package org.openhab.binding.velbus.internal.handler;
 
-import static org.openhab.binding.velbus.internal.VelbusBindingConstants.THING_TYPE_VMBELO;
+import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
 
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.velbus.internal.packets.VelbusPacket;
+import org.openhab.binding.velbus.internal.packets.VelbusRelayPacket;
+import org.openhab.binding.velbus.internal.packets.VelbusStatusRequestPacket;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
 import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.types.Command;
+import org.openhab.core.types.RefreshType;
 
 /**
  * The {@link VelbusVMBELOHandler} is responsible for handling commands, which are
  * sent to one of the channels.
  *
  * @author Cedric Boon - Initial contribution
+ * @author Daniel Rosengarten - Add output support
  */
 @NonNullByDefault
 public class VelbusVMBELOHandler extends VelbusMemoHandler {
-    public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(Arrays.asList(THING_TYPE_VMBELO));
+    public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(
+            Arrays.asList(THING_TYPE_VMBELO, THING_TYPE_VMBELO_20));
+
+    private final ChannelUID outputChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_OUTPUT, CHANNEL_OUTPUT);
 
     public VelbusVMBELOHandler(Thing thing) {
         super(thing);
     }
+
+    @Override
+    public void handleCommand(ChannelUID channelUID, Command command) {
+        super.handleCommand(channelUID, command);
+
+        VelbusBridgeHandler velbusBridgeHandler = getVelbusBridgeHandler();
+        if (velbusBridgeHandler == null) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
+            return;
+        }
+
+        if (command instanceof RefreshType) {
+            VelbusStatusRequestPacket packet = new VelbusStatusRequestPacket(getModuleAddress().getAddress());
+
+            byte[] packetBytes = packet.getBytes();
+            velbusBridgeHandler.sendPacket(packetBytes);
+        } else if (command instanceof OnOffType commandAsOnOffType) {
+            byte commandByte = determineCommandByte(commandAsOnOffType);
+
+            VelbusRelayPacket packet = new VelbusRelayPacket(getModuleAddress(), commandByte);
+
+            byte[] packetBytes = packet.getBytes();
+            velbusBridgeHandler.sendPacket(packetBytes);
+        } else {
+            logger.debug("The command '{}' is not supported by this handler.", command.getClass());
+        }
+    }
+
+    private byte determineCommandByte(OnOffType command) {
+        return (command == OnOffType.ON) ? COMMAND_SWITCH_RELAY_ON : COMMAND_SWITCH_RELAY_OFF;
+    }
+
+    @Override
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
+
+        if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
+            byte command = packet[4];
+
+            if (command == COMMAND_MODULE_STATUS && packet.length >= 7) {
+                boolean on = (packet[7] & (byte) 0x80) == (byte) 0x80;
+
+                OnOffType state = on ? OnOffType.ON : OnOffType.OFF;
+                updateState(outputChannel, state);
+            }
+        }
+
+        return true;
+    }
 }
index 45797ef6e7c196bac844b1ceb137e73f10281a96..ed8ce97ca2135927125464e43a62cd24655991be 100644 (file)
@@ -33,7 +33,8 @@ import org.openhab.core.thing.ThingTypeUID;
 public class VelbusVMBGPHandler extends VelbusThermostatHandler {
     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(
             Arrays.asList(THING_TYPE_VMBGP1, THING_TYPE_VMBGP1_2, THING_TYPE_VMBGP2, THING_TYPE_VMBGP2_2,
-                    THING_TYPE_VMBGP4, THING_TYPE_VMBGP4_2, THING_TYPE_VMBGP4PIR, THING_TYPE_VMBGP4PIR_2));
+                    THING_TYPE_VMBGP4, THING_TYPE_VMBGP4_2, THING_TYPE_VMBGP4PIR, THING_TYPE_VMBGP4PIR_2,
+                    THING_TYPE_VMBGP1_20, THING_TYPE_VMBGP2_20, THING_TYPE_VMBGP4_20, THING_TYPE_VMBGP4PIR_20));
 
     public VelbusVMBGPHandler(Thing thing) {
         super(thing, 4, new ChannelUID(thing.getUID(), "input", "CH9"));
index 8a926d52de3c6a3f4659bab3c08d3795a16e4086..6374dc8c6e70e17dfa72baa9af65ba5f15f7cdcd 100644 (file)
@@ -38,7 +38,7 @@ import org.openhab.core.types.RefreshType;
 @NonNullByDefault
 public class VelbusVMBGPOHandler extends VelbusMemoHandler {
     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(
-            Arrays.asList(THING_TYPE_VMBGPO, THING_TYPE_VMBGPOD, THING_TYPE_VMBGPOD_2));
+            Arrays.asList(THING_TYPE_VMBGPO, THING_TYPE_VMBGPOD, THING_TYPE_VMBGPOD_2, THING_TYPE_VMBGPO_20));
 
     public static final int MODULESETTINGS_MEMORY_ADDRESS = 0x02F0;
     public static final int LAST_MEMORY_LOCATION_ADDRESS = 0x1A03;
@@ -74,10 +74,10 @@ public class VelbusVMBGPOHandler extends VelbusMemoHandler {
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        super.onPacketReceived(packet);
-
-        logger.trace("onPacketReceived() was called");
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte command = packet[4];
@@ -101,5 +101,7 @@ public class VelbusVMBGPOHandler extends VelbusMemoHandler {
                 }
             }
         }
+
+        return true;
     }
 }
index 8add52e7d015f62a1576759c0f4f95503e91b323..41f7c2ad3e46d4d5d1ae981be586aeb3861522e1 100644 (file)
@@ -104,10 +104,10 @@ public class VelbusVMBMeteoHandler extends VelbusTemperatureSensorHandler {
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        super.onPacketReceived(packet);
-
-        logger.trace("onPacketReceived() was called");
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte command = packet[4];
@@ -133,5 +133,7 @@ public class VelbusVMBMeteoHandler extends VelbusTemperatureSensorHandler {
                 updateState(windspeedChannel, windValueState);
             }
         }
+
+        return true;
     }
 }
index 9b9f7adcb3e435ffc4e56633446d848226f0300b..784701fd7024e01ccdd6039402bdbe7bdc5fa8cc 100644 (file)
@@ -73,10 +73,10 @@ public class VelbusVMBPIROHandler extends VelbusTemperatureSensorHandler {
     }
 
     @Override
-    public void onPacketReceived(byte[] packet) {
-        super.onPacketReceived(packet);
-
-        logger.trace("onPacketReceived() was called");
+    public boolean onPacketReceived(byte[] packet) {
+        if (!super.onPacketReceived(packet)) {
+            return false;
+        }
 
         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
             byte command = packet[4];
@@ -90,5 +90,7 @@ public class VelbusVMBPIROHandler extends VelbusTemperatureSensorHandler {
                 updateState(illuminanceChannel, lightValueState);
             }
         }
+
+        return true;
     }
 }
diff --git a/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusDaliRequestPacket.java b/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusDaliRequestPacket.java
new file mode 100644 (file)
index 0000000..ad47f58
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.velbus.internal.packets;
+
+import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.velbus.internal.VelbusChannelIdentifier;
+
+/**
+ * The {@link VelbusDaliRequestPacket} represents a Velbus packet that can be used to
+ * request the values of the DALI channel(s) of the given Velbus module.
+ *
+ * @author Daniel Rosengarten - Initial contribution
+ */
+@NonNullByDefault
+public class VelbusDaliRequestPacket extends VelbusPacket {
+    private final byte GATEWAY_CONFIG = (byte) 0x01;
+
+    private byte channel = ALL_DALI_CHANNELS;
+
+    public VelbusDaliRequestPacket(byte address, byte channel) {
+        super(address, PRIO_LOW);
+
+        this.channel = (channel == ALL_CHANNELS) ? ALL_DALI_CHANNELS : channel;
+    }
+
+    public VelbusDaliRequestPacket(VelbusChannelIdentifier velbusChannelIdentifier) {
+        super(velbusChannelIdentifier.getAddress(), PRIO_LOW);
+
+        this.channel = velbusChannelIdentifier.getChannelByte();
+    }
+
+    @Override
+    protected byte[] getDataBytes() {
+        if (this.channel == ALL_DALI_CHANNELS) {
+            return new byte[] { COMMAND_TEMP_SENSOR_SETTINGS_REQUEST, this.channel, GATEWAY_CONFIG };
+        } else {
+            return new byte[] { COMMAND_TEMP_SENSOR_SETTINGS_REQUEST, this.channel, GATEWAY_CONFIG,
+                    DALI_SETTING_ACTUAL_LEVEL };
+        }
+    }
+}
index 0f899ed94a99b00983dbc9c04232b853efd3635e..e3b7c1270b7990981404d2fb822598669d01f2f3 100644 (file)
  */
 package org.openhab.binding.velbus.internal.packets;
 
+import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
+
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.binding.velbus.internal.VelbusChannelIdentifier;
+import org.openhab.binding.velbus.internal.VelbusModuleAddress;
 
 /**
  * The {@link VelbusRelayPacket} represents a Velbus packet that can be used to
@@ -33,6 +36,13 @@ public class VelbusRelayPacket extends VelbusPacket {
         this.command = command;
     }
 
+    public VelbusRelayPacket(VelbusModuleAddress velbusModuleAddress, byte command) {
+        super(velbusModuleAddress.getAddress(), PRIO_HI);
+
+        this.channel = ALL_CHANNELS;
+        this.command = command;
+    }
+
     @Override
     protected byte[] getDataBytes() {
         return new byte[] { command, channel };
diff --git a/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusSetColorPacket.java b/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusSetColorPacket.java
new file mode 100644 (file)
index 0000000..dd33b74
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.velbus.internal.packets;
+
+import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link VelbusSetColorPacket} represents a Velbus packet that can be used to
+ * set the color of a channel on the DALI module.
+ *
+ * @author Daniel Rosengarten - Initial contribution
+ */
+@NonNullByDefault
+public class VelbusSetColorPacket extends VelbusPacket {
+    private byte[] data;
+
+    public VelbusSetColorPacket(byte address, byte channel) {
+        super(address, PRIO_HI, false);
+
+        this.data = new byte[] { COMMAND_SET_COLOR, channel, VALUE_UNCHANGED, VALUE_UNCHANGED, VALUE_UNCHANGED,
+                VALUE_UNCHANGED, VALUE_UNCHANGED };
+    }
+
+    public void setBrightness(byte brightness) {
+        data[2] = brightness;
+    }
+
+    public void setColor(byte r, byte g, byte b) {
+        data[3] = r;
+        data[4] = g;
+        data[5] = b;
+    }
+
+    public void setColor(byte rgb[]) {
+        data[3] = rgb[0];
+        data[4] = rgb[1];
+        data[5] = rgb[2];
+    }
+
+    public void setWhite(byte white) {
+        data[6] = white;
+    }
+
+    @Override
+    protected byte[] getDataBytes() {
+        return data;
+    }
+}
diff --git a/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusSetDimPacket.java b/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusSetDimPacket.java
new file mode 100644 (file)
index 0000000..2e60a2f
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.velbus.internal.packets;
+
+import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link VelbusSetDimPacket} represents a Velbus packet that can be used to
+ * set the color of a channel on the DALI module.
+ *
+ * @author Daniel Rosengarten - Initial contribution
+ */
+@NonNullByDefault
+public class VelbusSetDimPacket extends VelbusPacket {
+    private byte[] data;
+
+    public VelbusSetDimPacket(byte address, byte channel) {
+        super(address, PRIO_HI, false);
+
+        this.data = new byte[] { COMMAND_SET_DIMVALUE, channel, VALUE_UNCHANGED, VALUE_UNCHANGED, VALUE_UNCHANGED };
+    }
+
+    public void setDim(byte dim) {
+        data[2] = dim;
+    }
+
+    @Override
+    protected byte[] getDataBytes() {
+        return data;
+    }
+}
diff --git a/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusSetScenePacket.java b/bundles/org.openhab.binding.velbus/src/main/java/org/openhab/binding/velbus/internal/packets/VelbusSetScenePacket.java
new file mode 100644 (file)
index 0000000..8db1c56
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.velbus.internal.packets;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.velbus.internal.VelbusBindingConstants;
+
+/**
+ * The {@link VelbusSetScenePacket} represents a Velbus packet that can be used to
+ * set the scene of a channel on the DALI module.
+ *
+ * @author Daniel Rosengarten - Initial contribution
+ */
+@NonNullByDefault
+public class VelbusSetScenePacket extends VelbusPacket {
+    private byte[] data;
+
+    public VelbusSetScenePacket(byte address, byte channel, byte sceneNumber) {
+        super(address, PRIO_HI, false);
+
+        this.data = new byte[] { VelbusBindingConstants.COMMAND_SET_DIMSCENE, channel, sceneNumber };
+    }
+
+    public void GoToScene(byte sceneNumber) {
+        data[2] = sceneNumber;
+    }
+
+    @Override
+    protected byte[] getDataBytes() {
+        return data;
+    }
+}
index cd7ab69b0cab9ce592a051930efd7ad2fadc0d2a..730eddd9de1756b27045393630326388fcef5aac 100644 (file)
                        <label>Address</label>
                        <description>The velbus address of the device</description>
                </parameter>
+               <parameter name="subaddress1" type="text" required="true">
+                       <label>Channel CH9 Address</label>
+                       <description>The velbus sub-address of the device (FF = disabled). In the VelbusLink application it's identified by
+                               Sensor or Thermostat.</description>
+                       <default>FF</default>
+               </parameter>
                <parameter name="refresh" type="integer" unit="s">
                        <label>Refresh Interval</label>
                        <description>Refresh interval for the temperature sensor (in seconds), default 300. If set to 0 or left empty, no
                        <label>Address</label>
                        <description>The velbus address of the device</description>
                </parameter>
+               <parameter name="subaddress1" type="text" required="true">
+                       <label>Channel CH9..CH16 Address</label>
+                       <description>The velbus sub-address 1 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               Page 3-4 or Pushbuttons 9-16.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="subaddress2" type="text" required="true">
+                       <label>Channel CH17..CH24 Address</label>
+                       <description>The velbus sub-address 2 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               Page 5-6 or Pushbuttons 17-24.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="subaddress3" type="text" required="true">
+                       <label>Channel CH25..CH32 Address</label>
+                       <description>The velbus sub-address 3 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               Page 7-8 or Pushbuttons 25-32.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="subaddress4" type="text" required="true">
+                       <label>Channel CH33 Address</label>
+                       <description>The velbus sub-address 4 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               Sensor or Thermostat.</description>
+                       <default>FF</default>
+               </parameter>
                <parameter name="refresh" type="integer" unit="s">
                        <label>Refresh Interval</label>
                        <description>Refresh interval for the temperature sensor (in seconds), default 300. If set to 0 or left empty, no
                        <advanced>true</advanced>
                </parameter>
        </config-description>
+
+       <config-description uri="thing-type:velbus:81channelDevice">
+               <parameter name="address" type="text" required="true">
+                       <label>Address</label>
+                       <description>The velbus address of the device. In the VelbusLink application it's identified by DALI Address A0..A7
+                               or Channel CH1..CH8.</description>
+               </parameter>
+               <parameter name="subaddress1" type="text" required="true">
+                       <label>Channel CH9..CH16 Address</label>
+                       <description>The velbus sub-address 1 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               DALI Address A8..A15 or Channel CH9..CH16.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="subaddress2" type="text" required="true">
+                       <label>Channel CH17..CH24 Address</label>
+                       <description>The velbus sub-address 2 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               DALI Address A16..A23 or Channel CH17..CH24.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="subaddress3" type="text" required="true">
+                       <label>Channel CH25..CH32 Address</label>
+                       <description>The velbus sub-address 3 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               DALI Address A24..A31 or Channel CH25..CH32.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="subaddress4" type="text" required="true">
+                       <label>Channel CH33..CH40 Address</label>
+                       <description>The velbus sub-address 4 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               DALI Address A32..A39 or Channel CH33..CH40.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="subaddress5" type="text" required="true">
+                       <label>Channel CH41..CH48 Address</label>
+                       <description>The velbus sub-address 5 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               DALI Address A40..A47 or Channel CH41..CH48.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="subaddress6" type="text" required="true">
+                       <label>Channel CH49..CH56 Address</label>
+                       <description>The velbus sub-address 6 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               DALI Address A48..A55 or Channel CH49..CH56.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="subaddress7" type="text" required="true">
+                       <label>Channel CH57..CH64 Address</label>
+                       <description>The velbus sub-address 7 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               DALI Address A56..A63 or Channel CH57..CH64.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="subaddress8" type="text" required="true">
+                       <label>Channel CH65..CH72 Address</label>
+                       <description>The velbus sub-address 8 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               DALI Group G0..G7 or Channel CH65..CH72.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="subaddress9" type="text" required="true">
+                       <label>Channel CH73..CH80 Address</label>
+                       <description>The velbus sub-address 9 of the device (FF = disabled). In the VelbusLink application it's identified by
+                               DALI Group G8..G15 or Channel CH73..CH80.</description>
+                       <default>FF</default>
+               </parameter>
+               <parameter name="refresh" type="integer" unit="s">
+                       <label>Refresh Interval</label>
+                       <description>Refresh interval for the temperature sensor (in seconds), default 300. If set to 0 or left empty, no
+                               refresh will be scheduled.</description>
+                       <default>300</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH1" type="text">
+                       <label>CH1 Name</label>
+                       <description>The name of CH1.</description>
+                       <default>A0</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH2" type="text">
+                       <label>CH2 Name</label>
+                       <description>The name of CH2.</description>
+                       <default>A1</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH3" type="text">
+                       <label>CH3 Name</label>
+                       <description>The name of CH3.</description>
+                       <default>A2</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH4" type="text">
+                       <label>A3 Name</label>
+                       <description>The name of CH4.</description>
+                       <default>CH4</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH5" type="text">
+                       <label>CH5 Name</label>
+                       <description>The name of CH5.</description>
+                       <default>A4</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH6" type="text">
+                       <label>CH6 Name</label>
+                       <description>The name of CH6.</description>
+                       <default>A5</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH7" type="text">
+                       <label>CH7 Name</label>
+                       <description>The name of CH7.</description>
+                       <default>A6</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH8" type="text">
+                       <label>CH8 Name</label>
+                       <description>The name of CH8.</description>
+                       <default>A7</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH9" type="text">
+                       <label>CH9 Name</label>
+                       <description>The name of CH9.</description>
+                       <default>A8</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH10" type="text">
+                       <label>CH10 Name</label>
+                       <description>The name of CH10.</description>
+                       <default>A9</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH11" type="text">
+                       <label>CH11 Name</label>
+                       <description>The name of CH11.</description>
+                       <default>A10</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH12" type="text">
+                       <label>CH12 Name</label>
+                       <description>The name of CH12.</description>
+                       <default>A11</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH13" type="text">
+                       <label>CH13 Name</label>
+                       <description>The name of CH13.</description>
+                       <default>A12</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH14" type="text">
+                       <label>CH14 Name</label>
+                       <description>The name of CH14.</description>
+                       <default>A13</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH15" type="text">
+                       <label>CH15 Name</label>
+                       <description>The name of CH15.</description>
+                       <default>A14</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH16" type="text">
+                       <label>CH16 Name</label>
+                       <description>The name of CH16.</description>
+                       <default>A15</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH17" type="text">
+                       <label>CH17 Name</label>
+                       <description>The name of CH17.</description>
+                       <default>A16</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH18" type="text">
+                       <label>CH18 Name</label>
+                       <description>The name of CH18.</description>
+                       <default>A17</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH19" type="text">
+                       <label>CH19 Name</label>
+                       <description>The name of CH19.</description>
+                       <default>A18</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH20" type="text">
+                       <label>CH20 Name</label>
+                       <description>The name of CH20.</description>
+                       <default>A19</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH21" type="text">
+                       <label>CH21 Name</label>
+                       <description>The name of CH21.</description>
+                       <default>A20</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH22" type="text">
+                       <label>CH22 Name</label>
+                       <description>The name of CH22.</description>
+                       <default>A21</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH23" type="text">
+                       <label>CH23 Name</label>
+                       <description>The name of CH23.</description>
+                       <default>A22</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH24" type="text">
+                       <label>CH24 Name</label>
+                       <description>The name of CH24.</description>
+                       <default>A23</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH25" type="text">
+                       <label>CH25 Name</label>
+                       <description>The name of CH25.</description>
+                       <default>A24</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH26" type="text">
+                       <label>CH26 Name</label>
+                       <description>The name of CH26.</description>
+                       <default>A25</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH27" type="text">
+                       <label>CH27 Name</label>
+                       <description>The name of CH27.</description>
+                       <default>A26</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH28" type="text">
+                       <label>CH28 Name</label>
+                       <description>The name of CH28.</description>
+                       <default>A27</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH29" type="text">
+                       <label>CH29 Name</label>
+                       <description>The name of CH29.</description>
+                       <default>A28</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH30" type="text">
+                       <label>CH30 Name</label>
+                       <description>The name of CH30.</description>
+                       <default>A29</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH31" type="text">
+                       <label>CH31 Name</label>
+                       <description>The name of CH31.</description>
+                       <default>A30</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH32" type="text">
+                       <label>CH32 Name</label>
+                       <description>The name of CH32.</description>
+                       <default>A31</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH33" type="text">
+                       <label>CH33 Name</label>
+                       <description>The name of CH33.</description>
+                       <default>A32</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH34" type="text">
+                       <label>CH34 Name</label>
+                       <description>The name of CH34.</description>
+                       <default>A33</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH35" type="text">
+                       <label>CH35 Name</label>
+                       <description>The name of CH35.</description>
+                       <default>A34</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH36" type="text">
+                       <label>CH36 Name</label>
+                       <description>The name of CH36.</description>
+                       <default>A35</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH37" type="text">
+                       <label>CH37 Name</label>
+                       <description>The name of CH37.</description>
+                       <default>A36</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH38" type="text">
+                       <label>CH38 Name</label>
+                       <description>The name of CH38.</description>
+                       <default>A37</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH39" type="text">
+                       <label>CH39 Name</label>
+                       <description>The name of CH39.</description>
+                       <default>A38</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH40" type="text">
+                       <label>CH40 Name</label>
+                       <description>The name of CH40.</description>
+                       <default>A39</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH41" type="text">
+                       <label>CH41 Name</label>
+                       <description>The name of CH41.</description>
+                       <default>A40</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH42" type="text">
+                       <label>CH42 Name</label>
+                       <description>The name of CH42.</description>
+                       <default>A41</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH43" type="text">
+                       <label>CH43 Name</label>
+                       <description>The name of CH43.</description>
+                       <default>A42</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH44" type="text">
+                       <label>CH44 Name</label>
+                       <description>The name of CH44.</description>
+                       <default>A43</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH45" type="text">
+                       <label>CH45 Name</label>
+                       <description>The name of CH45.</description>
+                       <default>A44</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH46" type="text">
+                       <label>CH46 Name</label>
+                       <description>The name of CH46.</description>
+                       <default>A45</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH47" type="text">
+                       <label>CH47 Name</label>
+                       <description>The name of CH47.</description>
+                       <default>A46</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH48" type="text">
+                       <label>CH48 Name</label>
+                       <description>The name of CH48.</description>
+                       <default>A47</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH49" type="text">
+                       <label>CH49 Name</label>
+                       <description>The name of CH49.</description>
+                       <default>A48</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH50" type="text">
+                       <label>CH50 Name</label>
+                       <description>The name of CH50.</description>
+                       <default>A39</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH51" type="text">
+                       <label>CH51 Name</label>
+                       <description>The name of CH51.</description>
+                       <default>A50</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH52" type="text">
+                       <label>CH52 Name</label>
+                       <description>The name of CH52.</description>
+                       <default>A51</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH53" type="text">
+                       <label>CH53 Name</label>
+                       <description>The name of CH53.</description>
+                       <default>A52</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH54" type="text">
+                       <label>CH54 Name</label>
+                       <description>The name of CH54.</description>
+                       <default>A53</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH55" type="text">
+                       <label>CH55 Name</label>
+                       <description>The name of CH55.</description>
+                       <default>A54</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH56" type="text">
+                       <label>CH56 Name</label>
+                       <description>The name of CH56.</description>
+                       <default>A55</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH57" type="text">
+                       <label>CH57 Name</label>
+                       <description>The name of CH57.</description>
+                       <default>A56</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH58" type="text">
+                       <label>CH58 Name</label>
+                       <description>The name of CH58.</description>
+                       <default>A57</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH59" type="text">
+                       <label>CH59 Name</label>
+                       <description>The name of CH59.</description>
+                       <default>A58</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH60" type="text">
+                       <label>CH60 Name</label>
+                       <description>The name of CH60.</description>
+                       <default>A59</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH61" type="text">
+                       <label>CH61 Name</label>
+                       <description>The name of CH61.</description>
+                       <default>A60</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH62" type="text">
+                       <label>CH62 Name</label>
+                       <description>The name of CH62.</description>
+                       <default>A61</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH63" type="text">
+                       <label>CH63 Name</label>
+                       <description>The name of CH63.</description>
+                       <default>A62</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH64" type="text">
+                       <label>CH64 Name</label>
+                       <description>The name of CH64.</description>
+                       <default>A63</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH65" type="text">
+                       <label>CH65 Name</label>
+                       <description>The name of CH65.</description>
+                       <default>G0</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH66" type="text">
+                       <label>CH66 Name</label>
+                       <description>The name of CH66.</description>
+                       <default>G1</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH67" type="text">
+                       <label>CH67 Name</label>
+                       <description>The name of CH67.</description>
+                       <default>G2</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH68" type="text">
+                       <label>CH68 Name</label>
+                       <description>The name of CH68.</description>
+                       <default>G3</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH69" type="text">
+                       <label>CH69 Name</label>
+                       <description>The name of CH69.</description>
+                       <default>G4</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH70" type="text">
+                       <label>CH70 Name</label>
+                       <description>The name of CH70.</description>
+                       <default>G5</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH71" type="text">
+                       <label>CH71 Name</label>
+                       <description>The name of CH71.</description>
+                       <default>G6</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH72" type="text">
+                       <label>CH72 Name</label>
+                       <description>The name of CH72.</description>
+                       <default>G7</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH73" type="text">
+                       <label>CH73 Name</label>
+                       <description>The name of CH73.</description>
+                       <default>G8</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH74" type="text">
+                       <label>CH74 Name</label>
+                       <description>The name of CH74.</description>
+                       <default>G9</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH75" type="text">
+                       <label>CH75 Name</label>
+                       <description>The name of CH75.</description>
+                       <default>G10</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH76" type="text">
+                       <label>CH76 Name</label>
+                       <description>The name of CH76.</description>
+                       <default>G11</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH77" type="text">
+                       <label>CH77 Name</label>
+                       <description>The name of CH77.</description>
+                       <default>G12</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH78" type="text">
+                       <label>CH78 Name</label>
+                       <description>The name of CH78.</description>
+                       <default>G13</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH79" type="text">
+                       <label>CH79 Name</label>
+                       <description>The name of CH79.</description>
+                       <default>G14</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH80" type="text">
+                       <label>CH80 Name</label>
+                       <description>The name of CH80.</description>
+                       <default>G15</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="CH81" type="text">
+                       <label>CH81 Name</label>
+                       <description>The name of CH81.</description>
+                       <default>Broadcast</default>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL1" type="text">
+                       <label>Virtual Light 1</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH1,CH2,CH3,CH4)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL2" type="text">
+                       <label>Virtual Light 2</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH5,CH6,CH7,CH8)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL3" type="text">
+                       <label>Virtual Light 3</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH9,CH10,CH11,CH12)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL4" type="text">
+                       <label>Virtual Light 4</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH13,CH14,CH15,CH16)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL5" type="text">
+                       <label>Virtual Light 5</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH17,CH18,CH19,CH20)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL6" type="text">
+                       <label>Virtual Light 6</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH21,CH22,CH23,CH24)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL7" type="text">
+                       <label>Virtual Light 7</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH25,CH26,CH27,CH28)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL8" type="text">
+                       <label>Virtual Light 8</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH29,CH30,CH31,CH32)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL9" type="text">
+                       <label>Virtual Light 9</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH33,CH34,CH35,CH36)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL10" type="text">
+                       <label>Virtual Light 10</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH37,CH38,CH39,CH40)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL11" type="text">
+                       <label>Virtual Light 11</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH41,CH42,CH43,CH44)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL12" type="text">
+                       <label>Virtual Light 12</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH45,CH46,CH47,CH48)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL13" type="text">
+                       <label>Virtual Light 13</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH49,CH50,CH51,CH52)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL14" type="text">
+                       <label>Virtual Light 14</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH53,CH54,CH55,CH56)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL15" type="text">
+                       <label>Virtual Light 15</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH57,CH58,CH59,CH60)</description>
+                       <advanced>true</advanced>
+               </parameter>
+               <parameter name="VL16" type="text">
+                       <label>Virtual Light 16</label>
+                       <description>Create a virtual color light from 3 or 4 channels. Format:
+                               Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to
+                               CH64. (e.g.
+                               CH61,CH62,CH63,CH64)</description>
+                       <advanced>true</advanced>
+               </parameter>
+       </config-description>
+
 </config-description:config-descriptions>
index fba843337328c1c8966e9e63363db6d85c0fb49a..3b4686df9a9cb530fd655eac77f3dba15cab38e1 100644 (file)
@@ -29,6 +29,8 @@ thing-type.velbus.vmb1ts.label = VMB1TS
 thing-type.velbus.vmb1ts.description = Temperature Sensor Module
 thing-type.velbus.vmb2bl.label = VMB2BL
 thing-type.velbus.vmb2bl.description = 2-channel blind control module
+thing-type.velbus.vmb2ble-10.label = VMB2BLE-10
+thing-type.velbus.vmb2ble-10.description = 2-channel blind control module with extended possibilities
 thing-type.velbus.vmb2ble.label = VMB2BLE
 thing-type.velbus.vmb2ble.description = 2-channel blind control module with extended possibilities
 thing-type.velbus.vmb2pbn.label = VMB2PBN
@@ -41,12 +43,18 @@ thing-type.velbus.vmb4pb.label = VMB4PB
 thing-type.velbus.vmb4pb.description = 4 button interface module
 thing-type.velbus.vmb4ry.label = VMB4RY
 thing-type.velbus.vmb4ry.description = 4-channel relay module
+thing-type.velbus.vmb4ryld-10.label = VMB4RYLD-10
+thing-type.velbus.vmb4ryld-10.description = 4-channel relay module with voltage outputs
 thing-type.velbus.vmb4ryld.label = VMB4RYLD
 thing-type.velbus.vmb4ryld.description = 4-channel relay module with voltage outputs
+thing-type.velbus.vmb4ryno-10.label = VMB4RYNO-10
+thing-type.velbus.vmb4ryno-10.description = 4-channel relay module with potential-free contacts
 thing-type.velbus.vmb4ryno.label = VMB4RYNO
 thing-type.velbus.vmb4ryno.description = 4-channel relay module with potential-free contacts
 thing-type.velbus.vmb6in.label = VMB6IN
 thing-type.velbus.vmb6in.description = 6-channel input module
+thing-type.velbus.vmb6pbn-20.label = VMB6PBN-20
+thing-type.velbus.vmb6pbn-20.description = 6 button interface module
 thing-type.velbus.vmb6pbn.label = VMB6PBN
 thing-type.velbus.vmb6pbn.description = Push-button interface module for Niko 4- or 6-fold push-button
 thing-type.velbus.vmb7in.label = VMB7IN
@@ -57,38 +65,62 @@ thing-type.velbus.vmb8pb.label = VMB8PB
 thing-type.velbus.vmb8pb.description = 8-Channel Push Button module
 thing-type.velbus.vmb8pbu.label = VMB8PBU
 thing-type.velbus.vmb8pbu.description = Push-button interface with 8 channels for universal mounting
+thing-type.velbus.vmbdali-20.label = VMBDALI-20
+thing-type.velbus.vmbdali-20.description = DALI gateway module
+thing-type.velbus.vmbdali.label = VMBDALI
+thing-type.velbus.vmbdali.description = DALI gateway module
 thing-type.velbus.vmbdme.label = VMBDME
 thing-type.velbus.vmbdme.description = Dimmer for electronic/resistive load
 thing-type.velbus.vmbdmi.label = VMBDMI
 thing-type.velbus.vmbdmi.description = Single channel triac dimmer for resistive and inductive loads
 thing-type.velbus.vmbdmir.label = VMBDMI-R
 thing-type.velbus.vmbdmir.description = Single channel triac dimmer for resistive and inductive loads
+thing-type.velbus.vmbel1-20.label = VMBEL1-20
+thing-type.velbus.vmbel1-20.description = Edge-lit one touch button module
 thing-type.velbus.vmbel1.label = VMBEL1
 thing-type.velbus.vmbel1.description = Edge-lit one touch button module
+thing-type.velbus.vmbel2-20.label = VMBEL2-20
+thing-type.velbus.vmbel2-20.description = Edge-lit two touch buttons module
 thing-type.velbus.vmbel2.label = VMBEL2
 thing-type.velbus.vmbel2.description = Edge-lit two touch buttons module
+thing-type.velbus.vmbel4-20.label = VMBEL4-20
+thing-type.velbus.vmbel4-20.description = Edge-lit four touch buttons module
 thing-type.velbus.vmbel4.label = VMBEL4
 thing-type.velbus.vmbel4.description = Edge-lit four touch buttons module
+thing-type.velbus.vmbel4pir-20.label = VMBEL4PIR-20
+thing-type.velbus.vmbel4pir-20.description = Edge-lit Motion detector with four touch button
+thing-type.velbus.vmbelo-20.label = VMBELO-20
+thing-type.velbus.vmbelo-20.description = Edge-lit touch panel with Oled display
 thing-type.velbus.vmbelo.label = VMBELO
 thing-type.velbus.vmbelo.description = Edge-lit touch panel with Oled display
 thing-type.velbus.vmbelpir.label = VMBELPIR
 thing-type.velbus.vmbelpir.description = Edge-lit Motion detector with one touch button
 thing-type.velbus.vmbgp1-2.label = VMBGP1-2
 thing-type.velbus.vmbgp1-2.description = Glass control module with 1 touch key (Edition 2)
+thing-type.velbus.vmbgp1-20.label = VMBGP1-20
+thing-type.velbus.vmbgp1-20.description = Glass control module with 1 touch key
 thing-type.velbus.vmbgp1.label = VMBGP1
 thing-type.velbus.vmbgp1.description = Glass control module with 1 touch key
 thing-type.velbus.vmbgp2-2.label = VMBGP2-2
 thing-type.velbus.vmbgp2-2.description = Glass control module with 2 touch keys (Edition 2)
+thing-type.velbus.vmbgp2-20.label = VMBGP2-20
+thing-type.velbus.vmbgp2-20.description = Glass control module with 2 touch keys
 thing-type.velbus.vmbgp2.label = VMBGP2
 thing-type.velbus.vmbgp2.description = Glass control module with 2 touch keys
 thing-type.velbus.vmbgp4-2.label = VMBGP4-2
 thing-type.velbus.vmbgp4-2.description = Glass control module with 4 touch keys (Edition 2)
+thing-type.velbus.vmbgp4-20.label = VMBGP4-20
+thing-type.velbus.vmbgp4-20.description = Glass control module with 4 touch keys
 thing-type.velbus.vmbgp4.label = VMBGP4
 thing-type.velbus.vmbgp4.description = Glass control module with 4 touch keys
 thing-type.velbus.vmbgp4pir-2.label = VMBGP4PIR-2
 thing-type.velbus.vmbgp4pir-2.description = Glass control module with 4 touch keys and built-in motion and twilight sensor (Edition 2)
+thing-type.velbus.vmbgp4pir-20.label = VMBGP4PIR-20
+thing-type.velbus.vmbgp4pir-20.description = Glass control module with 4 touch keys and built-in motion and twilight sensor
 thing-type.velbus.vmbgp4pir.label = VMBGP4PIR
 thing-type.velbus.vmbgp4pir.description = Glass control module with 4 touch keys and built-in motion and twilight sensor
+thing-type.velbus.vmbgpo-20.label = VMBGPO-20
+thing-type.velbus.vmbgpo-20.description = Glass control module with oled display
 thing-type.velbus.vmbgpo.label = VMBGPO
 thing-type.velbus.vmbgpo.description = Glass control module with oled display
 thing-type.velbus.vmbgpod-2.label = VMBGPOD-2
@@ -244,6 +276,14 @@ thing-type.config.velbus.33channelDeviceWithTemperatureSensor.address.label = Ad
 thing-type.config.velbus.33channelDeviceWithTemperatureSensor.address.description = The velbus address of the device
 thing-type.config.velbus.33channelDeviceWithTemperatureSensor.refresh.label = Refresh Interval
 thing-type.config.velbus.33channelDeviceWithTemperatureSensor.refresh.description = Refresh interval for the temperature sensor (in seconds), default 300. If set to 0 or left empty, no refresh will be scheduled.
+thing-type.config.velbus.33channelDeviceWithTemperatureSensor.subaddress1.label = Channel CH9..CH16 Address
+thing-type.config.velbus.33channelDeviceWithTemperatureSensor.subaddress1.description = The velbus sub-address 1 of the device (FF = disabled). In the VelbusLink application it's identified by Page 3-4 or Pushbuttons 9-16.
+thing-type.config.velbus.33channelDeviceWithTemperatureSensor.subaddress2.label = Channel CH17..CH24 Address
+thing-type.config.velbus.33channelDeviceWithTemperatureSensor.subaddress2.description = The velbus sub-address 2 of the device (FF = disabled). In the VelbusLink application it's identified by Page 5-6 or Pushbuttons 17-24.
+thing-type.config.velbus.33channelDeviceWithTemperatureSensor.subaddress3.label = Channel CH25..CH32 Address
+thing-type.config.velbus.33channelDeviceWithTemperatureSensor.subaddress3.description = The velbus sub-address 3 of the device (FF = disabled). In the VelbusLink application it's identified by Page 7-8 or Pushbuttons 25-32.
+thing-type.config.velbus.33channelDeviceWithTemperatureSensor.subaddress4.label = Channel CH33 Address
+thing-type.config.velbus.33channelDeviceWithTemperatureSensor.subaddress4.description = The velbus sub-address 4 of the device (FF = disabled). In the VelbusLink application it's identified by Sensor or Thermostat.
 thing-type.config.velbus.4channelDevice.CH1.label = CH1 Name
 thing-type.config.velbus.4channelDevice.CH1.description = The name of CH1.
 thing-type.config.velbus.4channelDevice.CH2.label = CH2 Name
@@ -372,6 +412,222 @@ thing-type.config.velbus.7channelDeviceWithTemperatureSensor.address.label = Add
 thing-type.config.velbus.7channelDeviceWithTemperatureSensor.address.description = The velbus address of the device
 thing-type.config.velbus.7channelDeviceWithTemperatureSensor.refresh.label = Refresh Interval
 thing-type.config.velbus.7channelDeviceWithTemperatureSensor.refresh.description = Refresh interval for the temperature sensor (in seconds), default 300. If set to 0 or left empty, no refresh will be scheduled.
+thing-type.config.velbus.81channelDevice.CH1.label = CH1 Name
+thing-type.config.velbus.81channelDevice.CH1.description = The name of CH1.
+thing-type.config.velbus.81channelDevice.CH10.label = CH10 Name
+thing-type.config.velbus.81channelDevice.CH10.description = The name of CH10.
+thing-type.config.velbus.81channelDevice.CH11.label = CH11 Name
+thing-type.config.velbus.81channelDevice.CH11.description = The name of CH11.
+thing-type.config.velbus.81channelDevice.CH12.label = CH12 Name
+thing-type.config.velbus.81channelDevice.CH12.description = The name of CH12.
+thing-type.config.velbus.81channelDevice.CH13.label = CH13 Name
+thing-type.config.velbus.81channelDevice.CH13.description = The name of CH13.
+thing-type.config.velbus.81channelDevice.CH14.label = CH14 Name
+thing-type.config.velbus.81channelDevice.CH14.description = The name of CH14.
+thing-type.config.velbus.81channelDevice.CH15.label = CH15 Name
+thing-type.config.velbus.81channelDevice.CH15.description = The name of CH15.
+thing-type.config.velbus.81channelDevice.CH16.label = CH16 Name
+thing-type.config.velbus.81channelDevice.CH16.description = The name of CH16.
+thing-type.config.velbus.81channelDevice.CH17.label = CH17 Name
+thing-type.config.velbus.81channelDevice.CH17.description = The name of CH17.
+thing-type.config.velbus.81channelDevice.CH18.label = CH18 Name
+thing-type.config.velbus.81channelDevice.CH18.description = The name of CH18.
+thing-type.config.velbus.81channelDevice.CH19.label = CH19 Name
+thing-type.config.velbus.81channelDevice.CH19.description = The name of CH19.
+thing-type.config.velbus.81channelDevice.CH2.label = CH2 Name
+thing-type.config.velbus.81channelDevice.CH2.description = The name of CH2.
+thing-type.config.velbus.81channelDevice.CH20.label = CH20 Name
+thing-type.config.velbus.81channelDevice.CH20.description = The name of CH20.
+thing-type.config.velbus.81channelDevice.CH21.label = CH21 Name
+thing-type.config.velbus.81channelDevice.CH21.description = The name of CH21.
+thing-type.config.velbus.81channelDevice.CH22.label = CH22 Name
+thing-type.config.velbus.81channelDevice.CH22.description = The name of CH22.
+thing-type.config.velbus.81channelDevice.CH23.label = CH23 Name
+thing-type.config.velbus.81channelDevice.CH23.description = The name of CH23.
+thing-type.config.velbus.81channelDevice.CH24.label = CH24 Name
+thing-type.config.velbus.81channelDevice.CH24.description = The name of CH24.
+thing-type.config.velbus.81channelDevice.CH25.label = CH25 Name
+thing-type.config.velbus.81channelDevice.CH25.description = The name of CH25.
+thing-type.config.velbus.81channelDevice.CH26.label = CH26 Name
+thing-type.config.velbus.81channelDevice.CH26.description = The name of CH26.
+thing-type.config.velbus.81channelDevice.CH27.label = CH27 Name
+thing-type.config.velbus.81channelDevice.CH27.description = The name of CH27.
+thing-type.config.velbus.81channelDevice.CH28.label = CH28 Name
+thing-type.config.velbus.81channelDevice.CH28.description = The name of CH28.
+thing-type.config.velbus.81channelDevice.CH29.label = CH29 Name
+thing-type.config.velbus.81channelDevice.CH29.description = The name of CH29.
+thing-type.config.velbus.81channelDevice.CH3.label = CH3 Name
+thing-type.config.velbus.81channelDevice.CH3.description = The name of CH3.
+thing-type.config.velbus.81channelDevice.CH30.label = CH30 Name
+thing-type.config.velbus.81channelDevice.CH30.description = The name of CH30.
+thing-type.config.velbus.81channelDevice.CH31.label = CH31 Name
+thing-type.config.velbus.81channelDevice.CH31.description = The name of CH31.
+thing-type.config.velbus.81channelDevice.CH32.label = CH32 Name
+thing-type.config.velbus.81channelDevice.CH32.description = The name of CH32.
+thing-type.config.velbus.81channelDevice.CH33.label = CH33 Name
+thing-type.config.velbus.81channelDevice.CH33.description = The name of CH33.
+thing-type.config.velbus.81channelDevice.CH34.label = CH34 Name
+thing-type.config.velbus.81channelDevice.CH34.description = The name of CH34.
+thing-type.config.velbus.81channelDevice.CH35.label = CH35 Name
+thing-type.config.velbus.81channelDevice.CH35.description = The name of CH35.
+thing-type.config.velbus.81channelDevice.CH36.label = CH36 Name
+thing-type.config.velbus.81channelDevice.CH36.description = The name of CH36.
+thing-type.config.velbus.81channelDevice.CH37.label = CH37 Name
+thing-type.config.velbus.81channelDevice.CH37.description = The name of CH37.
+thing-type.config.velbus.81channelDevice.CH38.label = CH38 Name
+thing-type.config.velbus.81channelDevice.CH38.description = The name of CH38.
+thing-type.config.velbus.81channelDevice.CH39.label = CH39 Name
+thing-type.config.velbus.81channelDevice.CH39.description = The name of CH39.
+thing-type.config.velbus.81channelDevice.CH4.label = A3 Name
+thing-type.config.velbus.81channelDevice.CH4.description = The name of CH4.
+thing-type.config.velbus.81channelDevice.CH40.label = CH40 Name
+thing-type.config.velbus.81channelDevice.CH40.description = The name of CH40.
+thing-type.config.velbus.81channelDevice.CH41.label = CH41 Name
+thing-type.config.velbus.81channelDevice.CH41.description = The name of CH41.
+thing-type.config.velbus.81channelDevice.CH42.label = CH42 Name
+thing-type.config.velbus.81channelDevice.CH42.description = The name of CH42.
+thing-type.config.velbus.81channelDevice.CH43.label = CH43 Name
+thing-type.config.velbus.81channelDevice.CH43.description = The name of CH43.
+thing-type.config.velbus.81channelDevice.CH44.label = CH44 Name
+thing-type.config.velbus.81channelDevice.CH44.description = The name of CH44.
+thing-type.config.velbus.81channelDevice.CH45.label = CH45 Name
+thing-type.config.velbus.81channelDevice.CH45.description = The name of CH45.
+thing-type.config.velbus.81channelDevice.CH46.label = CH46 Name
+thing-type.config.velbus.81channelDevice.CH46.description = The name of CH46.
+thing-type.config.velbus.81channelDevice.CH47.label = CH47 Name
+thing-type.config.velbus.81channelDevice.CH47.description = The name of CH47.
+thing-type.config.velbus.81channelDevice.CH48.label = CH48 Name
+thing-type.config.velbus.81channelDevice.CH48.description = The name of CH48.
+thing-type.config.velbus.81channelDevice.CH49.label = CH49 Name
+thing-type.config.velbus.81channelDevice.CH49.description = The name of CH49.
+thing-type.config.velbus.81channelDevice.CH5.label = CH5 Name
+thing-type.config.velbus.81channelDevice.CH5.description = The name of CH5.
+thing-type.config.velbus.81channelDevice.CH50.label = CH50 Name
+thing-type.config.velbus.81channelDevice.CH50.description = The name of CH50.
+thing-type.config.velbus.81channelDevice.CH51.label = CH51 Name
+thing-type.config.velbus.81channelDevice.CH51.description = The name of CH51.
+thing-type.config.velbus.81channelDevice.CH52.label = CH52 Name
+thing-type.config.velbus.81channelDevice.CH52.description = The name of CH52.
+thing-type.config.velbus.81channelDevice.CH53.label = CH53 Name
+thing-type.config.velbus.81channelDevice.CH53.description = The name of CH53.
+thing-type.config.velbus.81channelDevice.CH54.label = CH54 Name
+thing-type.config.velbus.81channelDevice.CH54.description = The name of CH54.
+thing-type.config.velbus.81channelDevice.CH55.label = CH55 Name
+thing-type.config.velbus.81channelDevice.CH55.description = The name of CH55.
+thing-type.config.velbus.81channelDevice.CH56.label = CH56 Name
+thing-type.config.velbus.81channelDevice.CH56.description = The name of CH56.
+thing-type.config.velbus.81channelDevice.CH57.label = CH57 Name
+thing-type.config.velbus.81channelDevice.CH57.description = The name of CH57.
+thing-type.config.velbus.81channelDevice.CH58.label = CH58 Name
+thing-type.config.velbus.81channelDevice.CH58.description = The name of CH58.
+thing-type.config.velbus.81channelDevice.CH59.label = CH59 Name
+thing-type.config.velbus.81channelDevice.CH59.description = The name of CH59.
+thing-type.config.velbus.81channelDevice.CH6.label = CH6 Name
+thing-type.config.velbus.81channelDevice.CH6.description = The name of CH6.
+thing-type.config.velbus.81channelDevice.CH60.label = CH60 Name
+thing-type.config.velbus.81channelDevice.CH60.description = The name of CH60.
+thing-type.config.velbus.81channelDevice.CH61.label = CH61 Name
+thing-type.config.velbus.81channelDevice.CH61.description = The name of CH61.
+thing-type.config.velbus.81channelDevice.CH62.label = CH62 Name
+thing-type.config.velbus.81channelDevice.CH62.description = The name of CH62.
+thing-type.config.velbus.81channelDevice.CH63.label = CH63 Name
+thing-type.config.velbus.81channelDevice.CH63.description = The name of CH63.
+thing-type.config.velbus.81channelDevice.CH64.label = CH64 Name
+thing-type.config.velbus.81channelDevice.CH64.description = The name of CH64.
+thing-type.config.velbus.81channelDevice.CH65.label = CH65 Name
+thing-type.config.velbus.81channelDevice.CH65.description = The name of CH65.
+thing-type.config.velbus.81channelDevice.CH66.label = CH66 Name
+thing-type.config.velbus.81channelDevice.CH66.description = The name of CH66.
+thing-type.config.velbus.81channelDevice.CH67.label = CH67 Name
+thing-type.config.velbus.81channelDevice.CH67.description = The name of CH67.
+thing-type.config.velbus.81channelDevice.CH68.label = CH68 Name
+thing-type.config.velbus.81channelDevice.CH68.description = The name of CH68.
+thing-type.config.velbus.81channelDevice.CH69.label = CH69 Name
+thing-type.config.velbus.81channelDevice.CH69.description = The name of CH69.
+thing-type.config.velbus.81channelDevice.CH7.label = CH7 Name
+thing-type.config.velbus.81channelDevice.CH7.description = The name of CH7.
+thing-type.config.velbus.81channelDevice.CH70.label = CH70 Name
+thing-type.config.velbus.81channelDevice.CH70.description = The name of CH70.
+thing-type.config.velbus.81channelDevice.CH71.label = CH71 Name
+thing-type.config.velbus.81channelDevice.CH71.description = The name of CH71.
+thing-type.config.velbus.81channelDevice.CH72.label = CH72 Name
+thing-type.config.velbus.81channelDevice.CH72.description = The name of CH72.
+thing-type.config.velbus.81channelDevice.CH73.label = CH73 Name
+thing-type.config.velbus.81channelDevice.CH73.description = The name of CH73.
+thing-type.config.velbus.81channelDevice.CH74.label = CH74 Name
+thing-type.config.velbus.81channelDevice.CH74.description = The name of CH74.
+thing-type.config.velbus.81channelDevice.CH75.label = CH75 Name
+thing-type.config.velbus.81channelDevice.CH75.description = The name of CH75.
+thing-type.config.velbus.81channelDevice.CH76.label = CH76 Name
+thing-type.config.velbus.81channelDevice.CH76.description = The name of CH76.
+thing-type.config.velbus.81channelDevice.CH77.label = CH77 Name
+thing-type.config.velbus.81channelDevice.CH77.description = The name of CH77.
+thing-type.config.velbus.81channelDevice.CH78.label = CH78 Name
+thing-type.config.velbus.81channelDevice.CH78.description = The name of CH78.
+thing-type.config.velbus.81channelDevice.CH79.label = CH79 Name
+thing-type.config.velbus.81channelDevice.CH79.description = The name of CH79.
+thing-type.config.velbus.81channelDevice.CH8.label = CH8 Name
+thing-type.config.velbus.81channelDevice.CH8.description = The name of CH8.
+thing-type.config.velbus.81channelDevice.CH80.label = CH80 Name
+thing-type.config.velbus.81channelDevice.CH80.description = The name of CH80.
+thing-type.config.velbus.81channelDevice.CH81.label = CH81 Name
+thing-type.config.velbus.81channelDevice.CH81.description = The name of CH81.
+thing-type.config.velbus.81channelDevice.CH9.label = CH9 Name
+thing-type.config.velbus.81channelDevice.CH9.description = The name of CH9.
+thing-type.config.velbus.81channelDevice.VL1.label = Virtual Light 1
+thing-type.config.velbus.81channelDevice.VL1.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH1,CH2,CH3,CH4)
+thing-type.config.velbus.81channelDevice.VL10.label = Virtual Light 10
+thing-type.config.velbus.81channelDevice.VL10.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH37,CH38,CH39,CH40)
+thing-type.config.velbus.81channelDevice.VL11.label = Virtual Light 11
+thing-type.config.velbus.81channelDevice.VL11.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH41,CH42,CH43,CH44)
+thing-type.config.velbus.81channelDevice.VL12.label = Virtual Light 12
+thing-type.config.velbus.81channelDevice.VL12.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH45,CH46,CH47,CH48)
+thing-type.config.velbus.81channelDevice.VL13.label = Virtual Light 13
+thing-type.config.velbus.81channelDevice.VL13.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH49,CH50,CH51,CH52)
+thing-type.config.velbus.81channelDevice.VL14.label = Virtual Light 14
+thing-type.config.velbus.81channelDevice.VL14.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH53,CH54,CH55,CH56)
+thing-type.config.velbus.81channelDevice.VL15.label = Virtual Light 15
+thing-type.config.velbus.81channelDevice.VL15.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH57,CH58,CH59,CH60)
+thing-type.config.velbus.81channelDevice.VL16.label = Virtual Light 16
+thing-type.config.velbus.81channelDevice.VL16.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH61,CH62,CH63,CH64)
+thing-type.config.velbus.81channelDevice.VL2.label = Virtual Light 2
+thing-type.config.velbus.81channelDevice.VL2.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH5,CH6,CH7,CH8)
+thing-type.config.velbus.81channelDevice.VL3.label = Virtual Light 3
+thing-type.config.velbus.81channelDevice.VL3.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH9,CH10,CH11,CH12)
+thing-type.config.velbus.81channelDevice.VL4.label = Virtual Light 4
+thing-type.config.velbus.81channelDevice.VL4.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH13,CH14,CH15,CH16)
+thing-type.config.velbus.81channelDevice.VL5.label = Virtual Light 5
+thing-type.config.velbus.81channelDevice.VL5.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH17,CH18,CH19,CH20)
+thing-type.config.velbus.81channelDevice.VL6.label = Virtual Light 6
+thing-type.config.velbus.81channelDevice.VL6.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH21,CH22,CH23,CH24)
+thing-type.config.velbus.81channelDevice.VL7.label = Virtual Light 7
+thing-type.config.velbus.81channelDevice.VL7.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH25,CH26,CH27,CH28)
+thing-type.config.velbus.81channelDevice.VL8.label = Virtual Light 8
+thing-type.config.velbus.81channelDevice.VL8.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH29,CH30,CH31,CH32)
+thing-type.config.velbus.81channelDevice.VL9.label = Virtual Light 9
+thing-type.config.velbus.81channelDevice.VL9.description = Create a virtual color light from 3 or 4 channels. Format: Red_channel,Green_channel,Blue_channel,White_channel. White_channel is optionnal. From CH1 to CH64. (e.g. CH33,CH34,CH35,CH36)
+thing-type.config.velbus.81channelDevice.address.label = Address
+thing-type.config.velbus.81channelDevice.address.description = The velbus address of the device. In the VelbusLink application it's identified by DALI Address A0..A7 or Channel CH1..CH8.
+thing-type.config.velbus.81channelDevice.refresh.label = Refresh Interval
+thing-type.config.velbus.81channelDevice.refresh.description = Refresh interval for the temperature sensor (in seconds), default 300. If set to 0 or left empty, no refresh will be scheduled.
+thing-type.config.velbus.81channelDevice.subaddress1.label = Channel CH9..CH16 Address
+thing-type.config.velbus.81channelDevice.subaddress1.description = The velbus sub-address 1 of the device (FF = disabled). In the VelbusLink application it's identified by DALI Address A8..A15 or Channel CH9..CH16.
+thing-type.config.velbus.81channelDevice.subaddress2.label = Channel CH17..CH24 Address
+thing-type.config.velbus.81channelDevice.subaddress2.description = The velbus sub-address 2 of the device (FF = disabled). In the VelbusLink application it's identified by DALI Address A16..A23 or Channel CH17..CH24.
+thing-type.config.velbus.81channelDevice.subaddress3.label = Channel CH25..CH32 Address
+thing-type.config.velbus.81channelDevice.subaddress3.description = The velbus sub-address 3 of the device (FF = disabled). In the VelbusLink application it's identified by DALI Address A24..A31 or Channel CH25..CH32.
+thing-type.config.velbus.81channelDevice.subaddress4.label = Channel CH33..CH40 Address
+thing-type.config.velbus.81channelDevice.subaddress4.description = The velbus sub-address 4 of the device (FF = disabled). In the VelbusLink application it's identified by DALI Address A32..A39 or Channel CH33..CH40.
+thing-type.config.velbus.81channelDevice.subaddress5.label = Channel CH41..CH48 Address
+thing-type.config.velbus.81channelDevice.subaddress5.description = The velbus sub-address 5 of the device (FF = disabled). In the VelbusLink application it's identified by DALI Address A40..A47 or Channel CH41..CH48.
+thing-type.config.velbus.81channelDevice.subaddress6.label = Channel CH49..CH56 Address
+thing-type.config.velbus.81channelDevice.subaddress6.description = The velbus sub-address 6 of the device (FF = disabled). In the VelbusLink application it's identified by DALI Address A48..A55 or Channel CH49..CH56.
+thing-type.config.velbus.81channelDevice.subaddress7.label = Channel CH57..CH64 Address
+thing-type.config.velbus.81channelDevice.subaddress7.description = The velbus sub-address 7 of the device (FF = disabled). In the VelbusLink application it's identified by DALI Address A56..A63 or Channel CH57..CH64.
+thing-type.config.velbus.81channelDevice.subaddress8.label = Channel CH65..CH72 Address
+thing-type.config.velbus.81channelDevice.subaddress8.description = The velbus sub-address 8 of the device (FF = disabled). In the VelbusLink application it's identified by DALI Group G0..G7 or Channel CH65..CH72.
+thing-type.config.velbus.81channelDevice.subaddress9.label = Channel CH73..CH80 Address
+thing-type.config.velbus.81channelDevice.subaddress9.description = The velbus sub-address 9 of the device (FF = disabled). In the VelbusLink application it's identified by DALI Group G8..G15 or Channel CH73..CH80.
 thing-type.config.velbus.8channelDevice.CH1.label = CH1 Name
 thing-type.config.velbus.8channelDevice.CH1.description = The name of CH1.
 thing-type.config.velbus.8channelDevice.CH2.label = CH2 Name
@@ -412,6 +668,8 @@ thing-type.config.velbus.9channelDeviceWithTemperatureSensor.address.label = Add
 thing-type.config.velbus.9channelDeviceWithTemperatureSensor.address.description = The velbus address of the device
 thing-type.config.velbus.9channelDeviceWithTemperatureSensor.refresh.label = Refresh Interval
 thing-type.config.velbus.9channelDeviceWithTemperatureSensor.refresh.description = Refresh interval for the temperature sensor (in seconds), default 300. If set to 0 or left empty, no refresh will be scheduled.
+thing-type.config.velbus.9channelDeviceWithTemperatureSensor.subaddress1.label = Channel CH9 Address
+thing-type.config.velbus.9channelDeviceWithTemperatureSensor.subaddress1.description = The velbus sub-address of the device (FF = disabled). In the VelbusLink application it's identified by Sensor or Thermostat.
 thing-type.config.velbus.temperatureSensorDevice.address.label = Address
 thing-type.config.velbus.temperatureSensorDevice.address.description = The velbus address of the device
 thing-type.config.velbus.temperatureSensorDevice.refresh.label = Refresh Interval
@@ -419,10 +677,14 @@ thing-type.config.velbus.temperatureSensorDevice.refresh.description = Refresh i
 
 # channel group types
 
+channel-group-type.velbus.16channelVirtualLight.label = Virtual light
+channel-group-type.velbus.16channelVirtualLight.description = This is a generic module with 16 virtual light channels.
 channel-group-type.velbus.1channelFeedbackModule.label = Feedback
 channel-group-type.velbus.1channelFeedbackModule.description = This is a generic module with 1 feedback channel.
 channel-group-type.velbus.1channelInputModuleWithTemperatureSensor.label = Input with Temperature Sensor
 channel-group-type.velbus.1channelInputModuleWithTemperatureSensor.description = This is a generic module with 8 input channels and a temperature sensor.
+channel-group-type.velbus.1outputModule.label = Output
+channel-group-type.velbus.1outputModule.description = This is a generic module with 1 output.
 channel-group-type.velbus.2channelButtonModule.label = Button
 channel-group-type.velbus.2channelButtonModule.description = This is a generic module with 2 button channels.
 channel-group-type.velbus.2channelFeedbackModule.label = Feedback
@@ -437,6 +699,8 @@ channel-group-type.velbus.4channelAnalogInputModule.label = Analog Input
 channel-group-type.velbus.4channelAnalogInputModule.description = This is a generic analog module with 4 input channels.
 channel-group-type.velbus.4channelAnalogOutputModule.label = Analog Input
 channel-group-type.velbus.4channelAnalogOutputModule.description = This is a generic analog module with 4 output channels.
+channel-group-type.velbus.4channelButtonModule.label = Button
+channel-group-type.velbus.4channelButtonModule.description = This is a generic module with 4 button channels.
 channel-group-type.velbus.4channelCounterModule.label = Counters
 channel-group-type.velbus.4channelCounterModule.description = This is a generic module with 4 counter channels.
 channel-group-type.velbus.4channelFeedbackModule.label = Feedback
@@ -451,6 +715,18 @@ channel-group-type.velbus.6channelInputModule.label = Input
 channel-group-type.velbus.6channelInputModule.description = This is a generic module with 6 input channels.
 channel-group-type.velbus.7channelInputModule.label = Input
 channel-group-type.velbus.7channelInputModule.description = This is a generic module with 7 input channels.
+channel-group-type.velbus.81channelBrightnessModule.label = Brightness
+channel-group-type.velbus.81channelBrightnessModule.description = This is a generic module with 81 brightness channels.
+channel-group-type.velbus.81channelColorModule.label = Color
+channel-group-type.velbus.81channelColorModule.description = This is a generic module with 81 color channels.
+channel-group-type.velbus.81channelFeedbackModule.label = Feedback
+channel-group-type.velbus.81channelFeedbackModule.description = This is a generic module with 81 feedback channels.
+channel-group-type.velbus.81channelInputModule.label = Input
+channel-group-type.velbus.81channelInputModule.description = This is a generic module with 81 input channels.
+channel-group-type.velbus.81channelSceneModule.label = Scene
+channel-group-type.velbus.81channelSceneModule.description = This is a generic module with 81 scene channels.
+channel-group-type.velbus.81channelWhiteColorModule.label = White Color
+channel-group-type.velbus.81channelWhiteColorModule.description = This is a generic module with 81 white color channels.
 channel-group-type.velbus.8channelButtonModule.label = Button
 channel-group-type.velbus.8channelButtonModule.description = This is a generic module with 8 button channels.
 channel-group-type.velbus.8channelFeedbackModule.label = Feedback
@@ -546,6 +822,8 @@ channel-type.velbus.ledFeedback.state.option.SET_LED = On
 channel-type.velbus.ledFeedback.state.option.SLOW_BLINK_LED = Slow blink
 channel-type.velbus.ledFeedback.state.option.FAST_BLINK_LED = Fast blink
 channel-type.velbus.ledFeedback.state.option.VERY_FAST_BLINK_LED = Very fast blink
+channel-type.velbus.light-scene.label = Scene
+channel-type.velbus.light-scene.description = Scene options for DALI network
 channel-type.velbus.minute.label = Minute
 channel-type.velbus.percentage.label = Percentage
 channel-type.velbus.percentage.description = Current percentage
@@ -567,3 +845,213 @@ channel-type.velbus.voltage.label = Voltage
 channel-type.velbus.voltage.description = Currently measured voltage
 channel-type.velbus.windspeed.label = Wind Speed
 channel-type.velbus.windspeed.description = Currently measured wind speed
+
+# channel group types
+
+channel-group-type.velbus.81channelColorTemperatureModule.label = Color Temperature
+channel-group-type.velbus.81channelColorTemperatureModule.description = This is a generic module with 81 color temperature channels.
+
+# thing types config
+
+thing-type.config.velbus.80channelDevice.CH1.label = CH1 Name
+thing-type.config.velbus.80channelDevice.CH1.description = The name of CH1.
+thing-type.config.velbus.80channelDevice.CH10.label = CH10 Name
+thing-type.config.velbus.80channelDevice.CH10.description = The name of CH10.
+thing-type.config.velbus.80channelDevice.CH11.label = CH11 Name
+thing-type.config.velbus.80channelDevice.CH11.description = The name of CH11.
+thing-type.config.velbus.80channelDevice.CH12.label = CH12 Name
+thing-type.config.velbus.80channelDevice.CH12.description = The name of CH12.
+thing-type.config.velbus.80channelDevice.CH13.label = CH13 Name
+thing-type.config.velbus.80channelDevice.CH13.description = The name of CH13.
+thing-type.config.velbus.80channelDevice.CH14.label = CH14 Name
+thing-type.config.velbus.80channelDevice.CH14.description = The name of CH14.
+thing-type.config.velbus.80channelDevice.CH15.label = CH15 Name
+thing-type.config.velbus.80channelDevice.CH15.description = The name of CH15.
+thing-type.config.velbus.80channelDevice.CH16.label = CH16 Name
+thing-type.config.velbus.80channelDevice.CH16.description = The name of CH16.
+thing-type.config.velbus.80channelDevice.CH17.label = CH17 Name
+thing-type.config.velbus.80channelDevice.CH17.description = The name of CH17.
+thing-type.config.velbus.80channelDevice.CH18.label = CH18 Name
+thing-type.config.velbus.80channelDevice.CH18.description = The name of CH18.
+thing-type.config.velbus.80channelDevice.CH19.label = CH19 Name
+thing-type.config.velbus.80channelDevice.CH19.description = The name of CH19.
+thing-type.config.velbus.80channelDevice.CH2.label = CH2 Name
+thing-type.config.velbus.80channelDevice.CH2.description = The name of CH2.
+thing-type.config.velbus.80channelDevice.CH20.label = CH20 Name
+thing-type.config.velbus.80channelDevice.CH20.description = The name of CH20.
+thing-type.config.velbus.80channelDevice.CH21.label = CH21 Name
+thing-type.config.velbus.80channelDevice.CH21.description = The name of CH21.
+thing-type.config.velbus.80channelDevice.CH22.label = CH22 Name
+thing-type.config.velbus.80channelDevice.CH22.description = The name of CH22.
+thing-type.config.velbus.80channelDevice.CH23.label = CH23 Name
+thing-type.config.velbus.80channelDevice.CH23.description = The name of CH23.
+thing-type.config.velbus.80channelDevice.CH24.label = CH24 Name
+thing-type.config.velbus.80channelDevice.CH24.description = The name of CH24.
+thing-type.config.velbus.80channelDevice.CH25.label = CH25 Name
+thing-type.config.velbus.80channelDevice.CH25.description = The name of CH25.
+thing-type.config.velbus.80channelDevice.CH26.label = CH26 Name
+thing-type.config.velbus.80channelDevice.CH26.description = The name of CH26.
+thing-type.config.velbus.80channelDevice.CH27.label = CH27 Name
+thing-type.config.velbus.80channelDevice.CH27.description = The name of CH27.
+thing-type.config.velbus.80channelDevice.CH28.label = CH28 Name
+thing-type.config.velbus.80channelDevice.CH28.description = The name of CH28.
+thing-type.config.velbus.80channelDevice.CH29.label = CH29 Name
+thing-type.config.velbus.80channelDevice.CH29.description = The name of CH29.
+thing-type.config.velbus.80channelDevice.CH3.label = CH3 Name
+thing-type.config.velbus.80channelDevice.CH3.description = The name of CH3.
+thing-type.config.velbus.80channelDevice.CH30.label = CH30 Name
+thing-type.config.velbus.80channelDevice.CH30.description = The name of CH30.
+thing-type.config.velbus.80channelDevice.CH31.label = CH31 Name
+thing-type.config.velbus.80channelDevice.CH31.description = The name of CH31.
+thing-type.config.velbus.80channelDevice.CH32.label = CH32 Name
+thing-type.config.velbus.80channelDevice.CH32.description = The name of CH32.
+thing-type.config.velbus.80channelDevice.CH33.label = CH33 Name
+thing-type.config.velbus.80channelDevice.CH33.description = The name of CH33.
+thing-type.config.velbus.80channelDevice.CH34.label = CH34 Name
+thing-type.config.velbus.80channelDevice.CH34.description = The name of CH34.
+thing-type.config.velbus.80channelDevice.CH35.label = CH35 Name
+thing-type.config.velbus.80channelDevice.CH35.description = The name of CH35.
+thing-type.config.velbus.80channelDevice.CH36.label = CH36 Name
+thing-type.config.velbus.80channelDevice.CH36.description = The name of CH36.
+thing-type.config.velbus.80channelDevice.CH37.label = CH37 Name
+thing-type.config.velbus.80channelDevice.CH37.description = The name of CH37.
+thing-type.config.velbus.80channelDevice.CH38.label = CH38 Name
+thing-type.config.velbus.80channelDevice.CH38.description = The name of CH38.
+thing-type.config.velbus.80channelDevice.CH39.label = CH39 Name
+thing-type.config.velbus.80channelDevice.CH39.description = The name of CH39.
+thing-type.config.velbus.80channelDevice.CH4.label = A3 Name
+thing-type.config.velbus.80channelDevice.CH4.description = The name of CH4.
+thing-type.config.velbus.80channelDevice.CH40.label = CH40 Name
+thing-type.config.velbus.80channelDevice.CH40.description = The name of CH40.
+thing-type.config.velbus.80channelDevice.CH41.label = CH41 Name
+thing-type.config.velbus.80channelDevice.CH41.description = The name of CH41.
+thing-type.config.velbus.80channelDevice.CH42.label = CH42 Name
+thing-type.config.velbus.80channelDevice.CH42.description = The name of CH42.
+thing-type.config.velbus.80channelDevice.CH43.label = CH43 Name
+thing-type.config.velbus.80channelDevice.CH43.description = The name of CH43.
+thing-type.config.velbus.80channelDevice.CH44.label = CH44 Name
+thing-type.config.velbus.80channelDevice.CH44.description = The name of CH44.
+thing-type.config.velbus.80channelDevice.CH45.label = CH45 Name
+thing-type.config.velbus.80channelDevice.CH45.description = The name of CH45.
+thing-type.config.velbus.80channelDevice.CH46.label = CH46 Name
+thing-type.config.velbus.80channelDevice.CH46.description = The name of CH46.
+thing-type.config.velbus.80channelDevice.CH47.label = CH47 Name
+thing-type.config.velbus.80channelDevice.CH47.description = The name of CH47.
+thing-type.config.velbus.80channelDevice.CH48.label = CH48 Name
+thing-type.config.velbus.80channelDevice.CH48.description = The name of CH48.
+thing-type.config.velbus.80channelDevice.CH49.label = CH49 Name
+thing-type.config.velbus.80channelDevice.CH49.description = The name of CH49.
+thing-type.config.velbus.80channelDevice.CH5.label = CH5 Name
+thing-type.config.velbus.80channelDevice.CH5.description = The name of CH5.
+thing-type.config.velbus.80channelDevice.CH50.label = CH50 Name
+thing-type.config.velbus.80channelDevice.CH50.description = The name of CH50.
+thing-type.config.velbus.80channelDevice.CH51.label = CH51 Name
+thing-type.config.velbus.80channelDevice.CH51.description = The name of CH51.
+thing-type.config.velbus.80channelDevice.CH52.label = CH52 Name
+thing-type.config.velbus.80channelDevice.CH52.description = The name of CH52.
+thing-type.config.velbus.80channelDevice.CH53.label = CH53 Name
+thing-type.config.velbus.80channelDevice.CH53.description = The name of CH53.
+thing-type.config.velbus.80channelDevice.CH54.label = CH54 Name
+thing-type.config.velbus.80channelDevice.CH54.description = The name of CH54.
+thing-type.config.velbus.80channelDevice.CH55.label = CH55 Name
+thing-type.config.velbus.80channelDevice.CH55.description = The name of CH55.
+thing-type.config.velbus.80channelDevice.CH56.label = CH56 Name
+thing-type.config.velbus.80channelDevice.CH56.description = The name of CH56.
+thing-type.config.velbus.80channelDevice.CH57.label = CH57 Name
+thing-type.config.velbus.80channelDevice.CH57.description = The name of CH57.
+thing-type.config.velbus.80channelDevice.CH58.label = CH58 Name
+thing-type.config.velbus.80channelDevice.CH58.description = The name of CH58.
+thing-type.config.velbus.80channelDevice.CH59.label = CH59 Name
+thing-type.config.velbus.80channelDevice.CH59.description = The name of CH59.
+thing-type.config.velbus.80channelDevice.CH6.label = CH6 Name
+thing-type.config.velbus.80channelDevice.CH6.description = The name of CH6.
+thing-type.config.velbus.80channelDevice.CH60.label = CH60 Name
+thing-type.config.velbus.80channelDevice.CH60.description = The name of CH60.
+thing-type.config.velbus.80channelDevice.CH61.label = CH61 Name
+thing-type.config.velbus.80channelDevice.CH61.description = The name of CH61.
+thing-type.config.velbus.80channelDevice.CH62.label = CH62 Name
+thing-type.config.velbus.80channelDevice.CH62.description = The name of CH62.
+thing-type.config.velbus.80channelDevice.CH63.label = CH63 Name
+thing-type.config.velbus.80channelDevice.CH63.description = The name of CH63.
+thing-type.config.velbus.80channelDevice.CH64.label = CH64 Name
+thing-type.config.velbus.80channelDevice.CH64.description = The name of CH64.
+thing-type.config.velbus.80channelDevice.CH65.label = CH65 Name
+thing-type.config.velbus.80channelDevice.CH65.description = The name of CH65.
+thing-type.config.velbus.80channelDevice.CH66.label = CH66 Name
+thing-type.config.velbus.80channelDevice.CH66.description = The name of CH66.
+thing-type.config.velbus.80channelDevice.CH67.label = CH67 Name
+thing-type.config.velbus.80channelDevice.CH67.description = The name of CH67.
+thing-type.config.velbus.80channelDevice.CH68.label = CH68 Name
+thing-type.config.velbus.80channelDevice.CH68.description = The name of CH68.
+thing-type.config.velbus.80channelDevice.CH69.label = CH69 Name
+thing-type.config.velbus.80channelDevice.CH69.description = The name of CH69.
+thing-type.config.velbus.80channelDevice.CH7.label = CH7 Name
+thing-type.config.velbus.80channelDevice.CH7.description = The name of CH7.
+thing-type.config.velbus.80channelDevice.CH70.label = CH70 Name
+thing-type.config.velbus.80channelDevice.CH70.description = The name of CH70.
+thing-type.config.velbus.80channelDevice.CH71.label = CH71 Name
+thing-type.config.velbus.80channelDevice.CH71.description = The name of CH71.
+thing-type.config.velbus.80channelDevice.CH72.label = CH72 Name
+thing-type.config.velbus.80channelDevice.CH72.description = The name of CH72.
+thing-type.config.velbus.80channelDevice.CH73.label = CH73 Name
+thing-type.config.velbus.80channelDevice.CH73.description = The name of CH73.
+thing-type.config.velbus.80channelDevice.CH74.label = CH74 Name
+thing-type.config.velbus.80channelDevice.CH74.description = The name of CH74.
+thing-type.config.velbus.80channelDevice.CH75.label = CH75 Name
+thing-type.config.velbus.80channelDevice.CH75.description = The name of CH75.
+thing-type.config.velbus.80channelDevice.CH76.label = CH76 Name
+thing-type.config.velbus.80channelDevice.CH76.description = The name of CH76.
+thing-type.config.velbus.80channelDevice.CH77.label = CH77 Name
+thing-type.config.velbus.80channelDevice.CH77.description = The name of CH77.
+thing-type.config.velbus.80channelDevice.CH78.label = CH78 Name
+thing-type.config.velbus.80channelDevice.CH78.description = The name of CH78.
+thing-type.config.velbus.80channelDevice.CH79.label = CH79 Name
+thing-type.config.velbus.80channelDevice.CH79.description = The name of CH79.
+thing-type.config.velbus.80channelDevice.CH8.label = CH8 Name
+thing-type.config.velbus.80channelDevice.CH8.description = The name of CH8.
+thing-type.config.velbus.80channelDevice.CH80.label = CH80 Name
+thing-type.config.velbus.80channelDevice.CH80.description = The name of CH80.
+thing-type.config.velbus.80channelDevice.CH9.label = CH9 Name
+thing-type.config.velbus.80channelDevice.CH9.description = The name of CH9.
+thing-type.config.velbus.80channelDevice.address.label = Address (Channel A0...7)
+thing-type.config.velbus.80channelDevice.address.description = The velbus address of the device
+thing-type.config.velbus.80channelDevice.refresh.label = Refresh Interval
+thing-type.config.velbus.80channelDevice.refresh.description = Refresh interval for the temperature sensor (in seconds), default 300. If set to 0 or left empty, no refresh will be scheduled.
+thing-type.config.velbus.80channelDevice.subaddress1.label = Channel A8...15
+thing-type.config.velbus.80channelDevice.subaddress1.description = The velbus sub-address 1 of the device (FF = disabled)
+thing-type.config.velbus.80channelDevice.subaddress2.label = Channel A16...23
+thing-type.config.velbus.80channelDevice.subaddress2.description = The velbus sub-address 2 of the device (FF = disabled)
+thing-type.config.velbus.80channelDevice.subaddress3.label = Channel A24...31
+thing-type.config.velbus.80channelDevice.subaddress3.description = The velbus sub-address 3 of the device (FF = disabled)
+thing-type.config.velbus.80channelDevice.subaddress4.label = Channel A32...39
+thing-type.config.velbus.80channelDevice.subaddress4.description = The velbus sub-address 4 of the device (FF = disabled)
+thing-type.config.velbus.80channelDevice.subaddress5.label = Channel A40...47
+thing-type.config.velbus.80channelDevice.subaddress5.description = The velbus sub-address 5 of the device (FF = disabled)
+thing-type.config.velbus.80channelDevice.subaddress6.label = Channel A48...55
+thing-type.config.velbus.80channelDevice.subaddress6.description = The velbus sub-address 6 of the device (FF = disabled)
+thing-type.config.velbus.80channelDevice.subaddress7.label = Channel A56...63
+thing-type.config.velbus.80channelDevice.subaddress7.description = The velbus sub-address 7 of the device (FF = disabled)
+thing-type.config.velbus.80channelDevice.subaddress8.label = Group G0...7
+thing-type.config.velbus.80channelDevice.subaddress8.description = The velbus sub-address 8 of the device (FF = disabled)
+thing-type.config.velbus.80channelDevice.subaddress9.label = Group G8...15
+thing-type.config.velbus.80channelDevice.subaddress9.description = The velbus sub-address 9 of the device (FF = disabled)
+
+# channel group types
+
+channel-group-type.velbus.80channelBrightnessModule.label = Brightness
+channel-group-type.velbus.80channelBrightnessModule.description = This is a generic module with 80 brightness channels.
+channel-group-type.velbus.80channelColorModule.label = Color
+channel-group-type.velbus.80channelColorModule.description = This is a generic module with 80 color channels.
+channel-group-type.velbus.80channelColorTemperatureModule.label = Color Temperature
+channel-group-type.velbus.80channelColorTemperatureModule.description = This is a generic module with 80 color temperature channels.
+channel-group-type.velbus.80channelFeedbackModule.label = Feedback
+channel-group-type.velbus.80channelFeedbackModule.description = This is a generic module with 80 feedback channels.
+channel-group-type.velbus.80channelInputModule.label = Input
+channel-group-type.velbus.80channelInputModule.description = This is a generic module with 80 input channels.
+channel-group-type.velbus.80channelSceneModule.label = Scene
+channel-group-type.velbus.80channelSceneModule.description = This is a generic module with 80 scene channels.
+
+# channel group types
+
+channel-group-type.velbus.80channelButtonModule.label = Button
+channel-group-type.velbus.80channelButtonModule.description = This is a generic module with 80 button channels.
index a4633a69f9aed3d0c72b8d6ba699e46c307380da..920a2e7254567d2985e07a799ed644e5582f09f0 100644 (file)
@@ -8,7 +8,7 @@
                <label>Velbus Serial Bridge</label>
                <description>This bridge represents a Velbus Serial-interface</description>
                <channel-groups>
-                       <channel-group id="bridgeClockAlarm" typeId="clockAlarm"/>
+                       <channel-group id="bridgeClockAlarm" typeId="bridgeClockAlarm"/>
                </channel-groups>
                <config-description-ref uri="bridge-type:velbus:bridge"/>
        </bridge-type>
@@ -17,7 +17,7 @@
                <label>Velbus Network Bridge</label>
                <description>This bridge represents a Velbus connection over TCP/IP</description>
                <channel-groups>
-                       <channel-group id="bridgeClockAlarm" typeId="clockAlarm"/>
+                       <channel-group id="bridgeClockAlarm" typeId="bridgeClockAlarm"/>
                </channel-groups>
                <config-description-ref uri="bridge-type:velbus:networkbridge"/>
        </bridge-type>
                <config-description-ref uri="thing-type:velbus:2channelDevice"/>
        </thing-type>
 
+       <thing-type id="vmb2ble-10">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMB2BLE-10</label>
+               <description>2-channel blind control module with extended possibilities</description>
+               <channels>
+                       <channel id="CH1" typeId="rollershutter"/>
+                       <channel id="CH2" typeId="rollershutter"/>
+               </channels>
+
+               <config-description-ref uri="thing-type:velbus:2channelDevice"/>
+       </thing-type>
+
        <thing-type id="vmb2pbn">
                <supported-bridge-type-refs>
                        <bridge-type-ref id="bridge"/>
                <config-description-ref uri="thing-type:velbus:5channelDevice"/>
        </thing-type>
 
+       <thing-type id="vmb4ryld-10">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMB4RYLD-10</label>
+               <description>4-channel relay module with voltage outputs</description>
+               <channels>
+                       <channel id="CH1" typeId="switch"/>
+                       <channel id="CH2" typeId="switch"/>
+                       <channel id="CH3" typeId="switch"/>
+                       <channel id="CH4" typeId="switch"/>
+                       <channel id="CH5" typeId="switch"/>
+               </channels>
+
+               <config-description-ref uri="thing-type:velbus:5channelDevice"/>
+       </thing-type>
+
        <thing-type id="vmb4ryno">
                <supported-bridge-type-refs>
                        <bridge-type-ref id="bridge"/>
                <config-description-ref uri="thing-type:velbus:5channelDevice"/>
        </thing-type>
 
+       <thing-type id="vmb4ryno-10">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMB4RYNO-10</label>
+               <description>4-channel relay module with potential-free contacts</description>
+               <channels>
+                       <channel id="CH1" typeId="switch"/>
+                       <channel id="CH2" typeId="switch"/>
+                       <channel id="CH3" typeId="switch"/>
+                       <channel id="CH4" typeId="switch"/>
+                       <channel id="CH5" typeId="switch"/>
+               </channels>
+
+               <config-description-ref uri="thing-type:velbus:5channelDevice"/>
+       </thing-type>
+
        <thing-type id="vmb6in">
                <supported-bridge-type-refs>
                        <bridge-type-ref id="bridge"/>
                <config-description-ref uri="thing-type:velbus:8channelDevice"/>
        </thing-type>
 
+       <thing-type id="vmb6pbn-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMB6PBN-20</label>
+               <description>6 button interface module</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="8channelInputModule"/>
+                       <channel-group id="button" typeId="8channelButtonModule"/>
+                       <channel-group id="feedback" typeId="6channelFeedbackModule"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+               </channel-groups>
+
+               <config-description-ref uri="thing-type:velbus:8channelDevice"/>
+       </thing-type>
+
        <thing-type id="vmb7in">
                <supported-bridge-type-refs>
                        <bridge-type-ref id="bridge"/>
                        <channel-group id="button" typeId="8channelButtonModule"/>
                        <channel-group id="feedback" typeId="1channelFeedbackModule"/>
                        <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="output" typeId="1outputModule"/>
                        <channel-group id="clockAlarm" typeId="clockAlarm"/>
                </channel-groups>
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
+
+               <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
+       </thing-type>
+
+       <thing-type id="vmbel1-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBEL1-20</label>
+               <description>Edge-lit one touch button module</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="9channelInputModuleWithTemperatureSensor"/>
+                       <channel-group id="button" typeId="8channelButtonModule"/>
+                       <channel-group id="feedback" typeId="1channelFeedbackModule"/>
+                       <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="output" typeId="1outputModule"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+               </channel-groups>
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
 
                <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
        </thing-type>
                        <channel-group id="button" typeId="8channelButtonModule"/>
                        <channel-group id="feedback" typeId="2channelFeedbackModule"/>
                        <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="output" typeId="1outputModule"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+               </channel-groups>
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
+
+               <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
+       </thing-type>
+
+       <thing-type id="vmbel2-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBEL2-20</label>
+               <description>Edge-lit two touch buttons module</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="9channelInputModuleWithTemperatureSensor"/>
+                       <channel-group id="button" typeId="8channelButtonModule"/>
+                       <channel-group id="feedback" typeId="2channelFeedbackModule"/>
+                       <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="output" typeId="1outputModule"/>
                        <channel-group id="clockAlarm" typeId="clockAlarm"/>
                </channel-groups>
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
 
                <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
        </thing-type>
                        <channel-group id="button" typeId="8channelButtonModule"/>
                        <channel-group id="feedback" typeId="4channelFeedbackModule"/>
                        <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="output" typeId="1outputModule"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+               </channel-groups>
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
+
+               <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
+       </thing-type>
+
+       <thing-type id="vmbel4-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBEL4-20</label>
+               <description>Edge-lit four touch buttons module</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="9channelInputModuleWithTemperatureSensor"/>
+                       <channel-group id="button" typeId="8channelButtonModule"/>
+                       <channel-group id="feedback" typeId="4channelFeedbackModule"/>
+                       <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="output" typeId="1outputModule"/>
                        <channel-group id="clockAlarm" typeId="clockAlarm"/>
                </channel-groups>
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
 
                <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
        </thing-type>
                        <channel-group id="button" typeId="32channelButtonModule"/>
                        <channel-group id="feedback" typeId="32channelFeedbackModule"/>
                        <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="output" typeId="1outputModule"/>
                        <channel-group id="clockAlarm" typeId="clockAlarm"/>
                        <channel-group id="oledDisplay" typeId="oledDisplay"/>
                </channel-groups>
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
+
+               <config-description-ref uri="thing-type:velbus:33channelDeviceWithTemperatureSensor"/>
+       </thing-type>
+
+       <thing-type id="vmbelo-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBELO-20</label>
+               <description>Edge-lit touch panel with Oled display</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="33channelInputModuleWithTemperatureSensor"/>
+                       <channel-group id="button" typeId="32channelButtonModule"/>
+                       <channel-group id="feedback" typeId="32channelFeedbackModule"/>
+                       <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="output" typeId="1outputModule"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+                       <channel-group id="oledDisplay" typeId="oledDisplay"/>
+               </channel-groups>
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
 
                <config-description-ref uri="thing-type:velbus:33channelDeviceWithTemperatureSensor"/>
        </thing-type>
                        <channel-group id="button" typeId="2channelButtonModule"/>
                        <channel-group id="feedback" typeId="1channelFeedbackModule"/>
                        <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="output" typeId="1outputModule"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+               </channel-groups>
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
+
+               <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
+       </thing-type>
+
+       <thing-type id="vmbel4pir-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBEL4PIR-20</label>
+               <description>Edge-lit Motion detector with four touch button</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="9channelInputModuleWithTemperatureSensor"/>
+                       <channel-group id="button" typeId="4channelButtonModule"/>
+                       <channel-group id="feedback" typeId="4channelFeedbackModule"/>
+                       <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="output" typeId="1outputModule"/>
                        <channel-group id="clockAlarm" typeId="clockAlarm"/>
                </channel-groups>
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
 
                <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
        </thing-type>
                <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
        </thing-type>
 
+       <thing-type id="vmbgp1-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBGP1-20</label>
+               <description>Glass control module with 1 touch key</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="9channelInputModuleWithTemperatureSensor"/>
+                       <channel-group id="button" typeId="8channelButtonModule"/>
+                       <channel-group id="feedback" typeId="1channelFeedbackModule"/>
+                       <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+               </channel-groups>
+
+               <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
+       </thing-type>
+
        <thing-type id="vmbgp1-2">
                <supported-bridge-type-refs>
                        <bridge-type-ref id="bridge"/>
                <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
        </thing-type>
 
+       <thing-type id="vmbgp2-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBGP2-20</label>
+               <description>Glass control module with 2 touch keys</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="9channelInputModuleWithTemperatureSensor"/>
+                       <channel-group id="button" typeId="8channelButtonModule"/>
+                       <channel-group id="feedback" typeId="2channelFeedbackModule"/>
+                       <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+               </channel-groups>
+
+               <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
+       </thing-type>
+
        <thing-type id="vmbgp2-2">
                <supported-bridge-type-refs>
                        <bridge-type-ref id="bridge"/>
                <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
        </thing-type>
 
+       <thing-type id="vmbgp4-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBGP4-20</label>
+               <description>Glass control module with 4 touch keys</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="9channelInputModuleWithTemperatureSensor"/>
+                       <channel-group id="button" typeId="8channelButtonModule"/>
+                       <channel-group id="feedback" typeId="4channelFeedbackModule"/>
+                       <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+               </channel-groups>
+
+               <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
+       </thing-type>
+
        <thing-type id="vmbgp4pir">
                <supported-bridge-type-refs>
                        <bridge-type-ref id="bridge"/>
                <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
        </thing-type>
 
+       <thing-type id="vmbgp4pir-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBGP4PIR-20</label>
+               <description>Glass control module with 4 touch keys and built-in motion and twilight sensor</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="9channelInputModuleWithTemperatureSensor"/>
+                       <channel-group id="button" typeId="8channelButtonModule"/>
+                       <channel-group id="feedback" typeId="4channelFeedbackModule"/>
+                       <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+               </channel-groups>
+
+               <config-description-ref uri="thing-type:velbus:9channelDeviceWithTemperatureSensor"/>
+       </thing-type>
+
        <thing-type id="vmbgpo">
                <supported-bridge-type-refs>
                        <bridge-type-ref id="bridge"/>
                <config-description-ref uri="thing-type:velbus:33channelDeviceWithTemperatureSensor"/>
        </thing-type>
 
+       <thing-type id="vmbgpo-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBGPO-20</label>
+               <description>Glass control module with oled display</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="33channelInputModuleWithTemperatureSensor"/>
+                       <channel-group id="button" typeId="32channelButtonModule"/>
+                       <channel-group id="feedback" typeId="32channelFeedbackModule"/>
+                       <channel-group id="thermostat" typeId="thermostat"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+                       <channel-group id="oledDisplay" typeId="oledDisplay"/>
+               </channel-groups>
+
+               <config-description-ref uri="thing-type:velbus:33channelDeviceWithTemperatureSensor"/>
+       </thing-type>
+
        <thing-type id="vmbgpod">
                <supported-bridge-type-refs>
                        <bridge-type-ref id="bridge"/>
                <config-description-ref uri="thing-type:velbus:8channelDevice"/>
        </thing-type>
 
+       <thing-type id="vmbdali">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBDALI</label>
+               <description>DALI gateway module</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="81channelInputModule"/>
+                       <channel-group id="feedback" typeId="81channelFeedbackModule"/>
+                       <channel-group id="color" typeId="81channelColorModule"/>
+                       <channel-group id="brightness" typeId="81channelBrightnessModule"/>
+                       <channel-group id="white" typeId="81channelWhiteColorModule"/>
+                       <channel-group id="scene" typeId="81channelSceneModule"/>
+                       <channel-group id="virtual-light" typeId="16channelVirtualLight"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+               </channel-groups>
+
+               <config-description-ref uri="thing-type:velbus:81channelDevice"/>
+       </thing-type>
+
+       <thing-type id="vmbdali-20">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+                       <bridge-type-ref id="networkbridge"/>
+               </supported-bridge-type-refs>
+
+               <label>VMBDALI-20</label>
+               <description>DALI gateway module</description>
+               <channel-groups>
+                       <channel-group id="input" typeId="81channelInputModule"/>
+                       <channel-group id="feedback" typeId="81channelFeedbackModule"/>
+                       <channel-group id="color" typeId="81channelColorModule"/>
+                       <channel-group id="brightness" typeId="81channelBrightnessModule"/>
+                       <channel-group id="white" typeId="81channelWhiteColorModule"/>
+                       <channel-group id="scene" typeId="81channelSceneModule"/>
+                       <channel-group id="virtual-light" typeId="16channelVirtualLight"/>
+                       <channel-group id="clockAlarm" typeId="clockAlarm"/>
+               </channel-groups>
+
+               <config-description-ref uri="thing-type:velbus:81channelDevice"/>
+       </thing-type>
+
        <channel-type id="heatingOperatingMode">
                <item-type>String</item-type>
                <label>Operating Mode</label>
                <label>Wind Speed</label>
                <description>Currently measured wind speed</description>
                <category>Wind</category>
-               <state readOnly="true" pattern="%.1f %unit%"/>
+               <state readOnly="true" pattern="%.1f %unit%">
+               </state>
        </channel-type>
        <channel-type id="trigger-channel">
                <kind>trigger</kind>
                        </options>
                </event>
        </channel-type>
+       <channel-type id="light-scene">
+               <item-type>Number</item-type>
+               <label>Scene</label>
+               <description>Scene options for DALI network</description>
+               <state readOnly="false" min="0" max="15" step="1">
+               </state>
+       </channel-type>
+
        <channel-group-type id="1channelInputModuleWithTemperatureSensor">
                <label>Input with Temperature Sensor</label>
                <description>This is a generic module with 8 input channels and a temperature sensor.</description>
                        <channel id="CH33" typeId="temperature"/>
                </channels>
        </channel-group-type>
+       <channel-group-type id="81channelInputModule">
+               <label>Input</label>
+               <description>This is a generic module with 81 input channels.</description>
+               <channels>
+                       <channel id="CH1" typeId="trigger-channel"/>
+                       <channel id="CH2" typeId="trigger-channel"/>
+                       <channel id="CH3" typeId="trigger-channel"/>
+                       <channel id="CH4" typeId="trigger-channel"/>
+                       <channel id="CH5" typeId="trigger-channel"/>
+                       <channel id="CH6" typeId="trigger-channel"/>
+                       <channel id="CH7" typeId="trigger-channel"/>
+                       <channel id="CH8" typeId="trigger-channel"/>
+                       <channel id="CH9" typeId="trigger-channel"/>
+                       <channel id="CH10" typeId="trigger-channel"/>
+                       <channel id="CH11" typeId="trigger-channel"/>
+                       <channel id="CH12" typeId="trigger-channel"/>
+                       <channel id="CH13" typeId="trigger-channel"/>
+                       <channel id="CH14" typeId="trigger-channel"/>
+                       <channel id="CH15" typeId="trigger-channel"/>
+                       <channel id="CH16" typeId="trigger-channel"/>
+                       <channel id="CH17" typeId="trigger-channel"/>
+                       <channel id="CH18" typeId="trigger-channel"/>
+                       <channel id="CH19" typeId="trigger-channel"/>
+                       <channel id="CH20" typeId="trigger-channel"/>
+                       <channel id="CH21" typeId="trigger-channel"/>
+                       <channel id="CH22" typeId="trigger-channel"/>
+                       <channel id="CH23" typeId="trigger-channel"/>
+                       <channel id="CH24" typeId="trigger-channel"/>
+                       <channel id="CH25" typeId="trigger-channel"/>
+                       <channel id="CH26" typeId="trigger-channel"/>
+                       <channel id="CH27" typeId="trigger-channel"/>
+                       <channel id="CH28" typeId="trigger-channel"/>
+                       <channel id="CH29" typeId="trigger-channel"/>
+                       <channel id="CH30" typeId="trigger-channel"/>
+                       <channel id="CH31" typeId="trigger-channel"/>
+                       <channel id="CH32" typeId="trigger-channel"/>
+                       <channel id="CH33" typeId="trigger-channel"/>
+                       <channel id="CH34" typeId="trigger-channel"/>
+                       <channel id="CH35" typeId="trigger-channel"/>
+                       <channel id="CH36" typeId="trigger-channel"/>
+                       <channel id="CH37" typeId="trigger-channel"/>
+                       <channel id="CH38" typeId="trigger-channel"/>
+                       <channel id="CH39" typeId="trigger-channel"/>
+                       <channel id="CH40" typeId="trigger-channel"/>
+                       <channel id="CH41" typeId="trigger-channel"/>
+                       <channel id="CH42" typeId="trigger-channel"/>
+                       <channel id="CH43" typeId="trigger-channel"/>
+                       <channel id="CH44" typeId="trigger-channel"/>
+                       <channel id="CH45" typeId="trigger-channel"/>
+                       <channel id="CH46" typeId="trigger-channel"/>
+                       <channel id="CH47" typeId="trigger-channel"/>
+                       <channel id="CH48" typeId="trigger-channel"/>
+                       <channel id="CH49" typeId="trigger-channel"/>
+                       <channel id="CH50" typeId="trigger-channel"/>
+                       <channel id="CH51" typeId="trigger-channel"/>
+                       <channel id="CH52" typeId="trigger-channel"/>
+                       <channel id="CH53" typeId="trigger-channel"/>
+                       <channel id="CH54" typeId="trigger-channel"/>
+                       <channel id="CH55" typeId="trigger-channel"/>
+                       <channel id="CH56" typeId="trigger-channel"/>
+                       <channel id="CH57" typeId="trigger-channel"/>
+                       <channel id="CH58" typeId="trigger-channel"/>
+                       <channel id="CH59" typeId="trigger-channel"/>
+                       <channel id="CH60" typeId="trigger-channel"/>
+                       <channel id="CH61" typeId="trigger-channel"/>
+                       <channel id="CH62" typeId="trigger-channel"/>
+                       <channel id="CH63" typeId="trigger-channel"/>
+                       <channel id="CH64" typeId="trigger-channel"/>
+                       <channel id="CH65" typeId="trigger-channel"/>
+                       <channel id="CH66" typeId="trigger-channel"/>
+                       <channel id="CH67" typeId="trigger-channel"/>
+                       <channel id="CH68" typeId="trigger-channel"/>
+                       <channel id="CH69" typeId="trigger-channel"/>
+                       <channel id="CH70" typeId="trigger-channel"/>
+                       <channel id="CH71" typeId="trigger-channel"/>
+                       <channel id="CH72" typeId="trigger-channel"/>
+                       <channel id="CH73" typeId="trigger-channel"/>
+                       <channel id="CH74" typeId="trigger-channel"/>
+                       <channel id="CH75" typeId="trigger-channel"/>
+                       <channel id="CH76" typeId="trigger-channel"/>
+                       <channel id="CH77" typeId="trigger-channel"/>
+                       <channel id="CH78" typeId="trigger-channel"/>
+                       <channel id="CH79" typeId="trigger-channel"/>
+                       <channel id="CH80" typeId="trigger-channel"/>
+                       <channel id="CH81" typeId="trigger-channel"/>
+               </channels>
+       </channel-group-type>
+       <channel-group-type id="1outputModule">
+               <label>Output</label>
+               <description>
+                       This is a generic module with 1 output.
+               </description>
+               <channels>
+                       <channel id="output" typeId="switch"/>
+               </channels>
+       </channel-group-type>
        <channel-group-type id="1channelFeedbackModule">
                <label>Feedback</label>
                <description>
                        <channel id="CH32" typeId="ledFeedback"/>
                </channels>
        </channel-group-type>
+       <channel-group-type id="81channelFeedbackModule">
+               <label>Feedback</label>
+               <description>
+                       This is a generic module with 81 feedback channels.
+               </description>
+               <channels>
+                       <channel id="CH1" typeId="ledFeedback"/>
+                       <channel id="CH2" typeId="ledFeedback"/>
+                       <channel id="CH3" typeId="ledFeedback"/>
+                       <channel id="CH4" typeId="ledFeedback"/>
+                       <channel id="CH5" typeId="ledFeedback"/>
+                       <channel id="CH6" typeId="ledFeedback"/>
+                       <channel id="CH7" typeId="ledFeedback"/>
+                       <channel id="CH8" typeId="ledFeedback"/>
+                       <channel id="CH9" typeId="ledFeedback"/>
+                       <channel id="CH10" typeId="ledFeedback"/>
+                       <channel id="CH11" typeId="ledFeedback"/>
+                       <channel id="CH12" typeId="ledFeedback"/>
+                       <channel id="CH13" typeId="ledFeedback"/>
+                       <channel id="CH14" typeId="ledFeedback"/>
+                       <channel id="CH15" typeId="ledFeedback"/>
+                       <channel id="CH16" typeId="ledFeedback"/>
+                       <channel id="CH17" typeId="ledFeedback"/>
+                       <channel id="CH18" typeId="ledFeedback"/>
+                       <channel id="CH19" typeId="ledFeedback"/>
+                       <channel id="CH20" typeId="ledFeedback"/>
+                       <channel id="CH21" typeId="ledFeedback"/>
+                       <channel id="CH22" typeId="ledFeedback"/>
+                       <channel id="CH23" typeId="ledFeedback"/>
+                       <channel id="CH24" typeId="ledFeedback"/>
+                       <channel id="CH25" typeId="ledFeedback"/>
+                       <channel id="CH26" typeId="ledFeedback"/>
+                       <channel id="CH27" typeId="ledFeedback"/>
+                       <channel id="CH28" typeId="ledFeedback"/>
+                       <channel id="CH29" typeId="ledFeedback"/>
+                       <channel id="CH30" typeId="ledFeedback"/>
+                       <channel id="CH31" typeId="ledFeedback"/>
+                       <channel id="CH32" typeId="ledFeedback"/>
+                       <channel id="CH33" typeId="ledFeedback"/>
+                       <channel id="CH34" typeId="ledFeedback"/>
+                       <channel id="CH35" typeId="ledFeedback"/>
+                       <channel id="CH36" typeId="ledFeedback"/>
+                       <channel id="CH37" typeId="ledFeedback"/>
+                       <channel id="CH38" typeId="ledFeedback"/>
+                       <channel id="CH39" typeId="ledFeedback"/>
+                       <channel id="CH40" typeId="ledFeedback"/>
+                       <channel id="CH41" typeId="ledFeedback"/>
+                       <channel id="CH42" typeId="ledFeedback"/>
+                       <channel id="CH43" typeId="ledFeedback"/>
+                       <channel id="CH44" typeId="ledFeedback"/>
+                       <channel id="CH45" typeId="ledFeedback"/>
+                       <channel id="CH46" typeId="ledFeedback"/>
+                       <channel id="CH47" typeId="ledFeedback"/>
+                       <channel id="CH48" typeId="ledFeedback"/>
+                       <channel id="CH49" typeId="ledFeedback"/>
+                       <channel id="CH50" typeId="ledFeedback"/>
+                       <channel id="CH51" typeId="ledFeedback"/>
+                       <channel id="CH52" typeId="ledFeedback"/>
+                       <channel id="CH53" typeId="ledFeedback"/>
+                       <channel id="CH54" typeId="ledFeedback"/>
+                       <channel id="CH55" typeId="ledFeedback"/>
+                       <channel id="CH56" typeId="ledFeedback"/>
+                       <channel id="CH57" typeId="ledFeedback"/>
+                       <channel id="CH58" typeId="ledFeedback"/>
+                       <channel id="CH59" typeId="ledFeedback"/>
+                       <channel id="CH60" typeId="ledFeedback"/>
+                       <channel id="CH61" typeId="ledFeedback"/>
+                       <channel id="CH62" typeId="ledFeedback"/>
+                       <channel id="CH63" typeId="ledFeedback"/>
+                       <channel id="CH64" typeId="ledFeedback"/>
+                       <channel id="CH65" typeId="ledFeedback"/>
+                       <channel id="CH66" typeId="ledFeedback"/>
+                       <channel id="CH67" typeId="ledFeedback"/>
+                       <channel id="CH68" typeId="ledFeedback"/>
+                       <channel id="CH69" typeId="ledFeedback"/>
+                       <channel id="CH70" typeId="ledFeedback"/>
+                       <channel id="CH71" typeId="ledFeedback"/>
+                       <channel id="CH72" typeId="ledFeedback"/>
+                       <channel id="CH73" typeId="ledFeedback"/>
+                       <channel id="CH74" typeId="ledFeedback"/>
+                       <channel id="CH75" typeId="ledFeedback"/>
+                       <channel id="CH76" typeId="ledFeedback"/>
+                       <channel id="CH77" typeId="ledFeedback"/>
+                       <channel id="CH78" typeId="ledFeedback"/>
+                       <channel id="CH79" typeId="ledFeedback"/>
+                       <channel id="CH80" typeId="ledFeedback"/>
+                       <channel id="CH81" typeId="ledFeedback"/>
+               </channels>
+       </channel-group-type>
        <channel-group-type id="2channelButtonModule">
                <label>Button</label>
                <description>
                        <channel id="CH2" typeId="button-channel"/>
                </channels>
        </channel-group-type>
+       <channel-group-type id="4channelButtonModule">
+               <label>Button</label>
+               <description>
+                       This is a generic module with 4 button channels.
+               </description>
+               <channels>
+                       <channel id="CH1" typeId="button-channel"/>
+                       <channel id="CH2" typeId="button-channel"/>
+                       <channel id="CH3" typeId="button-channel"/>
+                       <channel id="CH4" typeId="button-channel"/>
+               </channels>
+       </channel-group-type>
        <channel-group-type id="5SubchannelButtonModule">
                <label>Button</label>
                <description>
                        <channel id="CH32" typeId="button-channel"/>
                </channels>
        </channel-group-type>
+       <channel-group-type id="81channelColorModule">
+               <label>Color</label>
+               <description>
+                       This is a generic module with 81 color channels.
+               </description>
+               <channels>
+                       <channel id="CH1" typeId="system.color"/>
+                       <channel id="CH2" typeId="system.color"/>
+                       <channel id="CH3" typeId="system.color"/>
+                       <channel id="CH4" typeId="system.color"/>
+                       <channel id="CH5" typeId="system.color"/>
+                       <channel id="CH6" typeId="system.color"/>
+                       <channel id="CH7" typeId="system.color"/>
+                       <channel id="CH8" typeId="system.color"/>
+                       <channel id="CH9" typeId="system.color"/>
+                       <channel id="CH10" typeId="system.color"/>
+                       <channel id="CH11" typeId="system.color"/>
+                       <channel id="CH12" typeId="system.color"/>
+                       <channel id="CH13" typeId="system.color"/>
+                       <channel id="CH14" typeId="system.color"/>
+                       <channel id="CH15" typeId="system.color"/>
+                       <channel id="CH16" typeId="system.color"/>
+                       <channel id="CH17" typeId="system.color"/>
+                       <channel id="CH18" typeId="system.color"/>
+                       <channel id="CH19" typeId="system.color"/>
+                       <channel id="CH20" typeId="system.color"/>
+                       <channel id="CH21" typeId="system.color"/>
+                       <channel id="CH22" typeId="system.color"/>
+                       <channel id="CH23" typeId="system.color"/>
+                       <channel id="CH24" typeId="system.color"/>
+                       <channel id="CH25" typeId="system.color"/>
+                       <channel id="CH26" typeId="system.color"/>
+                       <channel id="CH27" typeId="system.color"/>
+                       <channel id="CH28" typeId="system.color"/>
+                       <channel id="CH29" typeId="system.color"/>
+                       <channel id="CH30" typeId="system.color"/>
+                       <channel id="CH31" typeId="system.color"/>
+                       <channel id="CH32" typeId="system.color"/>
+                       <channel id="CH33" typeId="system.color"/>
+                       <channel id="CH34" typeId="system.color"/>
+                       <channel id="CH35" typeId="system.color"/>
+                       <channel id="CH36" typeId="system.color"/>
+                       <channel id="CH37" typeId="system.color"/>
+                       <channel id="CH38" typeId="system.color"/>
+                       <channel id="CH39" typeId="system.color"/>
+                       <channel id="CH40" typeId="system.color"/>
+                       <channel id="CH41" typeId="system.color"/>
+                       <channel id="CH42" typeId="system.color"/>
+                       <channel id="CH43" typeId="system.color"/>
+                       <channel id="CH44" typeId="system.color"/>
+                       <channel id="CH45" typeId="system.color"/>
+                       <channel id="CH46" typeId="system.color"/>
+                       <channel id="CH47" typeId="system.color"/>
+                       <channel id="CH48" typeId="system.color"/>
+                       <channel id="CH49" typeId="system.color"/>
+                       <channel id="CH50" typeId="system.color"/>
+                       <channel id="CH51" typeId="system.color"/>
+                       <channel id="CH52" typeId="system.color"/>
+                       <channel id="CH53" typeId="system.color"/>
+                       <channel id="CH54" typeId="system.color"/>
+                       <channel id="CH55" typeId="system.color"/>
+                       <channel id="CH56" typeId="system.color"/>
+                       <channel id="CH57" typeId="system.color"/>
+                       <channel id="CH58" typeId="system.color"/>
+                       <channel id="CH59" typeId="system.color"/>
+                       <channel id="CH60" typeId="system.color"/>
+                       <channel id="CH61" typeId="system.color"/>
+                       <channel id="CH62" typeId="system.color"/>
+                       <channel id="CH63" typeId="system.color"/>
+                       <channel id="CH64" typeId="system.color"/>
+                       <channel id="CH65" typeId="system.color"/>
+                       <channel id="CH66" typeId="system.color"/>
+                       <channel id="CH67" typeId="system.color"/>
+                       <channel id="CH68" typeId="system.color"/>
+                       <channel id="CH69" typeId="system.color"/>
+                       <channel id="CH70" typeId="system.color"/>
+                       <channel id="CH71" typeId="system.color"/>
+                       <channel id="CH72" typeId="system.color"/>
+                       <channel id="CH73" typeId="system.color"/>
+                       <channel id="CH74" typeId="system.color"/>
+                       <channel id="CH75" typeId="system.color"/>
+                       <channel id="CH76" typeId="system.color"/>
+                       <channel id="CH77" typeId="system.color"/>
+                       <channel id="CH78" typeId="system.color"/>
+                       <channel id="CH79" typeId="system.color"/>
+                       <channel id="CH81" typeId="system.color"/>
+               </channels>
+       </channel-group-type>
+       <channel-group-type id="81channelBrightnessModule">
+               <label>Brightness</label>
+               <description>
+                       This is a generic module with 81 brightness channels.
+               </description>
+               <channels>
+                       <channel id="CH1" typeId="system.brightness"/>
+                       <channel id="CH2" typeId="system.brightness"/>
+                       <channel id="CH3" typeId="system.brightness"/>
+                       <channel id="CH4" typeId="system.brightness"/>
+                       <channel id="CH5" typeId="system.brightness"/>
+                       <channel id="CH6" typeId="system.brightness"/>
+                       <channel id="CH7" typeId="system.brightness"/>
+                       <channel id="CH8" typeId="system.brightness"/>
+                       <channel id="CH9" typeId="system.brightness"/>
+                       <channel id="CH10" typeId="system.brightness"/>
+                       <channel id="CH11" typeId="system.brightness"/>
+                       <channel id="CH12" typeId="system.brightness"/>
+                       <channel id="CH13" typeId="system.brightness"/>
+                       <channel id="CH14" typeId="system.brightness"/>
+                       <channel id="CH15" typeId="system.brightness"/>
+                       <channel id="CH16" typeId="system.brightness"/>
+                       <channel id="CH17" typeId="system.brightness"/>
+                       <channel id="CH18" typeId="system.brightness"/>
+                       <channel id="CH19" typeId="system.brightness"/>
+                       <channel id="CH20" typeId="system.brightness"/>
+                       <channel id="CH21" typeId="system.brightness"/>
+                       <channel id="CH22" typeId="system.brightness"/>
+                       <channel id="CH23" typeId="system.brightness"/>
+                       <channel id="CH24" typeId="system.brightness"/>
+                       <channel id="CH25" typeId="system.brightness"/>
+                       <channel id="CH26" typeId="system.brightness"/>
+                       <channel id="CH27" typeId="system.brightness"/>
+                       <channel id="CH28" typeId="system.brightness"/>
+                       <channel id="CH29" typeId="system.brightness"/>
+                       <channel id="CH30" typeId="system.brightness"/>
+                       <channel id="CH31" typeId="system.brightness"/>
+                       <channel id="CH32" typeId="system.brightness"/>
+                       <channel id="CH33" typeId="system.brightness"/>
+                       <channel id="CH34" typeId="system.brightness"/>
+                       <channel id="CH35" typeId="system.brightness"/>
+                       <channel id="CH36" typeId="system.brightness"/>
+                       <channel id="CH37" typeId="system.brightness"/>
+                       <channel id="CH38" typeId="system.brightness"/>
+                       <channel id="CH39" typeId="system.brightness"/>
+                       <channel id="CH40" typeId="system.brightness"/>
+                       <channel id="CH41" typeId="system.brightness"/>
+                       <channel id="CH42" typeId="system.brightness"/>
+                       <channel id="CH43" typeId="system.brightness"/>
+                       <channel id="CH44" typeId="system.brightness"/>
+                       <channel id="CH45" typeId="system.brightness"/>
+                       <channel id="CH46" typeId="system.brightness"/>
+                       <channel id="CH47" typeId="system.brightness"/>
+                       <channel id="CH48" typeId="system.brightness"/>
+                       <channel id="CH49" typeId="system.brightness"/>
+                       <channel id="CH50" typeId="system.brightness"/>
+                       <channel id="CH51" typeId="system.brightness"/>
+                       <channel id="CH52" typeId="system.brightness"/>
+                       <channel id="CH53" typeId="system.brightness"/>
+                       <channel id="CH54" typeId="system.brightness"/>
+                       <channel id="CH55" typeId="system.brightness"/>
+                       <channel id="CH56" typeId="system.brightness"/>
+                       <channel id="CH57" typeId="system.brightness"/>
+                       <channel id="CH58" typeId="system.brightness"/>
+                       <channel id="CH59" typeId="system.brightness"/>
+                       <channel id="CH60" typeId="system.brightness"/>
+                       <channel id="CH61" typeId="system.brightness"/>
+                       <channel id="CH62" typeId="system.brightness"/>
+                       <channel id="CH63" typeId="system.brightness"/>
+                       <channel id="CH64" typeId="system.brightness"/>
+                       <channel id="CH65" typeId="system.brightness"/>
+                       <channel id="CH66" typeId="system.brightness"/>
+                       <channel id="CH67" typeId="system.brightness"/>
+                       <channel id="CH68" typeId="system.brightness"/>
+                       <channel id="CH69" typeId="system.brightness"/>
+                       <channel id="CH70" typeId="system.brightness"/>
+                       <channel id="CH71" typeId="system.brightness"/>
+                       <channel id="CH72" typeId="system.brightness"/>
+                       <channel id="CH73" typeId="system.brightness"/>
+                       <channel id="CH74" typeId="system.brightness"/>
+                       <channel id="CH75" typeId="system.brightness"/>
+                       <channel id="CH76" typeId="system.brightness"/>
+                       <channel id="CH77" typeId="system.brightness"/>
+                       <channel id="CH78" typeId="system.brightness"/>
+                       <channel id="CH79" typeId="system.brightness"/>
+                       <channel id="CH80" typeId="system.brightness"/>
+                       <channel id="CH81" typeId="system.brightness"/>
+               </channels>
+       </channel-group-type>
+       <channel-group-type id="81channelWhiteColorModule">
+               <label>White Color</label>
+               <description>
+                       This is a generic module with 81 white color channels.
+               </description>
+               <channels>
+                       <channel id="CH1" typeId="system.brightness"/>
+                       <channel id="CH2" typeId="system.brightness"/>
+                       <channel id="CH3" typeId="system.brightness"/>
+                       <channel id="CH4" typeId="system.brightness"/>
+                       <channel id="CH5" typeId="system.brightness"/>
+                       <channel id="CH6" typeId="system.brightness"/>
+                       <channel id="CH7" typeId="system.brightness"/>
+                       <channel id="CH8" typeId="system.brightness"/>
+                       <channel id="CH9" typeId="system.brightness"/>
+                       <channel id="CH10" typeId="system.brightness"/>
+                       <channel id="CH11" typeId="system.brightness"/>
+                       <channel id="CH12" typeId="system.brightness"/>
+                       <channel id="CH13" typeId="system.brightness"/>
+                       <channel id="CH14" typeId="system.brightness"/>
+                       <channel id="CH15" typeId="system.brightness"/>
+                       <channel id="CH16" typeId="system.brightness"/>
+                       <channel id="CH17" typeId="system.brightness"/>
+                       <channel id="CH18" typeId="system.brightness"/>
+                       <channel id="CH19" typeId="system.brightness"/>
+                       <channel id="CH20" typeId="system.brightness"/>
+                       <channel id="CH21" typeId="system.brightness"/>
+                       <channel id="CH22" typeId="system.brightness"/>
+                       <channel id="CH23" typeId="system.brightness"/>
+                       <channel id="CH24" typeId="system.brightness"/>
+                       <channel id="CH25" typeId="system.brightness"/>
+                       <channel id="CH26" typeId="system.brightness"/>
+                       <channel id="CH27" typeId="system.brightness"/>
+                       <channel id="CH28" typeId="system.brightness"/>
+                       <channel id="CH29" typeId="system.brightness"/>
+                       <channel id="CH30" typeId="system.brightness"/>
+                       <channel id="CH31" typeId="system.brightness"/>
+                       <channel id="CH32" typeId="system.brightness"/>
+                       <channel id="CH33" typeId="system.brightness"/>
+                       <channel id="CH34" typeId="system.brightness"/>
+                       <channel id="CH35" typeId="system.brightness"/>
+                       <channel id="CH36" typeId="system.brightness"/>
+                       <channel id="CH37" typeId="system.brightness"/>
+                       <channel id="CH38" typeId="system.brightness"/>
+                       <channel id="CH39" typeId="system.brightness"/>
+                       <channel id="CH40" typeId="system.brightness"/>
+                       <channel id="CH41" typeId="system.brightness"/>
+                       <channel id="CH42" typeId="system.brightness"/>
+                       <channel id="CH43" typeId="system.brightness"/>
+                       <channel id="CH44" typeId="system.brightness"/>
+                       <channel id="CH45" typeId="system.brightness"/>
+                       <channel id="CH46" typeId="system.brightness"/>
+                       <channel id="CH47" typeId="system.brightness"/>
+                       <channel id="CH48" typeId="system.brightness"/>
+                       <channel id="CH49" typeId="system.brightness"/>
+                       <channel id="CH50" typeId="system.brightness"/>
+                       <channel id="CH51" typeId="system.brightness"/>
+                       <channel id="CH52" typeId="system.brightness"/>
+                       <channel id="CH53" typeId="system.brightness"/>
+                       <channel id="CH54" typeId="system.brightness"/>
+                       <channel id="CH55" typeId="system.brightness"/>
+                       <channel id="CH56" typeId="system.brightness"/>
+                       <channel id="CH57" typeId="system.brightness"/>
+                       <channel id="CH58" typeId="system.brightness"/>
+                       <channel id="CH59" typeId="system.brightness"/>
+                       <channel id="CH60" typeId="system.brightness"/>
+                       <channel id="CH61" typeId="system.brightness"/>
+                       <channel id="CH62" typeId="system.brightness"/>
+                       <channel id="CH63" typeId="system.brightness"/>
+                       <channel id="CH64" typeId="system.brightness"/>
+                       <channel id="CH65" typeId="system.brightness"/>
+                       <channel id="CH66" typeId="system.brightness"/>
+                       <channel id="CH67" typeId="system.brightness"/>
+                       <channel id="CH68" typeId="system.brightness"/>
+                       <channel id="CH69" typeId="system.brightness"/>
+                       <channel id="CH70" typeId="system.brightness"/>
+                       <channel id="CH71" typeId="system.brightness"/>
+                       <channel id="CH72" typeId="system.brightness"/>
+                       <channel id="CH73" typeId="system.brightness"/>
+                       <channel id="CH74" typeId="system.brightness"/>
+                       <channel id="CH75" typeId="system.brightness"/>
+                       <channel id="CH76" typeId="system.brightness"/>
+                       <channel id="CH77" typeId="system.brightness"/>
+                       <channel id="CH78" typeId="system.brightness"/>
+                       <channel id="CH79" typeId="system.brightness"/>
+                       <channel id="CH80" typeId="system.brightness"/>
+                       <channel id="CH81" typeId="system.brightness"/>
+               </channels>
+       </channel-group-type>
+       <channel-group-type id="81channelSceneModule">
+               <label>Scene</label>
+               <description>
+                       This is a generic module with 81 scene channels.
+               </description>
+               <channels>
+                       <channel id="CH1" typeId="light-scene"/>
+                       <channel id="CH2" typeId="light-scene"/>
+                       <channel id="CH3" typeId="light-scene"/>
+                       <channel id="CH4" typeId="light-scene"/>
+                       <channel id="CH5" typeId="light-scene"/>
+                       <channel id="CH6" typeId="light-scene"/>
+                       <channel id="CH7" typeId="light-scene"/>
+                       <channel id="CH8" typeId="light-scene"/>
+                       <channel id="CH9" typeId="light-scene"/>
+                       <channel id="CH10" typeId="light-scene"/>
+                       <channel id="CH11" typeId="light-scene"/>
+                       <channel id="CH12" typeId="light-scene"/>
+                       <channel id="CH13" typeId="light-scene"/>
+                       <channel id="CH14" typeId="light-scene"/>
+                       <channel id="CH15" typeId="light-scene"/>
+                       <channel id="CH16" typeId="light-scene"/>
+                       <channel id="CH17" typeId="light-scene"/>
+                       <channel id="CH18" typeId="light-scene"/>
+                       <channel id="CH19" typeId="light-scene"/>
+                       <channel id="CH20" typeId="light-scene"/>
+                       <channel id="CH21" typeId="light-scene"/>
+                       <channel id="CH22" typeId="light-scene"/>
+                       <channel id="CH23" typeId="light-scene"/>
+                       <channel id="CH24" typeId="light-scene"/>
+                       <channel id="CH25" typeId="light-scene"/>
+                       <channel id="CH26" typeId="light-scene"/>
+                       <channel id="CH27" typeId="light-scene"/>
+                       <channel id="CH28" typeId="light-scene"/>
+                       <channel id="CH29" typeId="light-scene"/>
+                       <channel id="CH30" typeId="light-scene"/>
+                       <channel id="CH31" typeId="light-scene"/>
+                       <channel id="CH32" typeId="light-scene"/>
+                       <channel id="CH33" typeId="light-scene"/>
+                       <channel id="CH34" typeId="light-scene"/>
+                       <channel id="CH35" typeId="light-scene"/>
+                       <channel id="CH36" typeId="light-scene"/>
+                       <channel id="CH37" typeId="light-scene"/>
+                       <channel id="CH38" typeId="light-scene"/>
+                       <channel id="CH39" typeId="light-scene"/>
+                       <channel id="CH40" typeId="light-scene"/>
+                       <channel id="CH41" typeId="light-scene"/>
+                       <channel id="CH42" typeId="light-scene"/>
+                       <channel id="CH43" typeId="light-scene"/>
+                       <channel id="CH44" typeId="light-scene"/>
+                       <channel id="CH45" typeId="light-scene"/>
+                       <channel id="CH46" typeId="light-scene"/>
+                       <channel id="CH47" typeId="light-scene"/>
+                       <channel id="CH48" typeId="light-scene"/>
+                       <channel id="CH49" typeId="light-scene"/>
+                       <channel id="CH50" typeId="light-scene"/>
+                       <channel id="CH51" typeId="light-scene"/>
+                       <channel id="CH52" typeId="light-scene"/>
+                       <channel id="CH53" typeId="light-scene"/>
+                       <channel id="CH54" typeId="light-scene"/>
+                       <channel id="CH55" typeId="light-scene"/>
+                       <channel id="CH56" typeId="light-scene"/>
+                       <channel id="CH57" typeId="light-scene"/>
+                       <channel id="CH58" typeId="light-scene"/>
+                       <channel id="CH59" typeId="light-scene"/>
+                       <channel id="CH60" typeId="light-scene"/>
+                       <channel id="CH61" typeId="light-scene"/>
+                       <channel id="CH62" typeId="light-scene"/>
+                       <channel id="CH63" typeId="light-scene"/>
+                       <channel id="CH64" typeId="light-scene"/>
+                       <channel id="CH65" typeId="light-scene"/>
+                       <channel id="CH66" typeId="light-scene"/>
+                       <channel id="CH67" typeId="light-scene"/>
+                       <channel id="CH68" typeId="light-scene"/>
+                       <channel id="CH69" typeId="light-scene"/>
+                       <channel id="CH70" typeId="light-scene"/>
+                       <channel id="CH71" typeId="light-scene"/>
+                       <channel id="CH72" typeId="light-scene"/>
+                       <channel id="CH73" typeId="light-scene"/>
+                       <channel id="CH74" typeId="light-scene"/>
+                       <channel id="CH75" typeId="light-scene"/>
+                       <channel id="CH76" typeId="light-scene"/>
+                       <channel id="CH77" typeId="light-scene"/>
+                       <channel id="CH78" typeId="light-scene"/>
+                       <channel id="CH79" typeId="light-scene"/>
+                       <channel id="CH80" typeId="light-scene"/>
+                       <channel id="CH81" typeId="light-scene"/>
+               </channels>
+       </channel-group-type>
+       <channel-group-type id="16channelVirtualLight">
+               <label>Virtual light</label>
+               <description>
+                       This is a generic module with 16 virtual light channels.
+               </description>
+               <channels>
+                       <channel id="VL1" typeId="system.color"/>
+                       <channel id="VL2" typeId="system.color"/>
+                       <channel id="VL3" typeId="system.color"/>
+                       <channel id="VL4" typeId="system.color"/>
+                       <channel id="VL5" typeId="system.color"/>
+                       <channel id="VL6" typeId="system.color"/>
+                       <channel id="VL7" typeId="system.color"/>
+                       <channel id="VL8" typeId="system.color"/>
+                       <channel id="VL9" typeId="system.color"/>
+                       <channel id="VL10" typeId="system.color"/>
+                       <channel id="VL11" typeId="system.color"/>
+                       <channel id="VL12" typeId="system.color"/>
+                       <channel id="VL13" typeId="system.color"/>
+                       <channel id="VL14" typeId="system.color"/>
+                       <channel id="VL15" typeId="system.color"/>
+                       <channel id="VL16" typeId="system.color"/>
+               </channels>
+       </channel-group-type>
        <channel-group-type id="oledDisplay">
                <label>O-LED Display</label>
                <channels>
diff --git a/bundles/org.openhab.binding.velbus/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.velbus/src/main/resources/OH-INF/update/instructions.xml
new file mode 100644 (file)
index 0000000..188e629
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
+
+       <thing-type uid="velbus:vmbel1">
+               <instruction-set targetVersion="1">
+                       <add-channel id="output" groupIds="output">
+                               <type>velbus:switch</type>
+                       </add-channel>
+               </instruction-set>
+       </thing-type>
+
+       <thing-type uid="velbus:vmbel2">
+               <instruction-set targetVersion="1">
+                       <add-channel id="output" groupIds="output">
+                               <type>velbus:switch</type>
+                       </add-channel>
+               </instruction-set>
+       </thing-type>
+
+       <thing-type uid="velbus:vmbel4">
+               <instruction-set targetVersion="1">
+                       <add-channel id="output" groupIds="output">
+                               <type>velbus:switch</type>
+                       </add-channel>
+               </instruction-set>
+       </thing-type>
+
+       <thing-type uid="velbus:vmbelo">
+               <instruction-set targetVersion="1">
+                       <add-channel id="output" groupIds="output">
+                               <type>velbus:switch</type>
+                       </add-channel>
+               </instruction-set>
+       </thing-type>
+
+</update:update-descriptions>