[nikobus] - added new trigger channels for Nikobus push button (#9166)

* Added new trigger channels for Nikobus push button.

Signed-off-by: Boris Krivonog <boris.krivonog@inova.si>
This commit is contained in:
Boris Krivonog 2020-12-08 00:05:29 +01:00 committed by GitHub
parent 82976235bc
commit 25ea32e2bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 572 additions and 339 deletions

View 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.

View 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

View 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,6 +49,176 @@ import org.slf4j.LoggerFactory;
*/
@NonNullByDefault
public class NikobusPushButtonHandler extends NikobusBaseThingHandler {
private static final String END_OF_TRANSMISSION = "\r#E1";
private final Logger logger = LoggerFactory.getLogger(NikobusPushButtonHandler.class);
private final List<ImpactedModule> impactedModules = new CopyOnWriteArrayList<>();
private final List<TriggerProcessor> triggerProcessors = new CopyOnWriteArrayList<>();
private @Nullable Future<?> requestUpdateFuture;
public NikobusPushButtonHandler(Thing thing) {
super(thing);
}
@Override
public void initialize() {
super.initialize();
if (thing.getStatus() == ThingStatus.OFFLINE) {
return;
}
impactedModules.clear();
triggerProcessors.clear();
Object impactedModulesObject = getConfig().get(CONFIG_IMPACTED_MODULES);
if (impactedModulesObject != null) {
try {
Bridge bridge = getBridge();
if (bridge == null) {
throw new IllegalArgumentException("Bridge does not exist!");
}
ThingUID bridgeUID = thing.getBridgeUID();
if (bridgeUID == null) {
throw new IllegalArgumentException("Unable to read BridgeUID!");
}
String[] impactedModulesString = impactedModulesObject.toString().split(",");
for (String impactedModuleString : impactedModulesString) {
ImpactedModuleUID impactedModuleUID = new ImpactedModuleUID(impactedModuleString.trim());
ThingTypeUID thingTypeUID = new ThingTypeUID(bridgeUID.getBindingId(),
impactedModuleUID.getThingTypeId());
ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, impactedModuleUID.getThingId());
if (!bridge.getThings().stream().anyMatch(thing -> thing.getUID().equals(thingUID))) {
throw new IllegalArgumentException(
"Impacted module " + thingUID + " not found for '" + impactedModuleString + "'");
}
impactedModules.add(new ImpactedModule(thingUID, impactedModuleUID.getGroup()));
}
} catch (RuntimeException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
return;
}
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);
}
}
@Override
public void dispose() {
super.dispose();
Utils.cancel(requestUpdateFuture);
requestUpdateFuture = null;
NikobusPcLinkHandler pcLink = getPcLink();
if (pcLink != null) {
pcLink.removeListener(getAddress());
}
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
logger.debug("handleCommand '{}' '{}'", channelUID, command);
if (!CHANNEL_BUTTON.equals(channelUID.getId())) {
return;
}
// Whenever the button receives an ON command,
// we send a simulated button press to the Nikobus.
if (command == OnOffType.ON) {
NikobusPcLinkHandler pcLink = getPcLink();
if (pcLink != null) {
pcLink.sendCommand(new NikobusCommand(getAddress() + END_OF_TRANSMISSION));
}
}
}
private void commandReceived() {
if (thing.getStatus() != ThingStatus.ONLINE) {
updateStatus(ThingStatus.ONLINE);
}
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);
}
}
private void update() {
for (ImpactedModule module : impactedModules) {
NikobusModuleHandler switchModule = getModuleWithId(module.getThingUID());
if (switchModule != null) {
switchModule.requestStatus(module.getGroup());
}
}
}
private @Nullable NikobusModuleHandler getModuleWithId(ThingUID thingUID) {
Bridge bridge = getBridge();
if (bridge == null) {
return null;
}
Thing thing = bridge.getThing(thingUID);
if (thing == null) {
return null;
}
ThingHandler thingHandler = thing.getHandler();
if (thingHandler instanceof NikobusModuleHandler) {
return (NikobusModuleHandler) thingHandler;
}
return null;
}
@Override
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;
@ -99,139 +271,111 @@ public class NikobusPushButtonHandler extends NikobusBaseThingHandler {
}
}
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 @Nullable Future<?> requestUpdateFuture;
public NikobusPushButtonHandler(Thing thing) {
super(thing);
private interface TriggerProcessor {
void process(long currentTimeMillis);
}
@Override
public void initialize() {
super.initialize();
private abstract class AbstractTriggerProcessor<Config> implements TriggerProcessor {
private long lastCommandReceivedTimestamp = 0;
protected final ChannelUID channelUID;
protected final Config config;
if (thing.getStatus() == ThingStatus.OFFLINE) {
return;
// 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);
}
impactedModules.clear();
Object impactedModulesObject = getConfig().get(CONFIG_IMPACTED_MODULES);
if (impactedModulesObject != null) {
try {
Bridge bridge = getBridge();
if (bridge == null) {
throw new IllegalArgumentException("Bridge does not exist!");
}
ThingUID bridgeUID = thing.getBridgeUID();
if (bridgeUID == null) {
throw new IllegalArgumentException("Unable to read BridgeUID!");
}
String[] impactedModulesString = impactedModulesObject.toString().split(",");
for (String impactedModuleString : impactedModulesString) {
ImpactedModuleUID impactedModuleUID = new ImpactedModuleUID(impactedModuleString.trim());
ThingTypeUID thingTypeUID = new ThingTypeUID(bridgeUID.getBindingId(),
impactedModuleUID.getThingTypeId());
ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, impactedModuleUID.getThingId());
if (!bridge.getThings().stream().anyMatch(thing -> thing.getUID().equals(thingUID))) {
throw new IllegalArgumentException(
"Impacted module " + thingUID + " not found for '" + impactedModuleString + "'");
}
impactedModules.add(new ImpactedModule(thingUID, impactedModuleUID.getGroup()));
}
} catch (RuntimeException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
return;
@Override
public void process(long currentTimeMillis) {
if (Math.abs(currentTimeMillis - lastCommandReceivedTimestamp) > BUTTON_RELEASED_MILIS) {
reset(currentTimeMillis);
}
logger.debug("Impacted modules for {} = {}", thing.getUID(), impactedModules);
lastCommandReceivedTimestamp = currentTimeMillis;
processNext(currentTimeMillis);
}
NikobusPcLinkHandler pcLink = getPcLink();
if (pcLink != null) {
pcLink.addListener(getAddress(), this::commandReceived);
}
abstract protected void reset(long currentTimeMillis);
abstract protected void processNext(long currentTimeMillis);
}
@Override
public void dispose() {
super.dispose();
Utils.cancel(requestUpdateFuture);
requestUpdateFuture = null;
NikobusPcLinkHandler pcLink = getPcLink();
if (pcLink != null) {
pcLink.removeListener(getAddress());
}
public static class TriggerButtonConfig {
public int threshold = 1000;
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
logger.debug("handleCommand '{}' '{}'", channelUID, command);
private class TriggerButton extends AbstractTriggerProcessor<TriggerButtonConfig> {
private long nextLongPressTimestamp = 0;
private @Nullable Future<?> triggerShortPressFuture;
if (!CHANNEL_BUTTON.equals(channelUID.getId())) {
return;
TriggerButton(Channel channel) {
super(TriggerButtonConfig.class, channel);
}
// Whenever the button receives an ON command,
// we send a simulated button press to the Nikobus.
if (command == OnOffType.ON) {
NikobusPcLinkHandler pcLink = getPcLink();
if (pcLink != null) {
pcLink.sendCommand(new NikobusCommand(getAddress() + END_OF_TRANSMISSION));
@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);
}
}
}
private void commandReceived() {
if (thing.getStatus() != ThingStatus.ONLINE) {
updateStatus(ThingStatus.ONLINE);
}
updateState(CHANNEL_BUTTON, OnOffType.ON);
if (!impactedModules.isEmpty()) {
Utils.cancel(requestUpdateFuture);
requestUpdateFuture = scheduler.schedule(this::update, 400, TimeUnit.MILLISECONDS);
@Override
public String toString() {
return "TriggerButton '" + channelUID + "', config: threshold = " + config.threshold;
}
}
private void update() {
for (ImpactedModule module : impactedModules) {
NikobusModuleHandler switchModule = getModuleWithId(module.getThingUID());
if (switchModule != null) {
switchModule.requestStatus(module.getGroup());
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);
}
}
}
}
private @Nullable NikobusModuleHandler getModuleWithId(ThingUID thingUID) {
Bridge bridge = getBridge();
if (bridge == null) {
return null;
@Override
public String toString() {
return "TriggerFilter '" + channelUID + "', config: command = '" + config.command + "', delay = "
+ config.delay + ", period = " + config.period;
}
Thing thing = bridge.getThing(thingUID);
if (thing == null) {
return null;
}
ThingHandler thingHandler = thing.getHandler();
if (thingHandler instanceof NikobusModuleHandler) {
return (NikobusModuleHandler) thingHandler;
}
return null;
}
@Override
protected String getAddress() {
return "#N" + super.getAddress();
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>