| 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
### 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
| 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
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:
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"
--- /dev/null
+/**
+ * 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.");
+ }
+ }
+}