]> git.basschouten.com Git - openhab-addons.git/commitdiff
[nikobus] - added new trigger channels for Nikobus push button (#9166)
authorBoris Krivonog <boris.krivonog@inova.si>
Mon, 7 Dec 2020 23:05:29 +0000 (00:05 +0100)
committerGitHub <noreply@github.com>
Mon, 7 Dec 2020 23:05:29 +0000 (15:05 -0800)
* Added new trigger channels for Nikobus push button.

Signed-off-by: Boris Krivonog <boris.krivonog@inova.si>
bundles/org.openhab.binding.nikobus/README.md
bundles/org.openhab.binding.nikobus/src/main/java/org/openhab/binding/nikobus/internal/NikobusBindingConstants.java
bundles/org.openhab.binding.nikobus/src/main/java/org/openhab/binding/nikobus/internal/handler/NikobusPushButtonHandler.java
bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/config/config.xml [new file with mode: 0644]
bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/dimmer-module.xml [new file with mode: 0644]
bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/pc-link.xml [new file with mode: 0644]
bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/push-button.xml [new file with mode: 0644]
bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/rollershutter-module.xml [new file with mode: 0644]
bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/switch-module.xml [new file with mode: 0644]
bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/thing-types.xml [deleted file]

index c23fe401f3245cef6e02f7f82f057e1d63344863..c5982f629d27e99f040fa92caafba60e5806f0e6 100644 (file)
@@ -170,6 +170,29 @@ Thing push-button pb1 [ address = "28092A", impactedModules = "switch-module:s1:
 
 In addition to the status requests triggered by button presses, there is also a scheduled status update interval defined by the `refreshInterval` parameter and explained above.
 
+#### Push Button Trigger Channels
+
+Beside receiving a status update (ON) when a physical Nikobus push button is pressed (and kept pressed), additional triggers can be added and configured to determine how press&hold of a physical push button should generate trigger events. Two types of trigger channels are supported:
+
+* filter trigger and
+* button trigger.
+
+##### Filter Trigger
+
+* `command` - command to be send,
+* `delay` - a required delay in milliseconds defining how much time must a button be pressed before an initial trigger event is fired,
+* `period` - optional time in milliseconds between successive triggers.
+
+Examples:
+
+* `command = PRESSED, delay = 0, period = <empty>` - triggers `PRESSED` event immediatelly when Nikobus button is pressed and is not triggered anymore while holding down the button,
+* `command = INCREMENT, delay = 1000, period = 500` - triggers initial `INCREMENT` event after 1 second and then every half a second while holding down the button.
+
+
+##### Button Trigger
+
+`threshold` - a required long-press threshold in miliseconds. Defines how long must a button be pressed before a long press event is triggered - pressing&holding a Nikobus push-button for `threshold` or more miliseconds will trigger long press event, otherwise a short press event will be triggered.
+
 ## Discovery
 
 Pressing a physical Nikobus push-button will generate a new inbox entry with an exception of buttons already discovered or setup.
@@ -245,6 +268,7 @@ so
 ```
 
 Above example `14E7F4:3` would give:
+
 * for 4 buttons switch - push button A,
 * for 8 buttons switch - push button 2A.
 
index 15a38baf74ce8879cb99bfa67d2ee0f4493f8339..1cc7bdade87472cf90aaa0db46f8af6d5223a3a4 100644 (file)
@@ -37,6 +37,8 @@ public class NikobusBindingConstants {
 
     // List of all Channel ids
     public static final String CHANNEL_BUTTON = "button";
+    public static final String CHANNEL_TRIGGER_FILTER = "trigger-filter";
+    public static final String CHANNEL_TRIGGER_BUTTON = "trigger-button";
     public static final String CHANNEL_OUTPUT_PREFIX = "output-";
 
     // Configuration parameters
index bbf7244eae5f809bd340b5d60602f75110974f94..ef8e6653b31cd083246c356fe6e783497fc56434 100644 (file)
@@ -15,9 +15,8 @@ package org.openhab.binding.nikobus.internal.handler;
 import static org.openhab.binding.nikobus.internal.NikobusBindingConstants.*;
 import static org.openhab.binding.nikobus.internal.protocol.SwitchModuleGroup.*;
 
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
@@ -29,13 +28,16 @@ import org.openhab.binding.nikobus.internal.utils.Utils;
 import org.openhab.core.common.AbstractUID;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.thing.Bridge;
+import org.openhab.core.thing.Channel;
 import org.openhab.core.thing.ChannelUID;
+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.thing.ThingUID;
 import org.openhab.core.thing.binding.ThingHandler;
+import org.openhab.core.thing.type.ChannelTypeUID;
 import org.openhab.core.types.Command;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -47,61 +49,10 @@ import org.slf4j.LoggerFactory;
  */
 @NonNullByDefault
 public class NikobusPushButtonHandler extends NikobusBaseThingHandler {
-    private static class ImpactedModule {
-        private final ThingUID thingUID;
-        private final SwitchModuleGroup group;
-
-        ImpactedModule(ThingUID thingUID, SwitchModuleGroup group) {
-            this.thingUID = thingUID;
-            this.group = group;
-        }
-
-        public ThingUID getThingUID() {
-            return thingUID;
-        }
-
-        public SwitchModuleGroup getGroup() {
-            return group;
-        }
-
-        @Override
-        public String toString() {
-            return "'" + thingUID + "'-" + group;
-        }
-    }
-
-    private static class ImpactedModuleUID extends AbstractUID {
-        ImpactedModuleUID(String uid) {
-            super(uid);
-        }
-
-        String getThingTypeId() {
-            return getSegment(0);
-        }
-
-        String getThingId() {
-            return getSegment(1);
-        }
-
-        SwitchModuleGroup getGroup() {
-            if (getSegment(2).equals("1")) {
-                return FIRST;
-            }
-            if (getSegment(2).equals("2")) {
-                return SECOND;
-            }
-            throw new IllegalArgumentException("Unexpected group found " + getSegment(2));
-        }
-
-        @Override
-        protected int getMinimalNumberOfSegments() {
-            return 3;
-        }
-    }
-
     private static final String END_OF_TRANSMISSION = "\r#E1";
     private final Logger logger = LoggerFactory.getLogger(NikobusPushButtonHandler.class);
-    private final List<ImpactedModule> impactedModules = Collections.synchronizedList(new ArrayList<>());
+    private final List<ImpactedModule> impactedModules = new CopyOnWriteArrayList<>();
+    private final List<TriggerProcessor> triggerProcessors = new CopyOnWriteArrayList<>();
     private @Nullable Future<?> requestUpdateFuture;
 
     public NikobusPushButtonHandler(Thing thing) {
@@ -117,6 +68,7 @@ public class NikobusPushButtonHandler extends NikobusBaseThingHandler {
         }
 
         impactedModules.clear();
+        triggerProcessors.clear();
 
         Object impactedModulesObject = getConfig().get(CONFIG_IMPACTED_MODULES);
         if (impactedModulesObject != null) {
@@ -153,6 +105,20 @@ public class NikobusPushButtonHandler extends NikobusBaseThingHandler {
             logger.debug("Impacted modules for {} = {}", thing.getUID(), impactedModules);
         }
 
+        try {
+            for (Channel channel : thing.getChannels()) {
+                TriggerProcessor processor = createTriggerProcessor(channel);
+                if (processor != null) {
+                    triggerProcessors.add(processor);
+                }
+            }
+        } catch (RuntimeException e) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
+            return;
+        }
+
+        logger.debug("Trigger channels for {} = {}", thing.getUID(), triggerProcessors);
+
         NikobusPcLinkHandler pcLink = getPcLink();
         if (pcLink != null) {
             pcLink.addListener(getAddress(), this::commandReceived);
@@ -197,6 +163,11 @@ public class NikobusPushButtonHandler extends NikobusBaseThingHandler {
 
         updateState(CHANNEL_BUTTON, OnOffType.ON);
 
+        if (!triggerProcessors.isEmpty()) {
+            long currentTimeMillis = System.currentTimeMillis();
+            triggerProcessors.forEach(processor -> processor.process(currentTimeMillis));
+        }
+
         if (!impactedModules.isEmpty()) {
             Utils.cancel(requestUpdateFuture);
             requestUpdateFuture = scheduler.schedule(this::update, 400, TimeUnit.MILLISECONDS);
@@ -234,4 +205,177 @@ public class NikobusPushButtonHandler extends NikobusBaseThingHandler {
     protected String getAddress() {
         return "#N" + super.getAddress();
     }
+
+    private @Nullable TriggerProcessor createTriggerProcessor(Channel channel) {
+        ChannelTypeUID channelTypeUID = channel.getChannelTypeUID();
+        if (channelTypeUID != null) {
+            switch (channelTypeUID.getId()) {
+                case CHANNEL_TRIGGER_FILTER:
+                    return new TriggerFilter(channel);
+                case CHANNEL_TRIGGER_BUTTON:
+                    return new TriggerButton(channel);
+            }
+        }
+        return null;
+    }
+
+    private static class ImpactedModule {
+        private final ThingUID thingUID;
+        private final SwitchModuleGroup group;
+
+        ImpactedModule(ThingUID thingUID, SwitchModuleGroup group) {
+            this.thingUID = thingUID;
+            this.group = group;
+        }
+
+        public ThingUID getThingUID() {
+            return thingUID;
+        }
+
+        public SwitchModuleGroup getGroup() {
+            return group;
+        }
+
+        @Override
+        public String toString() {
+            return "'" + thingUID + "'-" + group;
+        }
+    }
+
+    private static class ImpactedModuleUID extends AbstractUID {
+        ImpactedModuleUID(String uid) {
+            super(uid);
+        }
+
+        String getThingTypeId() {
+            return getSegment(0);
+        }
+
+        String getThingId() {
+            return getSegment(1);
+        }
+
+        SwitchModuleGroup getGroup() {
+            if (getSegment(2).equals("1")) {
+                return FIRST;
+            }
+            if (getSegment(2).equals("2")) {
+                return SECOND;
+            }
+            throw new IllegalArgumentException("Unexpected group found " + getSegment(2));
+        }
+
+        @Override
+        protected int getMinimalNumberOfSegments() {
+            return 3;
+        }
+    }
+
+    private interface TriggerProcessor {
+        void process(long currentTimeMillis);
+    }
+
+    private abstract class AbstractTriggerProcessor<Config> implements TriggerProcessor {
+        private long lastCommandReceivedTimestamp = 0;
+        protected final ChannelUID channelUID;
+        protected final Config config;
+
+        // Nikobus push button will send a new message on bus every ~50ms so
+        // lets assume if we haven't received a new message in over 150ms that
+        // button was released and pressed again.
+        protected static final long BUTTON_RELEASED_MILIS = 150;
+
+        protected AbstractTriggerProcessor(Class<Config> configType, Channel channel) {
+            this.channelUID = channel.getUID();
+            this.config = channel.getConfiguration().as(configType);
+        }
+
+        @Override
+        public void process(long currentTimeMillis) {
+            if (Math.abs(currentTimeMillis - lastCommandReceivedTimestamp) > BUTTON_RELEASED_MILIS) {
+                reset(currentTimeMillis);
+            }
+            lastCommandReceivedTimestamp = currentTimeMillis;
+            processNext(currentTimeMillis);
+        }
+
+        abstract protected void reset(long currentTimeMillis);
+
+        abstract protected void processNext(long currentTimeMillis);
+    }
+
+    public static class TriggerButtonConfig {
+        public int threshold = 1000;
+    }
+
+    private class TriggerButton extends AbstractTriggerProcessor<TriggerButtonConfig> {
+        private long nextLongPressTimestamp = 0;
+        private @Nullable Future<?> triggerShortPressFuture;
+
+        TriggerButton(Channel channel) {
+            super(TriggerButtonConfig.class, channel);
+        }
+
+        @Override
+        protected void reset(long currentTimeMillis) {
+            nextLongPressTimestamp = currentTimeMillis + config.threshold;
+        }
+
+        @Override
+        protected void processNext(long currentTimeMillis) {
+            if (currentTimeMillis < nextLongPressTimestamp) {
+                Utils.cancel(triggerShortPressFuture);
+                triggerShortPressFuture = scheduler.schedule(
+                        () -> triggerChannel(channelUID, CommonTriggerEvents.SHORT_PRESSED), BUTTON_RELEASED_MILIS,
+                        TimeUnit.MILLISECONDS);
+            } else if (nextLongPressTimestamp != 0) {
+                Utils.cancel(triggerShortPressFuture);
+                nextLongPressTimestamp = 0;
+                triggerChannel(channelUID, CommonTriggerEvents.LONG_PRESSED);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "TriggerButton '" + channelUID + "', config: threshold = " + config.threshold;
+        }
+    }
+
+    public static class TriggerFilterConfig {
+        public @Nullable String command;
+        public int delay = 0;
+        public int period = -1;
+    }
+
+    private class TriggerFilter extends AbstractTriggerProcessor<TriggerFilterConfig> {
+        private long nextTriggerTimestamp = 0;
+
+        TriggerFilter(Channel channel) {
+            super(TriggerFilterConfig.class, channel);
+        }
+
+        @Override
+        protected void reset(long currentTimeMillis) {
+            nextTriggerTimestamp = currentTimeMillis + config.delay;
+        }
+
+        @Override
+        protected void processNext(long currentTimeMillis) {
+            if (currentTimeMillis >= nextTriggerTimestamp) {
+                nextTriggerTimestamp = (config.period < 0) ? Long.MAX_VALUE : currentTimeMillis + config.period;
+                String command = config.command;
+                if (command != null) {
+                    triggerChannel(channelUID, command);
+                } else {
+                    triggerChannel(channelUID);
+                }
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "TriggerFilter '" + channelUID + "', config: command = '" + config.command + "', delay = "
+                    + config.delay + ", period = " + config.period;
+        }
+    }
 }
diff --git a/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/config/config.xml
new file mode 100644 (file)
index 0000000..7418e61
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<config-description:config-descriptions
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0 https://openhab.org/schemas/config-description-1.0.0.xsd">
+
+       <config-description uri="push-button:trigger-filter:config">
+               <parameter name="command" type="text">
+                       <label>Command</label>
+                       <description>Command to send</description>
+               </parameter>
+               <parameter name="delay" type="integer" required="true" min="0" unit="ms">
+                       <label>Delay</label>
+                       <description>Delay in milliseconds before triggered</description>
+                       <default>0</default>
+               </parameter>
+               <parameter name="period" type="integer" min="0" unit="ms">
+                       <label>Period</label>
+                       <description>Time in milliseconds between successive triggers</description>
+               </parameter>
+       </config-description>
+
+       <config-description uri="push-button:trigger-button:config">
+               <parameter name="threshold" type="integer" required="true" min="0" unit="ms">
+                       <label>Threshold</label>
+                       <description>Long-press threshold in milliseconds</description>
+                       <default>1000</default>
+               </parameter>
+       </config-description>
+
+       <config-description uri="module:address:config">
+               <parameter name="address" type="text" required="true">
+                       <label>Address</label>
+                       <description>The Nikobus address of the module</description>
+               </parameter>
+       </config-description>
+
+</config-description:config-descriptions>
diff --git a/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/dimmer-module.xml b/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/dimmer-module.xml
new file mode 100644 (file)
index 0000000..86f7e00
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="nikobus"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+       <thing-type id="dimmer-module">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="pc-link"/>
+               </supported-bridge-type-refs>
+
+               <label>Dimmer Module</label>
+               <description>Nikobus Dimmer module</description>
+
+               <channels>
+                       <channel id="output-1" typeId="dimmer-output">
+                               <label>Output 1</label>
+                       </channel>
+                       <channel id="output-2" typeId="dimmer-output">
+                               <label>Output 2</label>
+                       </channel>
+                       <channel id="output-3" typeId="dimmer-output">
+                               <label>Output 3</label>
+                       </channel>
+                       <channel id="output-4" typeId="dimmer-output">
+                               <label>Output 4</label>
+                       </channel>
+                       <channel id="output-5" typeId="dimmer-output">
+                               <label>Output 5</label>
+                       </channel>
+                       <channel id="output-6" typeId="dimmer-output">
+                               <label>Output 6</label>
+                       </channel>
+                       <channel id="output-7" typeId="dimmer-output">
+                               <label>Output 7</label>
+                       </channel>
+                       <channel id="output-8" typeId="dimmer-output">
+                               <label>Output 8</label>
+                       </channel>
+                       <channel id="output-9" typeId="dimmer-output">
+                               <label>Output 9</label>
+                       </channel>
+                       <channel id="output-10" typeId="dimmer-output">
+                               <label>Output 10</label>
+                       </channel>
+                       <channel id="output-11" typeId="dimmer-output">
+                               <label>Output 11</label>
+                       </channel>
+                       <channel id="output-12" typeId="dimmer-output">
+                               <label>Output 12</label>
+                       </channel>
+               </channels>
+
+               <config-description-ref uri="module:address:config"/>
+       </thing-type>
+
+       <channel-type id="dimmer-output">
+               <item-type>Dimmer</item-type>
+               <label>Output</label>
+               <description>Dimmer Module's Output</description>
+       </channel-type>
+
+</thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/pc-link.xml b/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/pc-link.xml
new file mode 100644 (file)
index 0000000..3825d15
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="nikobus"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+       <bridge-type id="pc-link">
+               <label>PC-Link</label>
+               <description>PC-Link via serial connection</description>
+
+               <config-description>
+                       <parameter name="port" type="text" required="true">
+                               <label>Port</label>
+                               <context>serial-port</context>
+                               <limitToOptions>false</limitToOptions>
+                               <description>The serial port used to connect to the Nikobus PC Link.</description>
+                       </parameter>
+                       <parameter name="refreshInterval" type="integer" max="65535" min="10" unit="s">
+                               <default>60</default>
+                               <label>Refresh Interval</label>
+                               <description>Refresh interval in seconds.</description>
+                       </parameter>
+               </config-description>
+       </bridge-type>
+
+</thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/push-button.xml b/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/push-button.xml
new file mode 100644 (file)
index 0000000..f272ea7
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="nikobus"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+       <thing-type id="push-button" extensible="trigger-filter,trigger-button">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="pc-link"/>
+               </supported-bridge-type-refs>
+
+               <label>Push Button</label>
+               <description>A single push button</description>
+
+               <channels>
+                       <channel id="button" typeId="button"/>
+               </channels>
+
+               <config-description>
+                       <parameter name="address" type="text" required="true">
+                               <label>Address</label>
+                               <description>The Nikobus address of the push-button.</description>
+                       </parameter>
+                       <parameter name="impactedModules" type="text">
+                               <label>Impacted Modules</label>
+                               <description>Comma separated list of impacted modules, i.e. switch-module:s1:1</description>
+                       </parameter>
+               </config-description>
+       </thing-type>
+
+       <channel-type id="button">
+               <item-type>Switch</item-type>
+               <label>Button Event</label>
+               <description>Fires when the button is pressed</description>
+       </channel-type>
+
+       <channel-type id="trigger-filter">
+               <kind>trigger</kind>
+               <label>Trigger Filter Channel</label>
+               <event/>
+               <config-description-ref uri="push-button:trigger-filter:config"/>
+       </channel-type>
+
+       <channel-type id="trigger-button">
+               <kind>trigger</kind>
+               <label>Trigger Button Channel</label>
+               <event>
+                       <options>
+                               <option value="SHORT_PRESSED">short pressed</option>
+                               <option value="LONG_PRESSED">long pressed</option>
+                       </options>
+               </event>
+               <config-description-ref uri="push-button:trigger-button:config"/>
+       </channel-type>
+
+</thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/rollershutter-module.xml b/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/rollershutter-module.xml
new file mode 100644 (file)
index 0000000..258f5cd
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="nikobus"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+       <thing-type id="rollershutter-module">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="pc-link"/>
+               </supported-bridge-type-refs>
+
+               <label>Rollershutter Module</label>
+               <description>Nikobus Rollershutter module</description>
+
+               <channels>
+                       <channel id="output-1" typeId="rollershutter-output">
+                               <label>Output 1</label>
+                       </channel>
+                       <channel id="output-2" typeId="rollershutter-output">
+                               <label>Output 2</label>
+                       </channel>
+                       <channel id="output-3" typeId="rollershutter-output">
+                               <label>Output 3</label>
+                       </channel>
+                       <channel id="output-4" typeId="rollershutter-output">
+                               <label>Output 4</label>
+                       </channel>
+                       <channel id="output-5" typeId="rollershutter-output">
+                               <label>Output 5</label>
+                       </channel>
+                       <channel id="output-6" typeId="rollershutter-output">
+                               <label>Output 6</label>
+                       </channel>
+               </channels>
+
+               <config-description-ref uri="module:address:config"/>
+       </thing-type>
+
+       <channel-type id="rollershutter-output">
+               <item-type>Rollershutter</item-type>
+               <label>Output</label>
+               <description>Rollershutter Module's Output</description>
+       </channel-type>
+
+</thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/switch-module.xml b/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/switch-module.xml
new file mode 100644 (file)
index 0000000..419ce16
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="nikobus"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+       <thing-type id="switch-module">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="pc-link"/>
+               </supported-bridge-type-refs>
+
+               <label>Switch Module</label>
+               <description>Nikobus Switch module</description>
+
+               <channels>
+                       <channel id="output-1" typeId="switch-output">
+                               <label>Output 1</label>
+                       </channel>
+                       <channel id="output-2" typeId="switch-output">
+                               <label>Output 2</label>
+                       </channel>
+                       <channel id="output-3" typeId="switch-output">
+                               <label>Output 3</label>
+                       </channel>
+                       <channel id="output-4" typeId="switch-output">
+                               <label>Output 4</label>
+                       </channel>
+                       <channel id="output-5" typeId="switch-output">
+                               <label>Output 5</label>
+                       </channel>
+                       <channel id="output-6" typeId="switch-output">
+                               <label>Output 6</label>
+                       </channel>
+                       <channel id="output-7" typeId="switch-output">
+                               <label>Output 7</label>
+                       </channel>
+                       <channel id="output-8" typeId="switch-output">
+                               <label>Output 8</label>
+                       </channel>
+                       <channel id="output-9" typeId="switch-output">
+                               <label>Output 9</label>
+                       </channel>
+                       <channel id="output-10" typeId="switch-output">
+                               <label>Output 10</label>
+                       </channel>
+                       <channel id="output-11" typeId="switch-output">
+                               <label>Output 11</label>
+                       </channel>
+                       <channel id="output-12" typeId="switch-output">
+                               <label>Output 12</label>
+                       </channel>
+               </channels>
+
+               <config-description-ref uri="module:address:config"/>
+       </thing-type>
+
+       <channel-type id="switch-output">
+               <item-type>Switch</item-type>
+               <label>Output</label>
+               <description>Switch Module's Output</description>
+       </channel-type>
+
+</thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.nikobus/src/main/resources/OH-INF/thing/thing-types.xml
deleted file mode 100644 (file)
index 8c3d4ed..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<thing:thing-descriptions bindingId="nikobus"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
-       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
-
-       <bridge-type id="pc-link">
-               <label>PC-Link</label>
-               <description>PC-Link via serial connection</description>
-
-               <config-description>
-                       <parameter name="port" type="text" required="true">
-                               <label>Port</label>
-                               <context>serial-port</context>
-                               <limitToOptions>false</limitToOptions>
-                               <description>The serial port used to connect to the Nikobus PC Link.</description>
-                       </parameter>
-                       <parameter name="refreshInterval" type="integer" max="65535" min="10" required="false">
-                               <default>60</default>
-                               <label>Refresh Interval</label>
-                               <description>Refresh interval in seconds.</description>
-                       </parameter>
-               </config-description>
-       </bridge-type>
-
-       <thing-type id="push-button">
-               <supported-bridge-type-refs>
-                       <bridge-type-ref id="pc-link"/>
-               </supported-bridge-type-refs>
-
-               <label>Push Button</label>
-               <description>A single push button</description>
-
-               <channels>
-                       <channel id="button" typeId="button"/>
-               </channels>
-
-               <config-description>
-                       <parameter name="address" type="text">
-                               <label>Address</label>
-                               <description>The Nikobus address of the module</description>
-                       </parameter>
-                       <parameter name="impactedModules" type="text">
-                               <label>Impacted Modules</label>
-                               <description>Comma separated list of impacted modules, i.e. switch-module:s1:1</description>
-                       </parameter>
-               </config-description>
-       </thing-type>
-
-       <channel-type id="button">
-               <item-type>Switch</item-type>
-               <label>Button Event</label>
-               <description>Fires when the button is pressed</description>
-
-               <config-description>
-                       <parameter name="address" type="text">
-                               <label>Address</label>
-                               <description>The Nikobus address of the module</description>
-                       </parameter>
-               </config-description>
-       </channel-type>
-
-       <thing-type id="switch-module">
-               <supported-bridge-type-refs>
-                       <bridge-type-ref id="pc-link"/>
-               </supported-bridge-type-refs>
-
-               <label>Switch Module</label>
-               <description>Nikobus Switch module</description>
-
-               <channels>
-                       <channel id="output-1" typeId="switch-output">
-                               <label>Output 1</label>
-                       </channel>
-                       <channel id="output-2" typeId="switch-output">
-                               <label>Output 2</label>
-                       </channel>
-                       <channel id="output-3" typeId="switch-output">
-                               <label>Output 3</label>
-                       </channel>
-                       <channel id="output-4" typeId="switch-output">
-                               <label>Output 4</label>
-                       </channel>
-                       <channel id="output-5" typeId="switch-output">
-                               <label>Output 5</label>
-                       </channel>
-                       <channel id="output-6" typeId="switch-output">
-                               <label>Output 6</label>
-                       </channel>
-                       <channel id="output-7" typeId="switch-output">
-                               <label>Output 7</label>
-                       </channel>
-                       <channel id="output-8" typeId="switch-output">
-                               <label>Output 8</label>
-                       </channel>
-                       <channel id="output-9" typeId="switch-output">
-                               <label>Output 9</label>
-                       </channel>
-                       <channel id="output-10" typeId="switch-output">
-                               <label>Output 10</label>
-                       </channel>
-                       <channel id="output-11" typeId="switch-output">
-                               <label>Output 11</label>
-                       </channel>
-                       <channel id="output-12" typeId="switch-output">
-                               <label>Output 12</label>
-                       </channel>
-               </channels>
-
-               <config-description>
-                       <parameter name="address" type="text">
-                               <label>Address</label>
-                               <description>The Nikobus address of the module</description>
-                       </parameter>
-               </config-description>
-       </thing-type>
-
-       <thing-type id="dimmer-module">
-               <supported-bridge-type-refs>
-                       <bridge-type-ref id="pc-link"/>
-               </supported-bridge-type-refs>
-
-               <label>Dimmer Module</label>
-               <description>Nikobus Dimmer module</description>
-
-               <channels>
-                       <channel id="output-1" typeId="dimmer-output">
-                               <label>Output 1</label>
-                       </channel>
-                       <channel id="output-2" typeId="dimmer-output">
-                               <label>Output 2</label>
-                       </channel>
-                       <channel id="output-3" typeId="dimmer-output">
-                               <label>Output 3</label>
-                       </channel>
-                       <channel id="output-4" typeId="dimmer-output">
-                               <label>Output 4</label>
-                       </channel>
-                       <channel id="output-5" typeId="dimmer-output">
-                               <label>Output 5</label>
-                       </channel>
-                       <channel id="output-6" typeId="dimmer-output">
-                               <label>Output 6</label>
-                       </channel>
-                       <channel id="output-7" typeId="dimmer-output">
-                               <label>Output 7</label>
-                       </channel>
-                       <channel id="output-8" typeId="dimmer-output">
-                               <label>Output 8</label>
-                       </channel>
-                       <channel id="output-9" typeId="dimmer-output">
-                               <label>Output 9</label>
-                       </channel>
-                       <channel id="output-10" typeId="dimmer-output">
-                               <label>Output 10</label>
-                       </channel>
-                       <channel id="output-11" typeId="dimmer-output">
-                               <label>Output 11</label>
-                       </channel>
-                       <channel id="output-12" typeId="dimmer-output">
-                               <label>Output 12</label>
-                       </channel>
-               </channels>
-
-               <config-description>
-                       <parameter name="address" type="text">
-                               <label>Address</label>
-                               <description>The Nikobus address of the module</description>
-                       </parameter>
-               </config-description>
-       </thing-type>
-
-       <thing-type id="rollershutter-module">
-               <supported-bridge-type-refs>
-                       <bridge-type-ref id="pc-link"/>
-               </supported-bridge-type-refs>
-
-               <label>Rollershutter Module</label>
-               <description>Nikobus Rollershutter module</description>
-
-               <channels>
-                       <channel id="output-1" typeId="rollershutter-output">
-                               <label>Output 1</label>
-                       </channel>
-                       <channel id="output-2" typeId="rollershutter-output">
-                               <label>Output 2</label>
-                       </channel>
-                       <channel id="output-3" typeId="rollershutter-output">
-                               <label>Output 3</label>
-                       </channel>
-                       <channel id="output-4" typeId="rollershutter-output">
-                               <label>Output 4</label>
-                       </channel>
-                       <channel id="output-5" typeId="rollershutter-output">
-                               <label>Output 5</label>
-                       </channel>
-                       <channel id="output-6" typeId="rollershutter-output">
-                               <label>Output 6</label>
-                       </channel>
-               </channels>
-
-               <config-description>
-                       <parameter name="address" type="text">
-                               <label>Address</label>
-                               <description>The Nikobus address of the module</description>
-                       </parameter>
-               </config-description>
-       </thing-type>
-
-       <channel-type id="switch-output">
-               <item-type>Switch</item-type>
-               <label>Output</label>
-               <description>Switch Module's Output</description>
-       </channel-type>
-
-       <channel-type id="dimmer-output">
-               <item-type>Dimmer</item-type>
-               <label>Output</label>
-               <description>Dimmer Module's Output</description>
-       </channel-type>
-
-       <channel-type id="rollershutter-output">
-               <item-type>Rollershutter</item-type>
-               <label>Output</label>
-               <description>Rollershutter Module's Output</description>
-       </channel-type>
-
-</thing:thing-descriptions>