]> git.basschouten.com Git - openhab-addons.git/commitdiff
[openwebnet] add sendMessage rule actions to send generic OWN messages on the BUS...
authorM Valla <12682715+mvalla@users.noreply.github.com>
Sun, 28 Apr 2024 09:55:28 +0000 (11:55 +0200)
committerGitHub <noreply@github.com>
Sun, 28 Apr 2024 09:55:28 +0000 (11:55 +0200)
* [openwebnet] Added OpenWebNetBridgeActions class and sendMessage action

Signed-off-by: Massimo Valla <mvcode00@gmail.com>
bundles/org.openhab.binding.openwebnet/README.md
bundles/org.openhab.binding.openwebnet/pom.xml
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/actions/OpenWebNetBridgeActions.java [new file with mode: 0644]
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/actions/OpenWebNetCENActions.java
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetBridgeHandler.java
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThermoregulationHandler.java
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/serial/SerialPortAdapter.java
bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/i18n/openwebnet.properties

index d5d73a8d6991cff326f0e45aa9894ec9156e06f7..36beca291093d396ee6ea5f889a14c6fa8b8ebf2 100644 (file)
@@ -57,9 +57,9 @@ The following Things and OpenWebNet `WHOs` are supported:
 
 | Category             | WHO    | Thing Type IDs                                        | Description                                                           | Status                               |
 | -------------------- | :----: | :---------------------------------------------------: | :-------------------------------------------------------------------: | ------------------------------------ |
-| Gateway Management   | `13`   | `zb_gateway`                                          | MyHOME Radio - Zigbee USB Gateway (models: BTI-3578 / LG 088328)                     | Tested: BTI-3578 and LG 088328       |
-| Lighting             | `1`    | `zb_dimmer`, `zb_on_off_switch`, `zb_on_off_switch2u` | Radio Zigbee dimmers, switches and 2-unit switches                          | Tested: BTI-4591, BTI-3584, BTI-4585 |
-| Automation           | `2`    | `zb_automation`                                       | Radio Zigbee roller shutters                                                |                                      |
+| Gateway Management   | `13`   | `zb_gateway`                                          | MyHOME Radio - Zigbee USB Gateway (models: BTI-3578 / LG 088328)      | Tested: BTI-3578 and LG 088328       |
+| Lighting             | `1`    | `zb_dimmer`, `zb_on_off_switch`, `zb_on_off_switch2u` | Radio Zigbee dimmers, switches and 2-unit switches                    | Tested: BTI-4591, BTI-3584, BTI-4585 |
+| Automation           | `2`    | `zb_automation`                                       | Radio Zigbee roller shutters                                          |                                      |
 
 ## Discovery
 
@@ -214,29 +214,29 @@ OPEN command to execute: *5*8#134##
 
 ### Lighting, Automation, Basic/CEN/CEN+ Scenario Events, Dry Contact / IR Interfaces, Power and AUX 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     |
-| `scenario`                              | `bus_scenario_control`                                        | String        | Trigger channel for Basic scenario events [see possible values](#scenario-channels)                                                                                    | R (TRIGGER) |
-| `button#X`                              | `bus_cen_scenario_control`, `bus_cenplus_scenario_control`    | String        | Trigger channel for CEN/CEN+ scenario events [see possible values](#scenario-channels)                                                                                 | R (TRIGGER) |
-| `sensor`                                | `bus_dry_contact_ir`                                          | Switch        | Indicates if a Dry Contact Interface is `ON`/`OFF`, or if an IR Sensor is detecting movement (`ON`), or not  (`OFF`)                                                   |      R      |
-| `power`                                 | `bus_energy_meter`                                            | Number:Power  | The current active power usage from Energy Meter                                                                                                                       |      R      |
-| `energyToday`                           | `bus_energy_meter`                                            | Number:Energy | Current day energy                                                                                                                                           |      R      |
-| `energyThisMonth`                       | `bus_energy_meter`                                            | Number:Energy | Current month energy                                                                                                                                         |      R      |
+| 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     |
+| `scenario`                              | `bus_scenario_control`                                        | String        | Trigger channel for Basic scenario events [see possible values](#scenario-channels)                           | R (TRIGGER) |
+| `button#X`                              | `bus_cen_scenario_control`, `bus_cenplus_scenario_control`    | String        | Trigger channel for CEN/CEN+ scenario events [see possible values](#scenario-channels)                        | R (TRIGGER) |
+| `sensor`                                | `bus_dry_contact_ir`                                          | Switch        | If a Dry Contact Interface is `ON`/`OFF`, or if an IR Sensor is detecting movement (`ON`), or not  (`OFF`)    |      R      |
+| `power`                                 | `bus_energy_meter`                                            | Number:Power  | The current active power usage from Energy Meter                                                              |      R      |
+| `energyToday`                           | `bus_energy_meter`                                            | Number:Energy | Current day energy                                                                                            |      R      |
+| `energyThisMonth`                       | `bus_energy_meter`                                            | Number:Energy | Current month energy                                                                                          |      R      |
 | `aux`                                   | `bus_aux`                                                     | String        | Possible commands: `ON`, `OFF`, `TOGGLE`, `STOP`, `UP`, `DOWN`, `ENABLED`, `DISABLED`, `RESET_GEN`, `RESET_BI`, `RESET_TRI`. Only `ON` and `OFF` are supported for now |     R/W     |
 
 ### Alarm channels
 
-| Channel Type ID (channel ID) | Applies to Thing Type IDs              | Item Type   | Description                                                           | Read/Write  |
-|------------------------------|----------------------------------------|-------------|-----------------------------------------------------------------------|:-----------:|
-| `state`                      | `bus_alarm_system`, `bus_alarm_zone`   | Switch      | Alarm system or zone is active (`ON`) or inactive (`OFF`)             |      R      |
-| `network`                    | `bus_alarm_system`                     | Switch      | Alarm system network state (`ON` = network ok, `OFF` = no network)    |      R      |
-| `battery`                    | `bus_alarm_system`                     | String      | Alarm system battery state (`OK`, `FAULT`, `UNLOADED`)                |      R      |
-| `armed`                      | `bus_alarm_system`                     | Switch      | Alarm system is armed (`ON`) or disarmed (`OFF`)                      |      R      |
+| Channel Type ID (channel ID) | Applies to Thing Type IDs              | Item Type   | Description                                                                    | Read/Write  |
+|------------------------------|----------------------------------------|-------------|--------------------------------------------------------------------------------|:-----------:|
+| `state`                      | `bus_alarm_system`, `bus_alarm_zone`   | Switch      | Alarm system or zone is active (`ON`) or inactive (`OFF`)                      |      R      |
+| `network`                    | `bus_alarm_system`                     | Switch      | Alarm system network state (`ON` = network ok, `OFF` = no network)             |      R      |
+| `battery`                    | `bus_alarm_system`                     | String      | Alarm system battery state (`OK`, `FAULT`, `UNLOADED`)                         |      R      |
+| `armed`                      | `bus_alarm_system`                     | Switch      | Alarm system is armed (`ON`) or disarmed (`OFF`)                               |      R      |
 | `alarm`                      | `bus_alarm_zone`                       | String      | Current alarm for the zone  (`SILENT`, `INTRUSION`, `TAMPERING`, `ANTI_PANIC`) |      R      |
-| `timestamp`                  | `bus_alarm_zone`                       | DateTime  | Current date and time of the zone's alarm event (YY/MM/DD hh:mm:ss)   |      R      |
+| `timestamp`                  | `bus_alarm_zone`                       | DateTime  | Current date and time of the zone's alarm event (YY/MM/DD hh:mm:ss)              |      R      |
 
 ### Thermo channels
 
@@ -244,27 +244,27 @@ OPEN command to execute: *5*8#134##
 
 | Channel Type ID (channel ID) | Applies to Thing Type IDs              | Item Type          | Description                                                                                                                           | Read/Write | Advanced |
 | ---------------------------- | -------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | :--------: | :------: |
-| `temperature`                | `bus_thermo_zone`, `bus_thermo_sensor` | Number:Temperature | Currently sensed temperature for zone or sensor                                                                                                 | R          | N        |
-| `setpointTemperature`        | `bus_thermo_zone`, `bus_thermo_cu`     | Number:Temperature | The zone or Central Unit manual setpoint temperature                                                                                         | R/W        | N        |
-| `targetTemperature`          | `bus_thermo_zone`                      | Number:Temperature | The current zone target temperature according to `mode`, `setpointTemperature` and `localOffset` | R        | Y        
-|`function`                   | `bus_thermo_zone`, `bus_thermo_cu`     | String             | The zone set thermo function (`COOLING`, `HEATING`, `GENERIC`) or the Central Unit thermo function (`COOLING`, `HEATING`)             | R/W        | N        |
+| `temperature`                | `bus_thermo_zone`, `bus_thermo_sensor` | Number:Temperature | Currently sensed temperature for zone or sensor                                                                                       | R          | N        |
+| `setpointTemperature`        | `bus_thermo_zone`, `bus_thermo_cu`     | Number:Temperature | The zone or Central Unit manual setpoint temperature                                                                                  | R/W        | N        |
+| `targetTemperature`          | `bus_thermo_zone`                      | Number:Temperature | The current zone target temperature according to `mode`, `setpointTemperature` and `localOffset`                                      | R          | Y        
+|`function`                    | `bus_thermo_zone`, `bus_thermo_cu`     | String             | The zone set thermo function (`COOLING`, `HEATING`, `GENERIC`) or the Central Unit thermo function (`COOLING`, `HEATING`)             | R/W        | N        |
 | `mode`                       | `bus_thermo_zone`, `bus_thermo_cu`     | String             | The zone set mode (`AUTO`, `MANUAL`, `OFF`, `PROTECTION`) or the Central Unit set mode (`WEEKLY`, `MANUAL`, `SCENARIO`, `HOLIDAY`, `VACATION`, `OFF`, `PROTECTION`) | R/W        | N        |
 | `speedFanCoil`               | `bus_thermo_zone`                      | String             | The zone fancoil speed: `AUTO`, `SPEED_1`, `SPEED_2`, `SPEED_3`                                                                       | R/W        | N        |
 | `actuators`                  | `bus_thermo_zone`                      | String             | The zone actuator(s) status: `OFF`, `ON`, `OPENED`, `CLOSED` , `STOP`, `OFF_FAN_COIL`, `ON_SPEED_1`, `ON_SPEED_2`, `ON_SPEED_3`, `OFF_SPEED_1`, `OFF_SPEED_2`, `OFF_SPEED_3`            | R          | Y        |
 | `heatingValves`              | `bus_thermo_zone`                      | String             | The zone heating valve(s) status: `OFF`, `ON`, `OPENED`, `CLOSED` , `STOP`, `OFF_FAN_COIL`, `ON_SPEED_1`, `ON_SPEED_2`, `ON_SPEED_3`, `OFF_SPEED_1`, `OFF_SPEED_2`, `OFF_SPEED_3`            | R          | Y        |
 | `conditioningValves`         | `bus_thermo_zone`                      | String             | The zone conditioning valve(s) status: `OFF`, `ON`, `OPENED`, `CLOSED` , `STOP`, `OFF_FAN_COIL`, `ON_SPEED_1`, `ON_SPEED_2`, `ON_SPEED_3`, `OFF_SPEED_1`, `OFF_SPEED_2`, `OFF_SPEED_3`            | R          | Y        |
-| `heating`         | `bus_thermo_zone`                      | Switch             | `ON` if the zone heating valve is currently active (meaning heating is On)             | R          | Y        |
-| `cooling`         | `bus_thermo_zone`                      | Switch             | `ON` if the zone conditioning valve is currently active (meaning conditioning is On)             | R          | Y        |
+| `heating`                    | `bus_thermo_zone`                      | Switch             | `ON` if the zone heating valve is currently active (meaning heating is On)                                                            | R          | Y        |
+| `cooling`        | `bus_thermo_zone`                      | Switch             | `ON` if the zone conditioning valve is currently active (meaning conditioning is On)                                                              | R          | Y        |
 | `localOffset`                | `bus_thermo_zone`                      | String             | The zone local offset status: `OFF`, `PROTECTION`, `MINUS_3`, `MINUS_2` , `MINUS_1`, `NORMAL`, `PLUS_1`, `PLUS_2`, `PLUS_3`, as set on the room thermostat physical knob          | R          | Y        |
 | `remoteControl`              | `bus_thermo_cu`                        | String             | The Central Unit Remote Control status: `ENABLED`, `DISABLED`                                                                         | R          | Y        |
 | `batteryStatus`              | `bus_thermo_cu`                        | String             | The Central Unit Battery status: `OK`, `KO`                                                                                           | R          | Y        |
-| `weeklyProgram`              | `bus_thermo_cu`                        | Number             | The weekly program number (`1`, `2`, `3`) when Central Unit mode is `WEEKLY`                                                                 | R/W        | N        |
-| `scenarioProgram`            | `bus_thermo_cu`                        | Number             | The scenario program number (`1`, `2`, ... ,  `16`) when Central Unit mode is `SCENARIO`                                                       | R/W        | N        |
-| `vacationDays`               | `bus_thermo_cu`                        | Number             | Number of days `1-255` the Central Unit will be set to Anti-freeze / Heat Protection temperature before returning to mode `WEEKLY`  | R/W        | N        |
-| `failureDiscovered`          | `bus_thermo_cu`                        | Switch             | Indicates if a Failure was discovered by the Central Unit (`ON`), or not (`OFF`)                                                                | R          | Y        |
-| `atLeastOneProbeOff`         | `bus_thermo_cu`                        | Switch             | Indicates if at least one probe is in OFF mode (`ON`) or not (`OFF`) | R          | Y        |
-| `atLeastOneProbeProtection`  | `bus_thermo_cu`                        | Switch             | Indicates if at least one probe is in PROTECTION mode (`ON`) or not (`OFF`)                                                                    | R          | Y        |
-| `atLeastOneProbeManual`      | `bus_thermo_cu`                        | Switch             | Indicates if at least one probe is in MANUAL mode (`ON`) or not (`OFF`)                                                                        | R          | Y        |
+| `weeklyProgram`              | `bus_thermo_cu`                        | Number             | The weekly program number (`1`, `2`, `3`) when Central Unit mode is `WEEKLY`                                                          | R/W        | N        |
+| `scenarioProgram`            | `bus_thermo_cu`                        | Number             | The scenario program number (`1`, `2`, ... ,  `16`) when Central Unit mode is `SCENARIO`                                              | R/W        | N        |
+| `vacationDays`               | `bus_thermo_cu`                        | Number             | Number of days `1-255` the Central Unit will be set to Anti-freeze / Heat Protection temperature before returning to mode `WEEKLY`    | R/W        | N        |
+| `failureDiscovered`          | `bus_thermo_cu`                        | Switch             | Indicates if a Failure was discovered by the Central Unit (`ON`), or not (`OFF`)                                                      | R          | Y        |
+| `atLeastOneProbeOff`         | `bus_thermo_cu`                        | Switch             | Indicates if at least one probe is in OFF mode (`ON`) or not (`OFF`)                                                                  | R          | Y        |
+| `atLeastOneProbeProtection`  | `bus_thermo_cu`                        | Switch             | Indicates if at least one probe is in PROTECTION mode (`ON`) or not (`OFF`)                                                           | R          | Y        |
+| `atLeastOneProbeManual`      | `bus_thermo_cu`                        | Switch             | Indicates if at least one probe is in MANUAL mode (`ON`) or not (`OFF`)                                                               | R          | Y        |
 
 ### Notes on channels
 
@@ -323,6 +323,50 @@ In order to activate one specific weekly or scenario program two different chann
 
 Example: to activate SCENARIO number 9 on the thermo Central Unit then set channel `mode` = `SCENARIO` and channel `scenarioProgram` = `9`.
 
+## Rule Actions
+
+The following Rule actions can be used to send arbitrary OpenWebNet messages on the MyHOME BUS. 
+Actions can be used for example to send commands to the BUS for a WHOs not yet supported by the binding.
+
+- `Boolean sendMessage(String message)` returns a `Boolean` = `true` if the `message` (OpenWebNet frame) was successfully sent via the gateway, `false` otherwise.
+- `Map<String, Object> sendMessageWithResponse(String message)` same as previous one, but returns a `Map<String, Object>` with following keys:
+    - `success`: a `Boolean` = `true` if the `message` was sent successfully
+    - `responseMessages`: a `List<String>` object containing all returned frames as response to command sent
+
+Usage example:
+
+:::: tabs
+
+::: tab DSL
+
+```java
+val actions = getActions("openwebnet", "openwebnet:bus_gateway:mybridge")
+var success = actions.sendMessage("*22*22#4#9*2#1##")
+logInfo("EventLog", "Success: " + success)
+
+var result = actions.sendMessageWithResponse("*22*22#4#9*2#1##")
+logInfo("EventLog", "Success: " + result.get("success"))
+logInfo("EventLog", "Response: " + result.get("responseMessages"))
+```
+
+:::
+
+::: tab JavaScript
+
+```javascript
+var actions = getActions("openwebnet", "openwebnet:bus_gateway:mybridge");
+var success = actions.sendMessage("*22*22#4#9*2#1##");
+logInfo("EventLog", "Success: " + success);
+
+var result = actions.sendMessageWithResponse("*22*22#4#9*2#1##");
+logInfo("EventLog", "Success: " + result.success);
+logInfo("EventLog", "Response: " + result.responseMessages);
+```
+
+:::
+
+::::
+
 ## Full Example
 
 ### openwebnet.things:
@@ -450,29 +494,29 @@ sitemap openwebnet label="OpenWebNet Binding Example Sitemap"
 
     Frame label="Energy Meters" icon="energy"
     {
-          Default item=iCENTRAL_Ta      label="General"                        icon="energy" valuecolor=[>3000="red"]
-          Default item=iCENTRAL_Tb      label="Ground Floor"                   icon="energy" valuecolor=[>3000="red"]
-          Default item=CENTRAL_Ta_day   label="General Energy Today"           icon="energy" valuecolor=[>3000="blue"]
-          Default item=CENTRAL_Tb_day   label="Ground Floor Energy Today"      icon="energy" valuecolor=[>3000="blue"]
-          Default item=CENTRAL_Ta_month label="General Energy This Month"      icon="energy" valuecolor=[>3000="yellow"]
-          Default item=CENTRAL_Tb_month label="Ground Floor Energy This Month" icon="energy" valuecolor=[>3000="yellow"]
+          Default item=iCENTRAL_Ta              label="General"                        icon="energy" valuecolor=[>3000="red"]
+          Default item=iCENTRAL_Tb              label="Ground Floor"                   icon="energy" valuecolor=[>3000="red"]
+          Default item=CENTRAL_Ta_day           label="General Energy Today"           icon="energy" valuecolor=[>3000="blue"]
+          Default item=CENTRAL_Tb_day           label="Ground Floor Energy Today"      icon="energy" valuecolor=[>3000="blue"]
+          Default item=CENTRAL_Ta_month         label="General Energy This Month"      icon="energy" valuecolor=[>3000="yellow"]
+          Default item=CENTRAL_Tb_month         label="Ground Floor Energy This Month" icon="energy" valuecolor=[>3000="yellow"]
     }
 
     Frame label="Living Room Thermo"
     {
-          Default   item=iLR_zone_temp      label="Temperature" icon="fire" valuecolor=[<20="red"] 
-          Setpoint  item=iLR_zone_setTemp   label="Setpoint [%.1f °C]" step=0.5 minValue=15 maxValue=30
-          Selection item=iLR_zone_fanSpeed  label="Fan Speed" icon="fan" mappings=[AUTO="AUTO", SPEED_1="Low", SPEED_2="Medium", SPEED_3="High"]
-          Switch    item=iLR_zone_mode      label="Mode" icon="settings"
-          Selection item=iLR_zone_func      label="Function" icon="heating" mappings=[HEATING="Heating", COOLING="Cooling", GENERIC="Heating/Cooling"]
-          Default   item=iLR_zone_actuators label="Actuators status"
-          Default   item=iLR_zone_hv        label="Heating valves status"
-          Default   item=iLR_zone_cv        label="Conditioning valves status"
+          Default   item=iLR_zone_temp          label="Temperature" icon="fire" valuecolor=[<20="red"] 
+          Setpoint  item=iLR_zone_setTemp       label="Setpoint [%.1f °C]" step=0.5 minValue=15 maxValue=30
+          Selection item=iLR_zone_fanSpeed      label="Fan Speed" icon="fan" mappings=[AUTO="AUTO", SPEED_1="Low", SPEED_2="Medium", SPEED_3="High"]
+          Switch    item=iLR_zone_mode          label="Mode" icon="settings"
+          Selection item=iLR_zone_func          label="Function" icon="heating" mappings=[HEATING="Heating", COOLING="Cooling", GENERIC="Heating/Cooling"]
+          Default   item=iLR_zone_actuators     label="Actuators status"
+          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"]
+          Switch    item=iCENPlusProxyItem      label="My CEN+ scenario" icon="movecontrol"  mappings=[ON="Activate"]
     }
     
     Frame label="Alarm"
index 2d867df83c0973c962bfcbe6839a05c8c177bfa3..bca1dc0e3626d40e1768c0c373a35e4611e9a927 100644 (file)
@@ -19,7 +19,7 @@
     <dependency>
       <groupId>io.github.openwebnet4j</groupId>
       <artifactId>openwebnet4j</artifactId>
-      <version>0.13.0</version>
+      <version>0.14.0</version>
       <scope>compile</scope>
     </dependency>
 
diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/actions/OpenWebNetBridgeActions.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/actions/OpenWebNetBridgeActions.java
new file mode 100644 (file)
index 0000000..eb88aae
--- /dev/null
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.openwebnet.internal.actions;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.openwebnet.internal.handler.OpenWebNetBridgeHandler;
+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.OpenGateway;
+import org.openwebnet4j.communication.OWNException;
+import org.openwebnet4j.communication.Response;
+import org.openwebnet4j.message.BaseOpenMessage;
+import org.openwebnet4j.message.FrameException;
+import org.openwebnet4j.message.OpenMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link OpenWebNetBridgeActions} defines the Bridge actions for the
+ * openwebnet binding.
+ *
+ * @author Massimo Valla - Initial contribution
+ */
+
+@ThingActionsScope(name = "openwebnet")
+@NonNullByDefault
+public class OpenWebNetBridgeActions implements ThingActions {
+
+    private final Logger logger = LoggerFactory.getLogger(OpenWebNetBridgeActions.class);
+    private @Nullable OpenWebNetBridgeHandler bridgeHandler;
+
+    @Override
+    public void setThingHandler(@Nullable ThingHandler handler) {
+        this.bridgeHandler = (OpenWebNetBridgeHandler) handler;
+    }
+
+    @Override
+    public @Nullable ThingHandler getThingHandler() {
+        return bridgeHandler;
+    }
+
+    @RuleAction(label = "sendMessage", description = "@text/action.sendMessage.desc")
+    public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMessage(
+            @ActionInput(name = "message", label = "message", description = "@text/action.sendMessage.input.message.desc") @Nullable String message) {
+        @Nullable
+        Boolean s = (Boolean) sendMessageInternal(message).get("success");
+        if (s != null) {
+            return s;
+        } else {
+            return Boolean.FALSE;
+        }
+    }
+
+    @RuleAction(label = "sendMessageWithResponse", description = "@text/action.sendMessageWithResponse.desc")
+    public @ActionOutput(name = "success", type = "java.lang.Boolean") @ActionOutput(name = "responseMessages", type = "java.util.List<String>") Map<String, Object> sendMessageWithResponse(
+            @ActionInput(name = "message", label = "message", description = "@text/action.sendMessage.input.message.desc") @Nullable String message) {
+        return sendMessageInternal(message);
+    }
+
+    private Map<String, Object> sendMessageInternal(@Nullable String message) {
+        Map<String, Object> responseMap = new HashMap<>();
+        responseMap.put("success", Boolean.FALSE);
+        responseMap.put("responseMessages", Collections.emptyList());
+
+        if (message == null || message.isBlank()) {
+            logger.warn("openwebnet sendMessage: cannot send message, message is null or empty");
+            return responseMap;
+        }
+        OpenWebNetBridgeHandler handler = bridgeHandler;
+        if (handler == null) {
+            logger.warn("openwebnet sendMessage: cannot send message, bridgeHandler is null.");
+            return responseMap;
+        }
+        OpenMessage msg;
+        try {
+            msg = BaseOpenMessage.parse(message);
+        } catch (FrameException e) {
+            logger.warn("openwebnet skipping sending message '{}': {}.", message, e.getMessage());
+            return responseMap;
+        }
+
+        OpenGateway gw = handler.getGateway();
+        if (gw != null && gw.isConnected()) {
+            try {
+                Response res = gw.send(msg);
+                logger.debug("sent message {} to gateway. Response: {}.", msg, res.getResponseMessages());
+                responseMap.put("success", res.isSuccess());
+                List<String> resultList = res.getResponseMessages().stream().map(rm -> rm.getFrameValue())
+                        .collect(Collectors.toList());
+                responseMap.put("responseMessages", resultList);
+                return responseMap;
+            } catch (OWNException e) {
+                logger.warn("openwebnet exception while sending message '{}' to gateway: {}.", msg, e.getMessage());
+                return responseMap;
+            }
+        } else {
+            logger.warn("openwebnet skipping sendMessage for bridge {}: gateway is not connected.",
+                    handler.getThing().getUID());
+            return responseMap;
+        }
+    }
+
+    // legacy delegate methods
+    public static Boolean sendMessage(@Nullable ThingActions actions, String message) {
+        if (actions instanceof OpenWebNetBridgeActions openwebnetBridgeActions) {
+            return openwebnetBridgeActions.sendMessage(message);
+        } else {
+            throw new IllegalArgumentException("Instance is not an OpenWebNetBridgeActions class.");
+        }
+    }
+
+    public static Map<String, Object> sendMessageWithResponse(@Nullable ThingActions actions, String message) {
+        if (actions instanceof OpenWebNetBridgeActions openwebnetBridgeActions) {
+            return openwebnetBridgeActions.sendMessageWithResponse(message);
+        } else {
+            throw new IllegalArgumentException("Instance is not an OpenWebNetBridgeActions class.");
+        }
+    }
+}
index dc4b4379fed6f26b10915797a889a801a2e33afd..ad5e8a56c5a377d7d00631ab0e57de6cccbb2d4f 100644 (file)
@@ -30,7 +30,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * The {@link OpenWebNetCENActions} defines CEN/CEN+ actions for the openwebnet binding.
+ * The {@link OpenWebNetCENActions} defines CEN/CEN+ actions for the openwebnet
+ * binding.
  *
  * @author Massimo Valla - Initial contribution
  */
@@ -53,10 +54,10 @@ public class OpenWebNetCENActions implements ThingActions {
         return scenarioHandler;
     }
 
-    @RuleAction(label = "virtualPress", description = "Virtual press of the push button")
+    @RuleAction(label = "virtualPress", description = "@text/action.virtualPress.desc")
     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) {
+            @ActionInput(name = "press", label = "press", description = "@text/action.virtualPress.input.press.desc") @Nullable String press,
+            @ActionInput(name = "button", label = "button", description = "@text/action.virtualPress.input.button.desc") int button) {
         OpenWebNetScenarioHandler handler = scenarioHandler;
         if (handler == null) {
             logger.warn("openwebnet OpenWebNetCENActions: scenarioHandler is null!");
@@ -86,9 +87,9 @@ public class OpenWebNetCENActions implements ThingActions {
     }
 
     // legacy delegate methods
-    public static void virtualPress(@Nullable ThingActions actions, @Nullable String press, int button) {
+    public static Boolean virtualPress(@Nullable ThingActions actions, @Nullable String press, int button) {
         if (actions instanceof OpenWebNetCENActions openWebNetCENActions) {
-            openWebNetCENActions.virtualPress(press, button);
+            return openWebNetCENActions.virtualPress(press, button);
         } else {
             throw new IllegalArgumentException("Instance is not an OpenWebNetCENActions class.");
         }
index 7bf064e163bc133e2898d171ed2b5bca107ceaa9..f64b8f85b7530b4d685a01927de2a5214863bb48 100644 (file)
@@ -29,6 +29,7 @@ import java.util.concurrent.TimeUnit;
 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.OpenWebNetBridgeActions;
 import org.openhab.binding.openwebnet.internal.discovery.OpenWebNetDeviceDiscoveryService;
 import org.openhab.binding.openwebnet.internal.handler.config.OpenWebNetBusBridgeConfig;
 import org.openhab.binding.openwebnet.internal.handler.config.OpenWebNetZigBeeBridgeConfig;
@@ -271,9 +272,18 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
         reconnecting = false;
     }
 
+    /**
+     * Return the OpenGateway linked to this BridgeHandler
+     *
+     * @return the linked OpenGateway
+     */
+    public @Nullable OpenGateway getGateway() {
+        return gateway;
+    }
+
     @Override
     public Collection<Class<? extends ThingHandlerService>> getServices() {
-        return Set.of(OpenWebNetDeviceDiscoveryService.class);
+        return Set.of(OpenWebNetDeviceDiscoveryService.class, OpenWebNetBridgeActions.class);
     }
 
     /**
index 9809c08b77ef061c6bd5910ccd45621b737159b7..2984d571831c01ed0709432731e879b982a107f3 100644 (file)
@@ -309,7 +309,6 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
                     }
                 } catch (MalformedFrameException | OWNException e) {
                     logger.warn("handleSetpoint() {}", e.getMessage());
-
                 }
             } else {
                 logger.info("handleSetpoint() Setpoint temperature must be between 5°C and 40°C for thing {}",
index 46bd4904c49addd6b32c4200d0fde2df4ac50e36..6d088869a4725bae58ea710143ebd5245c4c5699 100644 (file)
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
 @NonNullByDefault
 public class SerialPortAdapter implements org.openwebnet4j.communication.serial.spi.SerialPort {
 
-    private static final Logger logger = LoggerFactory.getLogger(SerialPortAdapter.class);
+    private final Logger logger = LoggerFactory.getLogger(SerialPortAdapter.class);
 
     private static final int OPEN_TIMEOUT_MS = 200;
 
index f3dfa79d225d5f53b1b5031cac19dd70e728c967..6f973f45dc3f767061655e6488d4f7dd1688ea7b 100644 (file)
@@ -321,3 +321,12 @@ offline.conf-error-no-bridge = No bridge associated. Assign a bridge in configur
 offline.conf-error-auth = Authentication failed. Check gateway password in configuration
 offline.bridge-offline = Bridge offline
 unknown.waiting-state = Waiting state update...
+
+# actions
+
+action.sendMessage.desc = Sends a message to the gateway
+action.sendMessage.input.message.desc = The message to send
+action.sendMessageWithResponse.desc = Sends a message to the gateway and returns the response messages
+action.virtualPress.desc = Virtual press of a push button
+action.virtualPress.input.press.desc = Type of press
+action.virtualPress.input.button.desc = Button number