From: M Valla <12682715+mvalla@users.noreply.github.com> Date: Sat, 30 Oct 2021 16:10:03 +0000 (+0200) Subject: [openwebnet] added support for CEN/CEN+ scenarios (WHO=15/25) (#11398) X-Git-Url: https://git.basschouten.com/?a=commitdiff_plain;h=3bd2939b6c796074defa97427df355e05931d13f;p=openhab-addons.git [openwebnet] added support for CEN/CEN+ scenarios (WHO=15/25) (#11398) * [openwebnet] first support for CEN Signed-off-by: Massimo Valla * [openwebnet] added CEN actions. OpenWebNetThingHandler.send() is now public Signed-off-by: Massimo Valla * [openwebnet] added CEN+ support Signed-off-by: Massimo Valla * [openwebnet] use WhereCEN, removed nullpointer warnings from EnergyHandler. Improved README Signed-off-by: Massimo Valla * [openwebnet] completed support for CEN/CEN+ Signed-off-by: Massimo Valla * [openwebnet] improved log Signed-off-by: Massimo Valla * [openwebnet] corrected "pressure" and renamed some labels Signed-off-by: Massimo Valla --- diff --git a/bundles/org.openhab.binding.openwebnet/README.md b/bundles/org.openhab.binding.openwebnet/README.md index da42c54067..89e1b8665e 100644 --- a/bundles/org.openhab.binding.openwebnet/README.md +++ b/bundles/org.openhab.binding.openwebnet/README.md @@ -44,6 +44,7 @@ The following Things and OpenWebNet `WHOs` are supported: | Lighting | `1` | `bus_on_off_switch`, `bus_dimmer` | BUS switches and dimmers | Successfully tested: F411/2, F411/4, F411U2, F422, F429. Some discovery issues reported with F429 (DALI Dimmers) | | Automation | `2` | `bus_automation` | BUS roller shutters, with position feedback and auto-calibration | Successfully tested: LN4672M2 | | Temperature Control | `4` | `bus_thermo_zone`, `bus_thermo_sensor` | Thermo zones management and temperature sensors (probes). NOTE Central Units (4 or 99 zones) are not fully supported yet. See [Channels - Thermo](#configuring-thermo) for more details. | Successfully tested: H/LN4691, HS4692, KG4691; thermo sensors: L/N/NT4577 + 3455 | +| CEN & CEN+ Scenarios | `15` & `25` | `bus_cen_scenario_control`, `bus_cenplus_scenario_control` | CEN/CEN+ scenarios events and virtual activation | Successfully tested: scenario buttons: HC/HD/HS/L/N/NT4680 | | Energy Management | `18` | `bus_energy_meter` | Energy Management | Successfully tested: F520, F521 | ### For ZigBee (Radio) @@ -66,6 +67,7 @@ For other gateways you can add them manually, see [Thing Configuration](#thing-c - Once the gateway is online, a second Inbox Scan will discover BUS devices - BUS/SCS Dimmers must be ON and dimmed (30%-100%) during a Scan, otherwise they will be discovered as simple On/Off switches - *KNOWN ISSUE*: In some cases dimmers connected to a F429 Dali-interface are not automatically discovered +- CEN/CEN+ Scenario Control devices will be discovered by activation only. See [discovery by activation](#discovery-by-activation) for details. After confirming a discovered CEN/CEN+ device from Inbox, activate again its scenario buttons to add button channels automatically #### Discovery by Activation @@ -117,13 +119,18 @@ Alternatively the ZigBee USB Gateway thing can be configured using the `.things` ### Configuring Devices Devices can be discovered automatically using an Inbox Scan after a gateway has been configured and connected. + For any manually added device, you must configure: - the associated gateway (`Parent Bridge` menu) - the `where` config parameter (`OpenWebNet Device Address`): - - example for BUS/SCS device with WHERE address Point to Point `A=2 PL=4` --> `where="24"` - - example for BUS/SCS device with WHERE address Point to Point `A=03 PL=11` on local bus --> `where="0311#4#01"` - - example for ZigBee devices: `where=765432101#9`. The ID of the device (ADDR part) is usually written in hexadecimal on the device itself, for example `ID 0074CBB1`: convert to decimal (`7654321`) and add `01#9` at the end to obtain `where=765432101#9`. For 2-unit switch devices (`zb_on_off_switch2u`), last part should be `00#9`. + - example for BUS/SCS: + - light device with WHERE address Point to Point `A=2 PL=4` --> `where="24"` + - light device with WHERE address Point to Point `A=03 PL=11` on local bus --> `where="0311#4#01"` + - CEN scenario with WHERE address Point to Point `A=05 PL=12` --> `where="0512"` + - CEN+ configured scenario `5`: add a `2` before --> `where="25"` + - example for ZigBee devices: `where=765432101#9`. The ID of the device (ADDR part) is usually written in hexadecimal on the device itself, for example `ID 0074CBB1`: convert to decimal (`7654321`) and add `01#9` at the end to obtain `where=765432101#9`. For 2-unit switch devices (`zb_on_off_switch2u`), last part should be `00#9`. + #### Configuring Thermo @@ -132,14 +139,14 @@ In BTicino MyHOME Thermoregulation (WHO=4) each **zone** has associated a thermo Thermo zones can be configured defining a `bus_thermo_zone` Thing for each zone with the following parameters: - the `where` config parameter (`OpenWebNet Device Address`): - - example BUS/SCS Thermo zone `1` --> `where="1"` + - example BUS/SCS Thermo zone `1` --> `where="1"` - the `standAlone` config parameter (`boolean`, default: `true`): identifies if the zone is managed or not by a Central Unit (4 or 99 zones). `standAlone=true` means no Central Unit is present in the system. Temperature sensors can be configured defining a `bus_thermo_sensor` Thing with the following parameters: - the `where` config parameter (`OpenWebNet Device Address`): - - example sensor `5` of external zone `00` --> `where="500"` - - example: slave sensor `3` of zone `2` --> `where="302"` + - example sensor `5` of external zone `00` --> `where="500"` + - example: slave sensor `3` of zone `2` --> `where="302"` #### NOTE @@ -148,13 +155,14 @@ Systems with Central Units (4 or 99 zones) are not fully supported yet. ## Channels -### Lighting, Automation and Power meter channels +### Lighting, Automation, Power meter and CEN/CEN+ Scenario Events channels | Channel Type ID (channel ID) | Applies to Thing Type IDs | Item Type | Description | Read/Write | | ---------------------------------------- | ------------------------------------------------------------- | ------------- | ----------------------------------------------------- | :--------: | | `switch` or `switch_01`/`02` for ZigBee | `bus_on_off_switch`, `zb_on_off_switch`, `zb_on_off_switch2u` | Switch | To switch the device `ON` and `OFF` | R/W | | `brightness` | `bus_dimmer`, `zb_dimmer` | Dimmer | To adjust the brightness value (Percent, `ON`, `OFF`) | R/W | | `shutter` | `bus_automation` | Rollershutter | To activate roller shutters (`UP`, `DOWN`, `STOP`, Percent - [see Shutter position](#shutter-position)) | R/W | +| `button#X` | `bus_cen_scenario_control`, `bus_cenplus_scenario_control` | String | Trigger channel for CEN/CEN+ scenario events [see possible values](#cen-cen-channels) | R (TRIGGER) | | `power` | `bus_energy_meter` | Number:Power | The current active power usage from Energy Meter | R | ### Thermo channels @@ -183,6 +191,31 @@ It's possible to enter a value manually or set `shutterRun=AUTO` (default) to ca - if OH is restarted the binding does not know if a shutter position has changed in the meantime, so its position will be `UNDEF`. Move the shutter all `UP`/`DOWN` to synchronize again its position with the binding - the shutter position is estimated based on UP/DOWN timing: an error of ±2% is normal +#### CEN/CEN+ channels + +CEN/CEN+ are [TRIGGER channels](https://www.openhab.org/docs/configuration/rules-dsl.html#channel-based-triggers]): they handle events and do not have a state. + +A powerful feature is to be able to assign CEN or CEN+ commands to your physical wall switches and use the events they generate to trigger rules in openHAB: this way openHAB becomes a very powerful scenario manager activated by physical BTicino switches. +See [openwebnet.rules](#openwebnet-rules) for an example on how to define rules that trigger on CEN/CEN+ buttons events. + +It's also possible to send *virtual press* events on the BUS, for example to enable the activation of MH202 scenarios from openHAB. +See [openwebnet.sitemap](#openwebnet-sitemap) & [openwebnet.rules](#openwebnet-rules) sections for an example on how to use the `virtualPress` action connected to a pushbutton on a sitemap. + +- channels are named `button#X` where `X` is the button number on the Scenario Control device +- in the .thing file configuration you can specify the `buttons` parameter to define a comma-separated list of buttons numbers [0-31] configured for the scenario device, example: `buttons=1,2,4` +- possible events are: + - for CEN: + - `START_PRESS` - sent when you start pressing the button + - `SHORT_PRESS` - sent if you pressed the button shorter than 0,5sec (sent at the moment when you release it) + - `EXTENDED_PRESS` - sent if you keep the button pressed longer than 0,5sec; will be sent again every 0,5sec as long as you hold pressed (good for dimming rules) + - `RELEASE_EXTENDED_PRESS` - sent once when you finally release the button after having it pressed longer than 0,5sec + - for CEN+: + - `SHORT_PRESS` - sent if you pressed the button shorter than 0,5sec (sent at the moment when you release it) + - `START_EXTENDED_PRESS` - sent once as soon as you keep the button pressed longer than 0,5sec + - `EXTENDED_PRESS` - sent after `START_EXTENDED_PRESS` if you keep the button pressed longer; will be sent again every 0,5sec as long as you hold pressed (good for dimming rules) + - `RELEASE_EXTENDED_PRESS` - sent once when you finally release the button after having it pressed longer than 0,5sec + + ## Full Example ### openwebnet.things: @@ -191,13 +224,15 @@ BUS gateway and things configuration: ``` Bridge openwebnet:bus_gateway:mybridge "MyHOMEServer1" [ host="192.168.1.35", passwd="abcde", port=20000, discoveryByActivation=false ] { - bus_on_off_switch LR_switch "Living Room Light" [ where="51" ] - bus_dimmer LR_dimmer "Living Room Dimmer" [ where="0311#4#01" ] - bus_automation LR_shutter "Living Room Shutter" [ where="93", shutterRun="10050"] - bus_energy_meter CENTRAL_Ta "Energy Meter Ta" [ where="51" ] - bus_energy_meter CENTRAL_Tb "Energy Meter Tb" [ where="52" ] - bus_thermo_zone LR_zone "Living Room Zone" [ where="2"] - bus_thermo_sensor EXT_tempsensor "External Temperature" [ where="500"] + bus_on_off_switch LR_switch "Living Room Light" [ where="51" ] + bus_dimmer LR_dimmer "Living Room Dimmer" [ where="0311#4#01" ] + bus_automation LR_shutter "Living Room Shutter" [ where="93", shutterRun="10050"] + bus_energy_meter CENTRAL_Ta "Energy Meter Ta" [ where="51" ] + bus_energy_meter CENTRAL_Tb "Energy Meter Tb" [ where="52" ] + bus_thermo_zone LR_zone "Living Room Zone" [ where="2"] + bus_thermo_sensor EXT_tempsensor "External Temperature" [ where="500"] + bus_cen_scenario_control LR_CEN_scenario "Living Room CEN" [ where="51", buttons="4,3,8"] + bus_cenplus_scenario_control LR_CENplus_scenario "Living Room CEN+" [ where="212", buttons="1,5,18" ] } ``` @@ -240,6 +275,8 @@ String iLR_zone_cv "Conditioning valves" (g Number:Temperature iEXT_temp "Temperature [%.1f %unit%]" (gExternal) { channel="openwebnet:bus_thermo_sensor:mybridge:EXT_tempsensor:temperature" } +String iCENPlusProxyItem "CEN+ Proxy Item" + ``` @@ -281,9 +318,47 @@ sitemap openwebnet label="OpenWebNet Binding Example Sitemap" Default item=iLR_zone_hv label="Heating valves status" Default item=iLR_zone_cv label="Conditioning valves status" } + + Frame label="CEN+ Scenario activation" + { + Switch item=iCENPlusProxyItem label="My CEN+ scenario" icon="movecontrol" mappings=[ON="Activate"] + } } ``` +### openwebnet.rules + +```xtend +rule "CEN+ virtual press from OH button" +/* This rule triggers when the proxy item iCENPlusProxyItem is activated, for example from a button on WebUI/sitemap. +When activated it sends a "virtual short press" event (where=212, button=5) on the BUS +*/ +when + Item iCENPlusProxyItem received command +then + val actions = getActions("openwebnet","openwebnet:bus_cenplus_scenario_control:mybridge:212") + actions.virtualPress("SHORT_PRESS", 5) +end + + +rule "CEN dimmer increase" +// A "start press" event on CEN where=51, button=4 will increase dimmer% +when + Channel "openwebnet:bus_cen_scenario_control:mybridge:51:button#4" triggered START_PRESS +then + sendCommand(iLR_dimmer, INCREASE) +end + + +rule "CEN dimmer decrease" +// A "release extended press" event on CEN where=51, button=4 will decrease dimmer% +when + Channel "openwebnet:bus_cen_scenario_control:mybridge:51:button#4" triggered RELEASE_EXTENDED_PRESS +then + sendCommand(iLR_dimmer, DECREASE) +end +``` + ## Notes - The OpenWebNet protocol is maintained and Copyright by BTicino/Legrand. The documentation of the protocol if freely accessible for developers on the [Legrand developer web site](https://developer.legrand.com/documentation/open-web-net-for-myhome/) diff --git a/bundles/org.openhab.binding.openwebnet/pom.xml b/bundles/org.openhab.binding.openwebnet/pom.xml index a69d138d68..a6e25ffac9 100644 --- a/bundles/org.openhab.binding.openwebnet/pom.xml +++ b/bundles/org.openhab.binding.openwebnet/pom.xml @@ -23,7 +23,7 @@ io.github.openwebnet4j openwebnet4j - 0.5.3 + 0.6.0 compile diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/OpenWebNetBindingConstants.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/OpenWebNetBindingConstants.java index 1f039a06fa..218aa20fe9 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/OpenWebNetBindingConstants.java +++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/OpenWebNetBindingConstants.java @@ -59,6 +59,12 @@ public class OpenWebNetBindingConstants { public static final String THING_LABEL_BUS_THERMO_SENSOR = "Thermo Sensor"; public static final ThingTypeUID THING_TYPE_BUS_THERMO_ZONE = new ThingTypeUID(BINDING_ID, "bus_thermo_zone"); public static final String THING_LABEL_BUS_THERMO_ZONE = "Thermo Zone"; + public static final ThingTypeUID THING_TYPE_BUS_CEN_SCENARIO_CONTROL = new ThingTypeUID(BINDING_ID, + "bus_cen_scenario_control"); + public static final String THING_LABEL_BUS_CEN_SCENARIO_CONTROL = "CEN Control"; + public static final ThingTypeUID THING_TYPE_BUS_CENPLUS_SCENARIO_CONTROL = new ThingTypeUID(BINDING_ID, + "bus_cenplus_scenario_control"); + public static final String THING_LABEL_BUS_CENPLUS_SCENARIO_CONTROL = "CEN+ Control"; // ZIGBEE public static final ThingTypeUID THING_TYPE_ZB_ON_OFF_SWITCH = new ThingTypeUID(BINDING_ID, "zb_on_off_switch"); @@ -81,24 +87,22 @@ public class OpenWebNetBindingConstants { // ## Automation public static final Set AUTOMATION_SUPPORTED_THING_TYPES = Set.of(THING_TYPE_ZB_AUTOMATION, THING_TYPE_BUS_AUTOMATION); - // ## Thermoregulation public static final Set THERMOREGULATION_SUPPORTED_THING_TYPES = Set.of(THING_TYPE_BUS_THERMO_ZONE, THING_TYPE_BUS_THERMO_SENSOR); - // ## Energy Management public static final Set ENERGY_MANAGEMENT_SUPPORTED_THING_TYPES = Set.of(THING_TYPE_BUS_ENERGY_METER); - + // ## CEN/CEN+ Scenario + public static final Set SCENARIO_SUPPORTED_THING_TYPES = Set.of(THING_TYPE_BUS_CEN_SCENARIO_CONTROL, + THING_TYPE_BUS_CENPLUS_SCENARIO_CONTROL); // ## Groups public static final Set DEVICE_SUPPORTED_THING_TYPES = Stream .of(LIGHTING_SUPPORTED_THING_TYPES, AUTOMATION_SUPPORTED_THING_TYPES, THERMOREGULATION_SUPPORTED_THING_TYPES, ENERGY_MANAGEMENT_SUPPORTED_THING_TYPES, - GENERIC_SUPPORTED_THING_TYPES) + SCENARIO_SUPPORTED_THING_TYPES, GENERIC_SUPPORTED_THING_TYPES) .flatMap(Collection::stream).collect(Collectors.toCollection(HashSet::new)); - public static final Set BRIDGE_SUPPORTED_THING_TYPES = Set.of(THING_TYPE_ZB_GATEWAY, THING_TYPE_BUS_GATEWAY); - public static final Set ALL_SUPPORTED_THING_TYPES = Stream .of(DEVICE_SUPPORTED_THING_TYPES, BRIDGE_SUPPORTED_THING_TYPES).flatMap(Collection::stream) .collect(Collectors.toCollection(HashSet::new)); @@ -109,10 +113,8 @@ public class OpenWebNetBindingConstants { public static final String CHANNEL_SWITCH_01 = "switch_01"; public static final String CHANNEL_SWITCH_02 = "switch_02"; public static final String CHANNEL_BRIGHTNESS = "brightness"; - // automation public static final String CHANNEL_SHUTTER = "shutter"; - // thermo public static final String CHANNEL_TEMPERATURE = "temperature"; public static final String CHANNEL_FUNCTION = "function"; @@ -122,18 +124,20 @@ public class OpenWebNetBindingConstants { public static final String CHANNEL_CONDITIONING_VALVES = "conditioningValves"; public static final String CHANNEL_HEATING_VALVES = "heatingValves"; public static final String CHANNEL_ACTUATORS = "actuators"; - // energy management public static final String CHANNEL_POWER = "power"; + // scenario button channels + public static final String CHANNEL_SCENARIO_BUTTON = "button#"; + public static final String CHANNEL_TYPE_CEN_BUTTON_EVENT = "cenButtonEvent"; + public static final String CHANNEL_TYPE_CEN_PLUS_BUTTON_EVENT = "cenPlusButtonEvent"; // devices config properties public static final String CONFIG_PROPERTY_WHERE = "where"; public static final String CONFIG_PROPERTY_SHUTTER_RUN = "shutterRun"; - + public static final String CONFIG_PROPERTY_SCENARIO_BUTTONS = "buttons"; // BUS gw config properties public static final String CONFIG_PROPERTY_HOST = "host"; public static final String CONFIG_PROPERTY_SERIAL_PORT = "serialPort"; - // properties public static final String PROPERTY_OWNID = "ownId"; public static final String PROPERTY_ZIGBEEID = "zigbeeid"; diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/OpenWebNetHandlerFactory.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/OpenWebNetHandlerFactory.java index 8b258df58c..6a024db6af 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/OpenWebNetHandlerFactory.java +++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/OpenWebNetHandlerFactory.java @@ -21,6 +21,7 @@ import org.openhab.binding.openwebnet.internal.handler.OpenWebNetBridgeHandler; import org.openhab.binding.openwebnet.internal.handler.OpenWebNetEnergyHandler; import org.openhab.binding.openwebnet.internal.handler.OpenWebNetGenericHandler; import org.openhab.binding.openwebnet.internal.handler.OpenWebNetLightingHandler; +import org.openhab.binding.openwebnet.internal.handler.OpenWebNetScenarioHandler; import org.openhab.binding.openwebnet.internal.handler.OpenWebNetThermoregulationHandler; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.Thing; @@ -70,6 +71,9 @@ public class OpenWebNetHandlerFactory extends BaseThingHandlerFactory { } else if (OpenWebNetThermoregulationHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) { logger.debug("creating NEW THERMO Handler"); return new OpenWebNetThermoregulationHandler(thing); + } else if (OpenWebNetScenarioHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) { + logger.debug("creating NEW SCENARIO Handler"); + return new OpenWebNetScenarioHandler(thing); } logger.warn("ThingType {} is not supported by this binding", thing.getThingTypeUID()); return null; diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/actions/OpenWebNetCENActions.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/actions/OpenWebNetCENActions.java new file mode 100644 index 0000000000..ce1b5e1b5b --- /dev/null +++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/actions/OpenWebNetCENActions.java @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2010-2021 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.openwebnet.internal.actions; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.openwebnet.internal.handler.OpenWebNetScenarioHandler; +import org.openhab.core.automation.annotation.ActionInput; +import org.openhab.core.automation.annotation.ActionOutput; +import org.openhab.core.automation.annotation.RuleAction; +import org.openhab.core.thing.binding.ThingActions; +import org.openhab.core.thing.binding.ThingActionsScope; +import org.openhab.core.thing.binding.ThingHandler; +import org.openwebnet4j.communication.OWNException; +import org.openwebnet4j.communication.Response; +import org.openwebnet4j.message.CEN; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link OpenWebNetCENActions} defines CEN/CEN+ actions for the openwebnet binding. + * + * @author Massimo Valla - Initial contribution + */ + +@ThingActionsScope(name = "openwebnet") +@NonNullByDefault +public class OpenWebNetCENActions implements ThingActions { + + private final Logger logger = LoggerFactory.getLogger(OpenWebNetCENActions.class); + private @Nullable OpenWebNetScenarioHandler scenarioHandler; + + @Override + public void setThingHandler(@Nullable ThingHandler handler) { + this.scenarioHandler = (OpenWebNetScenarioHandler) handler; + } + + @Override + public @Nullable ThingHandler getThingHandler() { + return scenarioHandler; + } + + @RuleAction(label = "virtualPress", description = "Virtual press of the push button") + public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean virtualPress( + @ActionInput(name = "press", label = "press", description = "Type of press") @Nullable String press, + @ActionInput(name = "button", label = "button", description = "Button number") int button) { + OpenWebNetScenarioHandler handler = scenarioHandler; + if (handler == null) { + logger.warn("openwebnet OpenWebNetCENActions: scenarioHandler is null!"); + return false; + } + if (press == null) { + logger.warn("openwebnet OpenWebNetCENActions: press parameter is null!"); + return false; + } + CEN msg = null; + try { + msg = handler.pressStrToMessage(press, button); + Response res = handler.send(msg); + if (res != null) { + logger.debug("Sent virtualPress '{}' to gateway. Response: {}", msg, res.getResponseMessages()); + return res.isSuccess(); + } else { + logger.debug("virtual press action returned null response"); + } + } catch (IllegalArgumentException e) { + logger.warn("cannot execute virtual press action for thing {}: {}", handler.getThing().getUID(), + e.getMessage()); + } catch (OWNException e) { + logger.warn("exception while sending virtual press message '{}' to gateway: {}", msg, e.getMessage()); + } + return false; + } + + // legacy delegate methods + public static void virtualPress(@Nullable ThingActions actions, @Nullable String press, int button) { + if (actions instanceof OpenWebNetCENActions) { + ((OpenWebNetCENActions) actions).virtualPress(press, button); + } else { + throw new IllegalArgumentException("Instance is not an OpenWebNetCENActions class."); + } + } +} diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/discovery/OpenWebNetDeviceDiscoveryService.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/discovery/OpenWebNetDeviceDiscoveryService.java index 2a339cca5f..e92e684833 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/discovery/OpenWebNetDeviceDiscoveryService.java +++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/discovery/OpenWebNetDeviceDiscoveryService.java @@ -153,6 +153,18 @@ public class OpenWebNetDeviceDiscoveryService extends AbstractDiscoveryService deviceWho = Who.ENERGY_MANAGEMENT; break; } + case SCENARIO_CONTROL: { + thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_BUS_CEN_SCENARIO_CONTROL; + thingLabel = OpenWebNetBindingConstants.THING_LABEL_BUS_CEN_SCENARIO_CONTROL; + deviceWho = Who.CEN_SCENARIO_SCHEDULER; + break; + } + case MULTIFUNCTION_SCENARIO_CONTROL: { + thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_BUS_CENPLUS_SCENARIO_CONTROL; + thingLabel = OpenWebNetBindingConstants.THING_LABEL_BUS_CENPLUS_SCENARIO_CONTROL; + deviceWho = Who.CEN_PLUS_SCENARIO_SCHEDULER; + break; + } default: logger.warn("Device type {} is not supported, default to GENERIC device (WHERE={})", deviceType, where); if (where instanceof WhereZigBee) { diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetBridgeHandler.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetBridgeHandler.java index 2b9c83fd88..c2e21d82a3 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetBridgeHandler.java +++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetBridgeHandler.java @@ -48,6 +48,7 @@ import org.openwebnet4j.communication.OWNAuthException; import org.openwebnet4j.communication.OWNException; import org.openwebnet4j.message.Automation; import org.openwebnet4j.message.BaseOpenMessage; +import org.openwebnet4j.message.CEN; import org.openwebnet4j.message.EnergyManagement; import org.openwebnet4j.message.FrameException; import org.openwebnet4j.message.GatewayMgmt; @@ -308,7 +309,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement } // we support these types only if (baseMsg instanceof Lighting || baseMsg instanceof Automation || baseMsg instanceof EnergyManagement - || baseMsg instanceof Thermoregulation) { + || baseMsg instanceof Thermoregulation || baseMsg instanceof CEN) { BaseOpenMessage bmsg = baseMsg; if (baseMsg instanceof Lighting) { What what = baseMsg.getWhat(); @@ -419,7 +420,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement BaseOpenMessage baseMsg = (BaseOpenMessage) msg; // let's try to get the Thing associated with this message... if (baseMsg instanceof Lighting || baseMsg instanceof Automation || baseMsg instanceof EnergyManagement - || baseMsg instanceof Thermoregulation) { + || baseMsg instanceof Thermoregulation || baseMsg instanceof CEN) { String ownId = ownIdFromMessage(baseMsg); logger.debug("ownIdFromMessage({}) --> {}", baseMsg, ownId); OpenWebNetThingHandler deviceHandler = registeredDevices.get(ownId); diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetEnergyHandler.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetEnergyHandler.java index 386e45126d..8835ba2cd5 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetEnergyHandler.java +++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetEnergyHandler.java @@ -107,20 +107,23 @@ public class OpenWebNetEnergyHandler extends OpenWebNetThingHandler { "subscribeToActivePowerChanges() Refreshing subscription for the next {}min for WHERE={} to active power changes notification", ENERGY_SUBSCRIPTION_PERIOD, deviceWhere); } - - try { - bridgeHandler.gateway.send(EnergyManagement.setActivePowerNotificationsTime(deviceWhere.value(), - ENERGY_SUBSCRIPTION_PERIOD)); - isFirstSchedulerLaunch = false; - } catch (Exception e) { - if (isFirstSchedulerLaunch) { - logger.warn( - "subscribeToActivePowerChanges() For WHERE={} could not subscribe to active power changes notifications. Exception={}", - deviceWhere, e.getMessage()); - } else { - logger.warn( - "subscribeToActivePowerChanges() Unable to refresh subscription to active power changes notifications for WHERE={}. Exception={}", - deviceWhere, e.getMessage()); + Where w = deviceWhere; + if (w == null) { + logger.warn("subscribeToActivePowerChanges() WHERE=null. Skipping"); + } else { + try { + send(EnergyManagement.setActivePowerNotificationsTime(w.value(), ENERGY_SUBSCRIPTION_PERIOD)); + isFirstSchedulerLaunch = false; + } catch (Exception e) { + if (isFirstSchedulerLaunch) { + logger.warn( + "subscribeToActivePowerChanges() For WHERE={} could not subscribe to active power changes notifications. Exception={}", + w, e.getMessage()); + } else { + logger.warn( + "subscribeToActivePowerChanges() Unable to refresh subscription to active power changes notifications for WHERE={}. Exception={}", + w, e.getMessage()); + } } } }, 0, ENERGY_SUBSCRIPTION_PERIOD - 1, TimeUnit.MINUTES); @@ -129,9 +132,9 @@ public class OpenWebNetEnergyHandler extends OpenWebNetThingHandler { @Override public void dispose() { if (notificationSchedule != null) { + ScheduledFuture ns = notificationSchedule; + ns.cancel(false); logger.debug("dispose() scheduler stopped."); - - notificationSchedule.cancel(false); } super.dispose(); } diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetScenarioHandler.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetScenarioHandler.java new file mode 100644 index 0000000000..3ae1a35d01 --- /dev/null +++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetScenarioHandler.java @@ -0,0 +1,346 @@ +/** + * Copyright (c) 2010-2021 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.openwebnet.internal.handler; + +import static org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants.*; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Optional; +import java.util.Scanner; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants; +import org.openhab.binding.openwebnet.internal.actions.OpenWebNetCENActions; +import org.openhab.core.thing.Channel; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.Thing; +import org.openhab.core.thing.ThingTypeUID; +import org.openhab.core.thing.binding.ThingHandlerService; +import org.openhab.core.thing.binding.builder.ChannelBuilder; +import org.openhab.core.thing.binding.builder.ThingBuilder; +import org.openhab.core.thing.type.ChannelKind; +import org.openhab.core.thing.type.ChannelTypeUID; +import org.openhab.core.types.Command; +import org.openwebnet4j.message.BaseOpenMessage; +import org.openwebnet4j.message.CEN; +import org.openwebnet4j.message.CEN.Pressure; +import org.openwebnet4j.message.CENPlusScenario; +import org.openwebnet4j.message.CENPlusScenario.CENPlusPressure; +import org.openwebnet4j.message.CENScenario; +import org.openwebnet4j.message.CENScenario.CENPressure; +import org.openwebnet4j.message.FrameException; +import org.openwebnet4j.message.Where; +import org.openwebnet4j.message.WhereCEN; +import org.openwebnet4j.message.Who; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link OpenWebNetScenarioHandler} is responsible for handling commands/messages for CEN/CEN+ Scenarios. It + * extends the abstract {@link OpenWebNetThingHandler}. + * + * @author Massimo Valla - Initial contribution + */ +@NonNullByDefault +public class OpenWebNetScenarioHandler extends OpenWebNetThingHandler { + + private final Logger logger = LoggerFactory.getLogger(OpenWebNetScenarioHandler.class); + + private interface PressEvent { + @Override + public String toString(); + } + + private enum CENPressEvent implements PressEvent { + CEN_EVENT_START_PRESS("START_PRESS"), + CEN_EVENT_SHORT_PRESS("SHORT_PRESS"), + CEN_EVENT_EXTENDED_PRESS("EXTENDED_PRESS"), + CEN_EVENT_RELEASE_EXTENDED_PRESS("RELEASE_EXTENDED_PRESS"); + + private final String press; + + CENPressEvent(final String pr) { + this.press = pr; + } + + public static @Nullable CENPressEvent fromValue(String s) { + Optional event = Arrays.stream(values()).filter(val -> s.equals(val.press)).findFirst(); + return event.orElse(null); + } + + @Override + public String toString() { + return press; + } + } + + private enum CENPlusPressEvent implements PressEvent { + CENPLUS_EVENT_SHORT_PRESS("SHORT_PRESS"), + CENPLUS_EVENT_START_EXTENDED_PRESS("START_EXTENDED_PRESS"), + CENPLUS_EVENT_EXTENDED_PRESS("EXTENDED_PRESS"), + CENPLUS_EVENT_RELEASE_EXTENDED_PRESS("RELEASE_EXTENDED_PRESS"); + + private final String press; + + CENPlusPressEvent(final String pr) { + this.press = pr; + } + + public static @Nullable CENPlusPressEvent fromValue(String s) { + Optional event = Arrays.stream(values()).filter(val -> s.equals(val.press)).findFirst(); + return event.orElse(null); + } + + @Override + public String toString() { + return press; + } + } + + private boolean isCENPlus = false; + + public static final Set SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.SCENARIO_SUPPORTED_THING_TYPES; + + public OpenWebNetScenarioHandler(Thing thing) { + super(thing); + if (OpenWebNetBindingConstants.THING_TYPE_BUS_CENPLUS_SCENARIO_CONTROL.equals(thing.getThingTypeUID())) { + isCENPlus = true; + logger.debug("created CEN+ device for thing: {}", getThing().getUID()); + } else { + logger.debug("created CEN device for thing: {}", getThing().getUID()); + } + } + + @Override + public void initialize() { + super.initialize(); + Object buttonsConfig = getConfig().get(CONFIG_PROPERTY_SCENARIO_BUTTONS); + if (buttonsConfig != null) { + Set buttons = csvStringToSetInt((String) buttonsConfig); + if (!buttons.isEmpty()) { + ThingBuilder thingBuilder = editThing(); + Channel ch; + for (Integer i : buttons) { + ch = thing.getChannel(CHANNEL_SCENARIO_BUTTON + i); + if (ch == null) { + thingBuilder.withChannel(buttonToChannel(i)); + logger.debug("added channel {} to thing: {}", i, getThing().getUID()); + } + } + updateThing(thingBuilder.build()); + } else { + logger.warn("invalid config parameter buttons='{}' for thing {}", buttonsConfig, thing.getUID()); + } + } + } + + @Override + public Collection> getServices() { + return Collections.singleton(OpenWebNetCENActions.class); + } + + @Override + protected String ownIdPrefix() { + if (isCENPlus) { + return Who.CEN_PLUS_SCENARIO_SCHEDULER.value().toString(); + } else { + return Who.CEN_SCENARIO_SCHEDULER.value().toString(); + } + } + + @Override + protected void handleMessage(BaseOpenMessage msg) { + super.handleMessage(msg); + if (msg.isCommand()) { + triggerChannel((CEN) msg); + } else { + logger.debug("handleMessage() Ignoring unsupported DIM for thing {}. Frame={}", getThing().getUID(), msg); + } + } + + private void triggerChannel(CEN cenMsg) { + Integer buttonNumber; + try { + buttonNumber = cenMsg.getButtonNumber(); + } catch (FrameException e) { + logger.warn("cannot read CEN/CEN+ button. Ignoring message {}", cenMsg); + return; + } + if (buttonNumber == null || buttonNumber < 0 || buttonNumber > 31) { + logger.warn("invalid CEN/CEN+ button number: {}. Ignoring message {}", buttonNumber, cenMsg); + return; + } + Channel ch = thing.getChannel(CHANNEL_SCENARIO_BUTTON + buttonNumber); + if (ch == null) { // we have found a new button for this device, let's add a new channel for the button + ThingBuilder thingBuilder = editThing(); + ch = buttonToChannel(buttonNumber); + thingBuilder.withChannel(ch); + updateThing(thingBuilder.build()); + logger.info("added new channel {} to thing {}", ch.getUID(), getThing().getUID()); + } + final Channel channel = ch; + PressEvent pressEv = null; + Pressure press = null; + try { + press = cenMsg.getButtonPressure(); + } catch (FrameException e) { + logger.warn("invalid CEN/CEN+ Press. Ignoring message {}", cenMsg); + return; + } + if (press == null) { + logger.warn("invalid CEN/CEN+ Press. Ignoring message {}", cenMsg); + return; + } + + if (cenMsg instanceof CENScenario) { + switch ((CENPressure) press) { + case START_PRESSURE: + pressEv = CENPressEvent.CEN_EVENT_START_PRESS; + break; + case RELEASE_SHORT_PRESSURE: + pressEv = CENPressEvent.CEN_EVENT_SHORT_PRESS; + break; + case EXTENDED_PRESSURE: + pressEv = CENPressEvent.CEN_EVENT_EXTENDED_PRESS; + break; + case RELEASE_EXTENDED_PRESSURE: + pressEv = CENPressEvent.CEN_EVENT_RELEASE_EXTENDED_PRESS; + break; + default: + logger.warn("unsupported CENPress. Ignoring message {}", cenMsg); + return; + } + } else { + switch ((CENPlusPressure) press) { + case SHORT_PRESSURE: + pressEv = CENPlusPressEvent.CENPLUS_EVENT_SHORT_PRESS; + break; + case START_EXTENDED_PRESSURE: + pressEv = CENPlusPressEvent.CENPLUS_EVENT_START_EXTENDED_PRESS; + break; + case EXTENDED_PRESSURE: + pressEv = CENPlusPressEvent.CENPLUS_EVENT_EXTENDED_PRESS; + break; + case RELEASE_EXTENDED_PRESSURE: + pressEv = CENPlusPressEvent.CENPLUS_EVENT_RELEASE_EXTENDED_PRESS; + break; + default: + logger.warn("unsupported CENPlusPress. Ignoring message {}", cenMsg); + return; + } + } + + triggerChannel(channel.getUID(), pressEv.toString()); + } + + private Channel buttonToChannel(int buttonNumber) { + ChannelTypeUID channelTypeUID; + if (isCENPlus) { + channelTypeUID = new ChannelTypeUID(BINDING_ID, CHANNEL_TYPE_CEN_PLUS_BUTTON_EVENT); + } else { + channelTypeUID = new ChannelTypeUID(BINDING_ID, CHANNEL_TYPE_CEN_BUTTON_EVENT); + } + return ChannelBuilder + .create(new ChannelUID(getThing().getUID(), CHANNEL_SCENARIO_BUTTON + buttonNumber), "String") + .withType(channelTypeUID).withKind(ChannelKind.TRIGGER).withLabel("Button " + buttonNumber).build(); + } + + /** + * Construct a CEN/CEN+ virtual press message for this device given a pressString and button number + * + * @param pressString one START_PRESS, SHORT_PRESS etc. + * @param button number [0-31] + * @return CEN message + * @throws IllegalArgumentException if button number or pressString are invalid + */ + public CEN pressStrToMessage(String pressString, int button) throws IllegalArgumentException { + Where w = deviceWhere; + if (w == null) { + throw new IllegalArgumentException("pressStrToMessage: deviceWhere is null"); + } + if (isCENPlus) { + CENPlusPressEvent prEvent = CENPlusPressEvent.fromValue(pressString); + if (prEvent != null) { + switch (prEvent) { + case CENPLUS_EVENT_SHORT_PRESS: + return CENPlusScenario.virtualShortPressure(w.value(), button); + case CENPLUS_EVENT_START_EXTENDED_PRESS: + return CENPlusScenario.virtualStartExtendedPressure(w.value(), button); + case CENPLUS_EVENT_EXTENDED_PRESS: + return CENPlusScenario.virtualExtendedPressure(w.value(), button); + case CENPLUS_EVENT_RELEASE_EXTENDED_PRESS: + return CENPlusScenario.virtualReleaseExtendedPressure(w.value(), button); + default: + throw new IllegalArgumentException("unsupported press type: " + pressString); + } + } else { + throw new IllegalArgumentException("unsupported press type: " + pressString); + } + } else { + CENPressEvent prEvent = CENPressEvent.fromValue(pressString); + if (prEvent != null) { + switch (prEvent) { + case CEN_EVENT_START_PRESS: + return CENScenario.virtualStartPressure(w.value(), button); + case CEN_EVENT_SHORT_PRESS: + return CENScenario.virtualReleaseShortPressure(w.value(), button); + case CEN_EVENT_EXTENDED_PRESS: + return CENScenario.virtualExtendedPressure(w.value(), button); + case CEN_EVENT_RELEASE_EXTENDED_PRESS: + return CENScenario.virtualReleaseExtendedPressure(w.value(), button); + default: + throw new IllegalArgumentException("unsupported press type: " + pressString); + } + } else { + throw new IllegalArgumentException("unsupported press type: " + pressString); + } + } + } + + private static Set csvStringToSetInt(String s) { + TreeSet intSet = new TreeSet(); + String sNorm = s.replaceAll("\\s", ""); + Scanner sc = new Scanner(sNorm); + sc.useDelimiter(","); + while (sc.hasNextInt()) { + intSet.add(sc.nextInt()); + } + sc.close(); + return intSet; + } + + @Override + protected void handleChannelCommand(ChannelUID channel, Command command) { + logger.warn("CEN/CEN+ channels are trigger channels and do not handle commands"); + } + + @Override + protected void refreshDevice(boolean refreshAll) { + logger.debug("CEN/CEN+ channels are trigger channels and do not have state"); + } + + @Override + protected Where buildBusWhere(String wStr) throws IllegalArgumentException { + return new WhereCEN(wStr); + } + + @Override + protected void requestChannelState(ChannelUID channel) { + logger.debug("CEN/CEN+ channels are trigger channels and do not have state"); + } +} diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThingHandler.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThingHandler.java index 7e0ac4bfe3..27be24da9b 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThingHandler.java +++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThingHandler.java @@ -165,7 +165,7 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler { /** * Helper method to send OWN messages from ThingHandlers */ - protected @Nullable Response send(OpenMessage msg) throws OWNException { + public @Nullable Response send(OpenMessage msg) throws OWNException { OpenWebNetBridgeHandler bh = bridgeHandler; if (bh != null) { OpenGateway gw = bh.gateway; diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusAutomation.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusAutomation.xml index 4ba3d5392f..e91aae1478 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusAutomation.xml +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusAutomation.xml @@ -38,7 +38,7 @@ - + Example: A/PL address: A=1 PL=3 --> where=13. On local bus: where=13#4#01 diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusCENPlusScenarioControl.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusCENPlusScenarioControl.xml new file mode 100644 index 0000000000..dbb589b143 --- /dev/null +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusCENPlusScenarioControl.xml @@ -0,0 +1,39 @@ + + + + + + + + + + A OpenWebNet BUS/SCS CEN+ Scenario Control device. BTicino models: HC/HD/HS/L/N/NT4680 + + + + + BTicino/Legrand + BTI-HC/HD/HS/L/N/NT4680 + 273 + + + ownId + + + + + List (comma separated) of buttons numbers [0-31] configured for this scenario device, example: + buttons=1,2,4 + + + + + Use 2+N[0-2047]. Example: scenario control 5 --> WHERE=25 + + + + + diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusCENScenarioControl.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusCENScenarioControl.xml new file mode 100644 index 0000000000..5f5700d1ff --- /dev/null +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusCENScenarioControl.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + A OpenWebNet BUS/SCS CEN Scenario Control device. BTicino models: HC/HD/HS/L/N/NT4680 + + + + + BTicino/Legrand + BTI-HC/HD/HS/L/N/NT4680 + 2 + + + ownId + + + + + List (comma separated) of buttons numbers [0-31] configured for this scenario device. Example: + buttons=1,2,4 + + + + Example: A/PL address: A=1 PL=3 --> WHERE=13. On local bus: WHERE=13#4#01 + + + + + + diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusDimmer.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusDimmer.xml index 58f5013e98..5288e9b5a8 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusDimmer.xml +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusDimmer.xml @@ -27,7 +27,7 @@ - + Example: A/PL address: A=1 PL=3 --> where=13. On local bus: where=13#4#01 diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusEnergyMeter.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusEnergyMeter.xml index 2fcd93bd88..e9990a2e85 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusEnergyMeter.xml +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusEnergyMeter.xml @@ -27,7 +27,7 @@ - + Example: 5N with N=[1-255] diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusOnOffSwitch.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusOnOffSwitch.xml index 805cc0dc6b..f8e7398b9a 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusOnOffSwitch.xml +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusOnOffSwitch.xml @@ -27,7 +27,7 @@ - + Example: A/PL address: A=1 PL=3 --> where=13. On local bus: where=13#4#01 diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusThermoSensor.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusThermoSensor.xml index aec78eb816..4f878a1fc1 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusThermoSensor.xml +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusThermoSensor.xml @@ -27,7 +27,7 @@ - + Example: sensor 3 of zone 2 --> where=302. Sensor 5 of external zone 00 --> where=500 diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusThermoZone.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusThermoZone.xml index 0bb8c8b01f..85032f7521 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusThermoZone.xml +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/BusThermoZone.xml @@ -36,7 +36,7 @@ - + Example: zone 2 --> where=2. diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBAutomation.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBAutomation.xml index 87a60e4374..340541a9a8 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBAutomation.xml +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBAutomation.xml @@ -37,7 +37,7 @@ AUTO - + It identifies one ZigBee device. Example: 765432101#9 diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBDimmer.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBDimmer.xml index 98b07e81a5..f27f8b8574 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBDimmer.xml +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBDimmer.xml @@ -27,7 +27,7 @@ - + It identifies one ZigBee device. Example: 765432101#9 diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBOnOffSwitch.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBOnOffSwitch.xml index f741b72403..6e0f3e1714 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBOnOffSwitch.xml +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBOnOffSwitch.xml @@ -27,7 +27,7 @@ - + It identifies one ZigBee device. Example: 765432101#9 diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBOnOffSwitch2Units.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBOnOffSwitch2Units.xml index 6de61f7f7f..8f1fd58588 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBOnOffSwitch2Units.xml +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/ZBOnOffSwitch2Units.xml @@ -28,7 +28,7 @@ - + It identifies one ZigBee device. Example: 765432100#9 (use unit=00 at the end) diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/channels.xml b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/channels.xml index 97ca3eedc6..ddba826d73 100644 --- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/channels.xml +++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/thing/channels.xml @@ -178,4 +178,31 @@ Energy + + + + trigger + + + + + + + + + + + + + trigger + + + + + + + + + +