diff --git a/bundles/org.openhab.binding.openwebnet/README.md b/bundles/org.openhab.binding.openwebnet/README.md
index 734e86658..9587f3653 100644
--- a/bundles/org.openhab.binding.openwebnet/README.md
+++ b/bundles/org.openhab.binding.openwebnet/README.md
@@ -123,13 +123,13 @@ Devices can be discovered automatically using an Inbox Scan after a gateway has
For any manually added device, you must configure:
-- the associated gateway (`Parent Bridge` menu)
-- the `where` configuration parameter (`OpenWebNet Address`):
- - 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"`
+- the associated gateway Thing (`Parent Bridge` menu)
+- the `where` configuration parameter (`OpenWebNet Address`): this is the OpenWebNet address configured for the device in the BTicino/Legrand system. This address can be found either on the device itself (Physical configuration, using jumpers in case of BUS) or through the MyHOME_Suite software (Virtual configuration). The address can have several formats depending on the device/system:
+ - example for BUS/SCS system, address Point-to-point with Area (A) and Light-point (PL):
+ - light device A=`2` (Area 2), PL=`4` (Light-point 4) --> `where="24"`
+ - light device A=`03`, PL=`11` on local bus --> `where="0311#4#01"`
+ - CEN scenario A=`05`, PL=`12` --> `where="0512"`
+ - CEN+ scenario `5`: add a `2` before --> `where="25"`
- Dry Contact or IR Interface `99`: add a `3` before --> `where="399"`
- 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`.
@@ -141,7 +141,7 @@ 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` configuration parameter (`OpenWebNet Address`):
- - example BUS/SCS Thermo zone `1` --> `where="1"`
+ - example BUS/SCS zone `1` --> `where="1"`
- the `standAlone` configuration 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:
diff --git a/bundles/org.openhab.binding.openwebnet/pom.xml b/bundles/org.openhab.binding.openwebnet/pom.xml
index a46c8481d..24b732b72 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.6.0
+ 0.7.1
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 f68924166..997f74318 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
@@ -138,7 +138,7 @@ public class OpenWebNetBindingConstants {
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
+ // gw config properties
public static final String CONFIG_PROPERTY_HOST = "host";
public static final String CONFIG_PROPERTY_SERIAL_PORT = "serialPort";
// properties
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 c92242d30..08077109b 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
@@ -54,25 +54,25 @@ public class OpenWebNetHandlerFactory extends BaseThingHandlerFactory {
@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
if (OpenWebNetBridgeHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
- logger.debug("creating NEW BRIDGE Handler");
+ logger.debug("creating NEW BRIDGE Handler --- {}", thing.getUID());
return new OpenWebNetBridgeHandler((Bridge) thing);
} else if (OpenWebNetGenericHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
- logger.debug("creating NEW GENERIC Handler");
+ logger.debug("creating NEW GENERIC Handler --- {}", thing.getUID());
return new OpenWebNetGenericHandler(thing);
} else if (OpenWebNetLightingHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
- logger.debug("creating NEW LIGHTING Handler");
+ logger.debug("creating NEW LIGHTING Handler --- {}", thing.getUID());
return new OpenWebNetLightingHandler(thing);
} else if (OpenWebNetAutomationHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
- logger.debug("creating NEW AUTOMATION Handler");
+ logger.debug("creating NEW AUTOMATION Handler --- {}", thing.getUID());
return new OpenWebNetAutomationHandler(thing);
} else if (OpenWebNetEnergyHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
- logger.debug("creating NEW ENERGY Handler");
+ logger.debug("creating NEW ENERGY Handler --- {}", thing.getUID());
return new OpenWebNetEnergyHandler(thing);
} else if (OpenWebNetThermoregulationHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
- logger.debug("creating NEW THERMO Handler");
+ logger.debug("creating NEW THERMO Handler --- {}", thing.getUID());
return new OpenWebNetThermoregulationHandler(thing);
} else if (OpenWebNetScenarioHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
- logger.debug("creating NEW SCENARIO Handler");
+ logger.debug("creating NEW SCENARIO Handler --- {}", thing.getUID());
return new OpenWebNetScenarioHandler(thing);
}
logger.warn("ThingType {} is not supported by this binding", thing.getThingTypeUID());
diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetAutomationHandler.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetAutomationHandler.java
index ecb00fcb7..43437d580 100644
--- a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetAutomationHandler.java
+++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetAutomationHandler.java
@@ -59,12 +59,10 @@ public class OpenWebNetAutomationHandler extends OpenWebNetThingHandler {
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("ss.SSS");
- private static long lastAllDevicesRefreshTS = -1; // timestamp when the last request for all device refresh was sent
- protected static final int ALL_DEVICES_REFRESH_INTERVAL_MSEC = 60000; // interval in msec before sending another all
- // devices refresh request
-
public static final Set SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.AUTOMATION_SUPPORTED_THING_TYPES;
+ private static long lastAllDevicesRefreshTS = 0; // ts when last all device refresh was sent for this handler
+
// moving states
public static final int MOVING_STATE_STOPPED = 0;
public static final int MOVING_STATE_MOVING_UP = 1;
@@ -141,38 +139,36 @@ public class OpenWebNetAutomationHandler extends OpenWebNetThingHandler {
@Override
protected void requestChannelState(ChannelUID channel) {
- logger.debug("requestChannelState() thingUID={} channel={}", thing.getUID(), channel.getId());
+ super.requestChannelState(channel);
Where w = deviceWhere;
if (w != null) {
try {
send(Automation.requestStatus(w.value()));
} catch (OWNException e) {
- logger.debug("Exception while requesting channel {} state: {}", channel, e.getMessage(), e);
+ logger.debug("Exception while requesting state for channel {}: {} ", channel, e.getMessage());
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
}
- } else {
- logger.warn("Could not requestChannelState(): deviceWhere is null");
}
}
+ @Override
+ protected long getRefreshAllLastTS() {
+ return lastAllDevicesRefreshTS;
+ };
+
@Override
protected void refreshDevice(boolean refreshAll) {
- OpenWebNetBridgeHandler brH = bridgeHandler;
- if (brH != null) {
- if (brH.isBusGateway() && refreshAll) {
- long now = System.currentTimeMillis();
- if (now - lastAllDevicesRefreshTS > ALL_DEVICES_REFRESH_INTERVAL_MSEC) {
- try {
- send(Automation.requestStatus(WhereLightAutom.GENERAL.value()));
- lastAllDevicesRefreshTS = now;
- } catch (OWNException e) {
- logger.warn("Excpetion while requesting all devices refresh: {}", e.getMessage());
- }
- } else {
- logger.debug("Refresh all devices just sent...");
- }
- } else {
- requestChannelState(new ChannelUID("any")); // channel here does not make any difference
+ if (refreshAll) {
+ logger.debug("--- refreshDevice() : refreshing GENERAL... ({})", thing.getUID());
+ try {
+ send(Automation.requestStatus(WhereLightAutom.GENERAL.value()));
+ lastAllDevicesRefreshTS = System.currentTimeMillis();
+ } catch (OWNException e) {
+ logger.warn("Excpetion while requesting all devices refresh: {}", e.getMessage());
}
+ } else {
+ logger.debug("--- refreshDevice() : refreshing SINGLE... ({})", thing.getUID());
+ requestChannelState(new ChannelUID(thing.getUID(), CHANNEL_SHUTTER));
}
}
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 a06b03d3e..e0b062916 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
@@ -16,6 +16,7 @@ import static org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -79,6 +80,9 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
private static final int REFRESH_ALL_DEVICES_DELAY_MSEC = 500; // Delay to wait before sending all devices refresh
// request after a connect/reconnect
+ private static final int REFRESH_ALL_CHECK_DELAY_SEC = 20;
+
+ private static long lastRegisteredDeviceTS = -1; // timestamp when the last device has been associated to the bridge
public static final Set SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.BRIDGE_SUPPORTED_THING_TYPES;
@@ -94,7 +98,8 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
public @Nullable OpenWebNetDeviceDiscoveryService deviceDiscoveryService;
private boolean reconnecting = false; // we are trying to reconnect to gateway
- private @Nullable ScheduledFuture> refreshSchedule;
+ private @Nullable ScheduledFuture> refreshAllSchedule;
+ private @Nullable ScheduledFuture> connectSchedule;
private boolean scanIsActive = false; // a device scan has been activated by OpenWebNetDeviceDiscoveryService;
private boolean discoveryByActivation;
@@ -128,8 +133,8 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
logger.debug("Trying to connect gateway {}... ", gw);
try {
gw.connect();
- scheduler.schedule(() -> {
- // if status is still UNKNOWN after timer ends, set the device as OFFLINE
+ connectSchedule = scheduler.schedule(() -> {
+ // if status is still UNKNOWN after timer ends, set the device OFFLINE
if (thing.getStatus().equals(ThingStatus.UNKNOWN)) {
logger.info("status still UNKNOWN. Setting device={} to OFFLINE", thing.getUID());
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
@@ -167,6 +172,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
*/
private @Nullable OpenGateway initBusGateway() {
logger.debug("Initializing BUS gateway");
+
OpenWebNetBusBridgeConfig busBridgeConfig = getConfigAs(OpenWebNetBusBridgeConfig.class);
String host = busBridgeConfig.getHost();
if (host == null || host.isEmpty()) {
@@ -199,7 +205,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
return;
} else {
if (command instanceof RefreshType) {
- refreshAllDevices();
+ refreshAllBridgeDevices();
} else {
logger.warn("Command or channel not supported: channel={} command={}", channelUID, command);
}
@@ -219,10 +225,14 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
@Override
public void dispose() {
- ScheduledFuture> rSc = refreshSchedule;
+ ScheduledFuture> rSc = refreshAllSchedule;
if (rSc != null) {
rSc.cancel(true);
}
+ ScheduledFuture> cs = connectSchedule;
+ if (cs != null) {
+ cs.cancel(true);
+ }
disconnectGateway();
super.dispose();
}
@@ -366,6 +376,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
logger.warn("registering device with an existing ownId={}", ownId);
}
registeredDevices.put(ownId, thingHandler);
+ lastRegisteredDeviceTS = System.currentTimeMillis();
logger.debug("registered device ownId={}, thing={}", ownId, thingHandler.getThing().getUID());
}
@@ -392,13 +403,62 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
return registeredDevices.get(ownId);
}
- private void refreshAllDevices() {
- logger.debug("Refreshing all devices for bridge {}", thing.getUID());
- for (Thing ownThing : getThing().getThings()) {
- OpenWebNetThingHandler hndlr = (OpenWebNetThingHandler) ownThing.getHandler();
- if (hndlr != null) {
- hndlr.refreshDevice(true);
+ private void refreshAllBridgeDevices() {
+ logger.debug("--- --- ABOUT TO REFRESH ALL devices for bridge {}", thing.getUID());
+ int howMany = 0;
+ final List things = getThing().getThings();
+ int total = things.size();
+ logger.debug("--- FOUND {} things by getThings()", total);
+ if (total > 0) {
+ if (registeredDevices.isEmpty()
+ || (System.currentTimeMillis() - lastRegisteredDeviceTS < REFRESH_ALL_DEVICES_DELAY_MSEC)) {
+ // if a device has been registered with the bridge just now, let's wait for other devices: re-schedule
+ // refreshAllDevices
+ logger.debug(
+ "--- REGISTER device not started or just called... re-scheduling refreshAllBridgeDevices()");
+ refreshAllSchedule = scheduler.schedule(this::refreshAllBridgeDevices, REFRESH_ALL_DEVICES_DELAY_MSEC,
+ TimeUnit.MILLISECONDS);
+ } else {
+ for (Thing ownThing : things) {
+ OpenWebNetThingHandler hndlr = (OpenWebNetThingHandler) ownThing.getHandler();
+ if (hndlr != null) {
+ howMany++;
+ logger.debug("--- REFRESHING ALL DEVICES FOR thing #{}/{}: {}", howMany, total,
+ ownThing.getUID());
+ hndlr.refreshAllDevices();
+ } else {
+ logger.warn("--- No handler for thing {}", ownThing.getUID());
+ }
+ }
+ logger.debug("--- --- COMPLETED REFRESH all devices for bridge {}", thing.getUID());
+
+ // set a check that all things are Online
+ refreshAllSchedule = scheduler.schedule(() -> checkAllRefreshed(things), REFRESH_ALL_CHECK_DELAY_SEC,
+ TimeUnit.SECONDS);
}
+ } else {
+ logger.debug("--- --- NO CHILD DEVICE to REFRESH for bridge {}", thing.getUID());
+ }
+ }
+
+ private void checkAllRefreshed(List things) {
+ int howMany = 0;
+ int total = things.size();
+ boolean allOnline = true;
+ for (Thing ownThing : things) {
+ howMany++;
+ ThingStatus ts = ownThing.getStatus();
+ if (ThingStatus.ONLINE == ts) {
+ logger.debug("--- CHECKED ONLINE thing #{}/{}: {}", howMany, total, ownThing.getUID());
+ } else {
+ logger.debug("--- CHECKED ^^^OFFLINE^^^ thing #{}/{}: {}", howMany, total, ownThing.getUID());
+ allOnline = false;
+ }
+ }
+ if (allOnline) {
+ logger.debug("--- --- REFRESH CHECK COMPLETED: all things ONLINE for bridge {}", thing.getUID());
+ } else {
+ logger.debug("--- --- REFRESH CHECK COMPLETED: NOT all things ONLINE for bridge {}", thing.getUID());
}
}
@@ -476,7 +536,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
}
updateStatus(ThingStatus.ONLINE);
// schedule a refresh for all devices
- refreshSchedule = scheduler.schedule(this::refreshAllDevices, REFRESH_ALL_DEVICES_DELAY_MSEC,
+ refreshAllSchedule = scheduler.schedule(this::refreshAllBridgeDevices, REFRESH_ALL_DEVICES_DELAY_MSEC,
TimeUnit.MILLISECONDS);
}
@@ -532,7 +592,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
"@text/offline.conf-error-auth" + " (" + e + ")");
}
} else {
- logger.debug("---- reconnecting=true");
+ logger.debug("---- already reconnecting");
}
} else {
logger.warn("---- cannot start RECONNECT, gateway is null");
@@ -550,9 +610,8 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
this.updateProperty(PROPERTY_FIRMWARE_VERSION, gw.getFirmwareVersion());
logger.debug("gw firmware version: {}", gw.getFirmwareVersion());
}
-
// schedule a refresh for all devices
- refreshSchedule = scheduler.schedule(this::refreshAllDevices, REFRESH_ALL_DEVICES_DELAY_MSEC,
+ refreshAllSchedule = scheduler.schedule(this::refreshAllBridgeDevices, REFRESH_ALL_DEVICES_DELAY_MSEC,
TimeUnit.MILLISECONDS);
}
}
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 d0e1c6794..59c68e5d1 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
@@ -28,6 +28,7 @@ import org.openhab.core.library.unit.Units;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.ThingStatusInfo;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.types.Command;
@@ -146,22 +147,22 @@ public class OpenWebNetEnergyHandler extends OpenWebNetThingHandler {
@Override
protected void requestChannelState(ChannelUID channel) {
- logger.debug("requestChannelState() thingUID={} channel={}", thing.getUID(), channel.getId());
+ super.requestChannelState(channel);
Where w = deviceWhere;
if (w != null) {
try {
send(EnergyManagement.requestActivePower(w.value()));
} catch (OWNException e) {
- logger.debug("Exception while requesting channel {} state: {}", channel, e.getMessage(), e);
+ logger.debug("Exception while requesting state for channel {}: {} ", channel, e.getMessage());
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
}
- } else {
- logger.warn("Could not requestChannelState(): deviceWhere is null");
}
}
@Override
protected void refreshDevice(boolean refreshAll) {
- requestChannelState(new ChannelUID("any:any:any:any"));
+ logger.debug("--- refreshDevice() : refreshing SINGLE... ({})", thing.getUID());
+ requestChannelState(new ChannelUID(thing.getUID(), CHANNEL_POWER));
}
@Override
diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetLightingHandler.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetLightingHandler.java
index 2236c123a..c8f2b61a5 100644
--- a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetLightingHandler.java
+++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetLightingHandler.java
@@ -26,10 +26,10 @@ import org.openhab.core.library.types.PercentType;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.types.Command;
import org.openwebnet4j.communication.OWNException;
-import org.openwebnet4j.communication.Response;
import org.openwebnet4j.message.BaseOpenMessage;
import org.openwebnet4j.message.FrameException;
import org.openwebnet4j.message.Lighting;
@@ -63,16 +63,12 @@ public class OpenWebNetLightingHandler extends OpenWebNetThingHandler {
private static final int UNKNOWN_STATE = 1000;
- private static long lastAllDevicesRefreshTS = -1; // timestamp when the last request for all device refresh was sent
- // for this handler
-
- protected static final int ALL_DEVICES_REFRESH_INTERVAL_MSEC = 60000; // interval in msec before sending another all
- // devices refresh request
-
private long lastBrightnessChangeSentTS = 0; // timestamp when last brightness change was sent to the device
private long lastStatusRequestSentTS = 0; // timestamp when last status request was sent to the device
+ private static long lastAllDevicesRefreshTS = 0; // ts when last all device refresh was sent for this handler
+
private int brightness = UNKNOWN_STATE; // current brightness percent value for this device
private int brightnessBeforeOff = UNKNOWN_STATE; // latest brightness before device was set to off
@@ -85,58 +81,43 @@ public class OpenWebNetLightingHandler extends OpenWebNetThingHandler {
@Override
protected void requestChannelState(ChannelUID channel) {
- logger.debug("requestChannelState() thingUID={} channel={}", thing.getUID(), channel.getId());
- requestStatus(channel.getId());
- }
-
- /** helper method to request light status based on channel */
- private void requestStatus(String channelId) {
- Where w = deviceWhere;
- if (w != null) {
+ super.requestChannelState(channel);
+ if (deviceWhere != null) {
try {
lastStatusRequestSentTS = System.currentTimeMillis();
- Response res = send(Lighting.requestStatus(toWhere(channelId)));
- if (res != null && res.isSuccess()) {
- // set thing online, if not already
- ThingStatus ts = getThing().getStatus();
- if (ThingStatus.ONLINE != ts && ThingStatus.REMOVING != ts && ThingStatus.REMOVED != ts) {
- updateStatus(ThingStatus.ONLINE);
- }
- }
+ send(Lighting.requestStatus(toWhere(channel.getId())));
} catch (OWNException e) {
- logger.warn("requestStatus() Exception while requesting light state: {}", e.getMessage());
+ logger.debug("Exception while requesting state for channel {}: {} ", channel, e.getMessage());
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
}
- } else {
- logger.warn("Could not requestStatus(): deviceWhere is null");
}
}
+ @Override
+ protected long getRefreshAllLastTS() {
+ return lastAllDevicesRefreshTS;
+ };
+
@Override
protected void refreshDevice(boolean refreshAll) {
- OpenWebNetBridgeHandler brH = bridgeHandler;
- if (brH != null) {
- if (brH.isBusGateway() && refreshAll) {
- long now = System.currentTimeMillis();
- if (now - lastAllDevicesRefreshTS > ALL_DEVICES_REFRESH_INTERVAL_MSEC) {
- try {
- send(Lighting.requestStatus(WhereLightAutom.GENERAL.value()));
- lastAllDevicesRefreshTS = now;
- } catch (OWNException e) {
- logger.warn("Excpetion while requesting all devices refresh: {}", e.getMessage());
- }
- } else {
- logger.debug("Refresh all devices just sent...");
- }
- } else { // USB or BUS-single device
- ThingTypeUID thingType = thing.getThingTypeUID();
- if (THING_TYPE_ZB_ON_OFF_SWITCH_2UNITS.equals(thingType)) {
- // Unfortunately using USB Gateway OpenWebNet both switch endpoints cannot be requested at the same
- // time using UNIT 00 because USB stick returns NACK, so we need to send a request status for both
- // endpoints
- requestStatus(CHANNEL_SWITCH_02);
- }
- requestStatus(""); // channel here does not make any difference, see {@link #toWhere()}
+ if (refreshAll) {
+ logger.debug("--- refreshDevice() : refreshing GENERAL... ({})", thing.getUID());
+ try {
+ send(Lighting.requestStatus(WhereLightAutom.GENERAL.value()));
+ lastAllDevicesRefreshTS = System.currentTimeMillis();
+ } catch (OWNException e) {
+ logger.warn("Excpetion while requesting all devices refresh: {}", e.getMessage());
}
+ } else {
+ logger.debug("--- refreshDevice() : refreshing SINGLE... ({})", thing.getUID());
+ ThingTypeUID thingType = thing.getThingTypeUID();
+ if (THING_TYPE_ZB_ON_OFF_SWITCH_2UNITS.equals(thingType)) {
+ // Unfortunately using USB Gateway OpenWebNet both switch endpoints cannot be requested at the same
+ // time using UNIT 00 because USB stick returns NACK, so we need to send a request status for both
+ // endpoints
+ requestChannelState(new ChannelUID(thing.getUID(), CHANNEL_SWITCH_02));
+ }
+ requestChannelState(new ChannelUID(thing.getUID(), CHANNEL_SWITCH_01));
}
}
@@ -291,7 +272,7 @@ public class OpenWebNetLightingHandler extends OpenWebNetThingHandler {
logger.debug(" $BRI 'ON' is new notification from network, scheduling requestStatus...");
// we must wait BRIGHTNESS_STATUS_REQUEST_DELAY_MSEC to be sure dimmer has reached its final level
scheduler.schedule(() -> {
- requestStatus(CHANNEL_BRIGHTNESS);
+ requestChannelState(new ChannelUID(thing.getUID(), CHANNEL_BRIGHTNESS));
}, BRIGHTNESS_STATUS_REQUEST_DELAY_MSEC, TimeUnit.MILLISECONDS);
return;
} else {
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
index 25547cbb9..33b61005f 100644
--- 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
@@ -30,6 +30,8 @@ import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.ThingHandlerService;
import org.openhab.core.thing.binding.builder.ChannelBuilder;
@@ -117,10 +119,8 @@ public class OpenWebNetScenarioHandler extends OpenWebNetThingHandler {
private boolean isDryContactIR = false;
private boolean isCENPlus = false;
- private static long lastAllDevicesRefreshTS = -1; // timestamp when the last request for all device refresh was sent
- // for this handler
- protected static final int ALL_DEVICES_REFRESH_INTERVAL_MSEC = 10000; // interval in msec before sending another all
- // devices refresh request
+
+ private static long lastAllDevicesRefreshTS = 0; // ts when last all device refresh was sent for this handler
public static final Set SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.SCENARIO_SUPPORTED_THING_TYPES;
@@ -361,49 +361,50 @@ public class OpenWebNetScenarioHandler extends OpenWebNetThingHandler {
}
@Override
- protected void refreshDevice(boolean refreshAll) {
+ protected void requestChannelState(ChannelUID channel) {
if (isDryContactIR) {
- if (refreshAll) {
- long now = System.currentTimeMillis();
- if (now - lastAllDevicesRefreshTS > ALL_DEVICES_REFRESH_INTERVAL_MSEC) {
- try {
- send(CENPlusScenario.requestStatus("30"));
- lastAllDevicesRefreshTS = now;
- } catch (OWNException e) {
- logger.warn("Excpetion while requesting all DryContact/IR devices refresh: {}", e.getMessage());
- }
- } else {
- logger.debug("Refresh all devices just sent...");
+ super.requestChannelState(channel);
+ Where w = deviceWhere;
+ if (w != null) {
+ try {
+ send(CENPlusScenario.requestStatus(w.value()));
+ } catch (OWNException e) {
+ logger.debug("Exception while requesting state for channel {}: {} ", channel, e.getMessage());
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
}
- } else {
- requestState();
}
} else {
- logger.debug("CEN/CEN+ channels are trigger channels and do not have state");
+ logger.debug("requestChannelState() CEN/CEN+ channels are trigger channels and do not have state.");
}
}
@Override
- protected void requestChannelState(ChannelUID channel) {
- if (isDryContactIR) {
- requestState();
- } else {
- logger.debug("CEN/CEN+ channels are trigger channels and do not have state");
- }
- }
+ protected long getRefreshAllLastTS() {
+ return lastAllDevicesRefreshTS;
+ };
- /* helper method to request DryContact/IR device state */
- private void requestState() {
- Where w = deviceWhere;
- if (w != null) {
- try {
- send(CENPlusScenario.requestStatus(w.value()));
- } catch (OWNException e) {
- logger.warn("requestState() Exception while requesting device state: {} for thing {}", e.getMessage(),
- thing.getUID());
+ @Override
+ protected void refreshDevice(boolean refreshAll) {
+ if (isDryContactIR) {
+ if (refreshAll) {
+ logger.debug("--- refreshDevice() : refreshing GENERAL... ({})", thing.getUID());
+ try {
+ send(CENPlusScenario.requestStatus("30"));
+ lastAllDevicesRefreshTS = System.currentTimeMillis();
+ } catch (OWNException e) {
+ logger.warn("Excpetion while requesting all devices refresh: {}", e.getMessage());
+ }
+ } else {
+ logger.debug("--- refreshDevice() : refreshing SINGLE... ({})", thing.getUID());
+ requestChannelState(new ChannelUID(thing.getUID(), CHANNEL_DRY_CONTACT_IR));
}
} else {
- logger.warn("Could not requestState(): deviceWhere is null");
+ logger.debug("CEN/CEN+ channels are trigger channels and do not have state. Setting it ONLINE");
+ // put CEN/CEN+ scenario things to ONLINE automatically as they do not have state
+ ThingStatus ts = getThing().getStatus();
+ if (ThingStatus.ONLINE != ts && ThingStatus.REMOVING != ts && ThingStatus.REMOVED != ts) {
+ updateStatus(ThingStatus.ONLINE);
+ }
}
}
diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThermoregulationHandler.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThermoregulationHandler.java
index 42c7fd413..4dba0b938 100644
--- a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThermoregulationHandler.java
+++ b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetThermoregulationHandler.java
@@ -97,9 +97,31 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
@Override
protected void requestChannelState(ChannelUID channel) {
+ super.requestChannelState(channel);
refreshDevice(false);
}
+ @Override
+ protected void refreshDevice(boolean refreshAll) {
+ logger.debug("--- refreshDevice() : refreshing SINGLE... ({})", thing.getUID());
+ if (deviceWhere != null) {
+ String w = deviceWhere.value();
+ try {
+ send(Thermoregulation.requestTemperature(w));
+ if (!this.isTempSensor) {
+ // for bus_thermo_zone request also other single channels updates
+ send(Thermoregulation.requestSetPointTemperature(w));
+ send(Thermoregulation.requestFanCoilSpeed(w));
+ send(Thermoregulation.requestMode(w));
+ send(Thermoregulation.requestValvesStatus(w));
+ send(Thermoregulation.requestActuatorsStatus(w));
+ }
+ } catch (OWNException e) {
+ logger.warn("refreshDevice() where='{}' returned OWNException {}", w, e.getMessage());
+ }
+ }
+ }
+
@Override
protected Where buildBusWhere(String wStr) throws IllegalArgumentException {
WhereThermo wt = new WhereThermo(wStr);
@@ -233,17 +255,17 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
Thermoregulation.WhatThermo w = Thermoregulation.WhatThermo.fromValue(tmsg.getWhat().value());
- if (w.mode() == null) {
+ if (w.getMode() == null) {
logger.debug("updateModeAndFunction() Could not parse Mode from: {}", tmsg.getFrameValue());
return;
}
- if (w.function() == null) {
+ if (w.getFunction() == null) {
logger.debug("updateModeAndFunction() Could not parse Function from: {}", tmsg.getFrameValue());
return;
}
- Thermoregulation.OperationMode mode = w.mode();
- Thermoregulation.Function function = w.function();
+ Thermoregulation.OperationMode mode = w.getMode();
+ Thermoregulation.Function function = w.getFunction();
if (w == Thermoregulation.WhatThermo.HEATING) {
function = Thermoregulation.Function.HEATING;
@@ -314,24 +336,4 @@ public class OpenWebNetThermoregulationHandler extends OpenWebNetThingHandler {
updateState(CHANNEL_ACTUATORS, UnDefType.UNDEF);
}
}
-
- @Override
- protected void refreshDevice(boolean refreshAll) {
- if (deviceWhere != null) {
- String w = deviceWhere.value();
- try {
- send(Thermoregulation.requestTemperature(w));
- if (!this.isTempSensor) {
- // for bus_thermo_zone request also other single channels updates
- send(Thermoregulation.requestSetPointTemperature(w));
- send(Thermoregulation.requestFanCoilSpeed(w));
- send(Thermoregulation.requestMode(w));
- send(Thermoregulation.requestValvesStatus(w));
- send(Thermoregulation.requestActuatorsStatus(w));
- }
- } catch (OWNException e) {
- logger.warn("refreshDevice() where='{}' returned OWNException {}", w, e.getMessage());
- }
- }
- }
}
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 1cc076890..3ab7523eb 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
@@ -29,6 +29,7 @@ import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.ThingStatusInfo;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
@@ -58,10 +59,14 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
protected @Nullable OpenWebNetBridgeHandler bridgeHandler;
protected @Nullable String ownId; // OpenWebNet identifier for this device: WHO.WHERE
- protected @Nullable Where deviceWhere; // this device Where address
+ protected @Nullable Where deviceWhere; // this device WHERE address
+ protected @Nullable ScheduledFuture> requestChannelStateTimeout;
protected @Nullable ScheduledFuture> refreshTimeout;
+ private static final int ALL_DEVICES_REFRESH_INTERVAL_MSEC = 60_000; // interval before sending another
+ // refreshAllDevices request
+
public OpenWebNetThingHandler(Thing thing) {
super(thing);
}
@@ -108,6 +113,15 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
}
}
+ @Override
+ public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
+ if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
+ updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, "@text/unknown.waiting-state");
+ } else if (bridgeStatusInfo.getStatus() == ThingStatus.OFFLINE) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
+ }
+ }
+
@Override
public void handleCommand(ChannelUID channel, Command command) {
logger.debug("handleCommand() (command={} - channel={})", command, channel);
@@ -115,23 +129,16 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
if (handler != null) {
OpenGateway gw = handler.gateway;
if (gw != null && !gw.isConnected()) {
- logger.info("Cannot handle {} command for {}: gateway is not connected", command, getThing().getUID());
+ logger.info("Cannot handle {} command for {}: gateway is not connected", command, thing.getUID());
return;
}
if (deviceWhere == null) {
logger.info("Cannot handle {} command for {}: 'where' parameter is not configured or is invalid",
- command, getThing().getUID());
+ command, thing.getUID());
return;
}
if (command instanceof RefreshType) {
requestChannelState(channel);
- // set a schedule to put device OFFLINE if no answer is received after THING_STATE_REQ_TIMEOUT_SEC
- refreshTimeout = scheduler.schedule(() -> {
- if (thing.getStatus().equals(ThingStatus.UNKNOWN)) {
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
- "Could not get channel state (timer expired)");
- }
- }, THING_STATE_REQ_TIMEOUT_SEC, TimeUnit.SECONDS);
} else {
handleChannelCommand(channel, command);
}
@@ -142,16 +149,16 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
/**
* Handles a command for the specific channel for this thing.
- * It must be implemented by each specific OpenWebNet category of device (WHO), based on channel
+ * It must be further implemented by each specific device handler.
*
- * @param channel specific ChannleUID
+ * @param channel the {@link ChannelUID}
* @param command the Command to be executed
*/
protected abstract void handleChannelCommand(ChannelUID channel, Command command);
/**
- * Handle incoming message from OWN network via bridge Thing, directed to this device. It should be further
- * implemented by each specific device handler.
+ * Handle incoming message from OWN network via bridge Thing, directed to this device.
+ * It should be further implemented by each specific device handler.
*
* @param msg the message to handle
*/
@@ -163,7 +170,9 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
}
/**
- * Helper method to send OWN messages from ThingHandlers
+ * Helper method to send OWN messages from handler.
+ *
+ * @param msg the OpenMessage to be sent
*/
public @Nullable Response send(OpenMessage msg) throws OWNException {
OpenWebNetBridgeHandler bh = bridgeHandler;
@@ -178,7 +187,9 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
}
/**
- * Helper method to send with high priority OWN messages from ThingsHandlers
+ * Helper method to send with high priority OWN messages from handler.
+ *
+ * @param msg the OpenMessage to be sent
*/
protected @Nullable Response sendHighPriority(OpenMessage msg) throws OWNException {
OpenWebNetBridgeHandler handler = bridgeHandler;
@@ -192,19 +203,87 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
}
/**
- * Request the state for the specified channel
+ * Request the state for the specified channel. If no answer is received within THING_STATE_REQ_TIMEOUT_SEC, it is
+ * put OFFLINE.
+ * The method must be further implemented by each specific handler.
*
* @param channel the {@link ChannelUID} to request the state for
*/
- protected abstract void requestChannelState(ChannelUID channel);
+ protected void requestChannelState(ChannelUID channel) {
+ logger.debug("requestChannelState() {}", channel);
+ Where w = deviceWhere;
+ if (w == null) {
+ logger.warn("Could not requestChannelState(): deviceWhere is null for thing {}", thing.getUID());
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "@text/offline.conf-error-where");
+ return;
+ }
+ // set a schedule to put device OFFLINE if no answer is received after THING_STATE_REQ_TIMEOUT_SEC
+ requestChannelStateTimeout = scheduler.schedule(() -> {
+ if (thing.getStatus().equals(ThingStatus.UNKNOWN)) {
+ logger.debug("requestChannelState() TIMEOUT for thing {}", thing.getUID());
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+ "@text/offline.comm-error-state");
+ }
+ }, THING_STATE_REQ_TIMEOUT_SEC, TimeUnit.SECONDS);
+ }
/**
- * Refresh the device
+ * Refresh a device, possibly using a single OWN command if refreshAll=true and if supported.
+ * The method must be further implemented by each specific handler.
*
- * @param refreshAll set true if all devices of the binding should be refreshed with one command, if possible
+ * @param refreshAll true if all devices for this handler must be refreshed with a single OWN command, if supported,
+ * otherwise just refresh the single device.
*/
protected abstract void refreshDevice(boolean refreshAll);
+ /**
+ * If the subclass supports refreshing all devices with a single OWN command, returns the last TS when a refreshAll
+ * was requested, or 0 if not requested yet. If not supported return -1 (default).
+ * It must be implemented by each subclass that supports all devices refresh.
+ *
+ * @return timestamp when last refreshAll command was sent, 0 if not requested yet, or -1 if it's not supported by
+ * subclass.
+ */
+ protected long getRefreshAllLastTS() {
+ return -1;
+ };
+
+ /**
+ * Refresh all devices for this handler
+ */
+ protected void refreshAllDevices() {
+ logger.debug("--- refreshAllDevices() for device {}", thing.getUID());
+ OpenWebNetBridgeHandler brH = bridgeHandler;
+ if (brH != null) {
+ long refAllTS = getRefreshAllLastTS();
+ logger.debug("{} support = {}", thing.getUID(), refAllTS >= 0);
+ if (brH.isBusGateway() && refAllTS >= 0) {
+ long now = System.currentTimeMillis();
+ if (now - refAllTS > ALL_DEVICES_REFRESH_INTERVAL_MSEC) {
+ logger.debug("--- refreshAllDevices() : refreshing ALL devices... ({})", thing.getUID());
+ refreshDevice(true);
+ } else {
+ logger.debug("--- refreshAllDevices() : refresh all devices just sent... ({})", thing.getUID());
+ }
+ // sometimes GENERAL (e.g. #*1*0##) refresh requests do not return state for all devices, so let's
+ // schedule another single refresh device, just in case
+ refreshTimeout = scheduler.schedule(() -> {
+ if (thing.getStatus().equals(ThingStatus.UNKNOWN)) {
+ logger.debug(
+ "--- refreshAllDevices() : schedule expired: --UNKNOWN-- status for {}. Refreshing it...",
+ thing.getUID());
+ refreshDevice(false);
+ } else {
+ logger.debug("--- refreshAllDevices() : schedule expired: ONLINE status for {}",
+ thing.getUID());
+ }
+ }, THING_STATE_REQ_TIMEOUT_SEC, TimeUnit.SECONDS);
+ } else { // USB device or AllDevicesRefresh not supported
+ refreshDevice(false);
+ }
+ }
+ }
+
/**
* Abstract builder for device Where address, to be implemented by each subclass to choose the right Where subclass
* (the method is used only if the Thing is associated to a BUS gateway).
@@ -220,9 +299,13 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
if (bh != null && oid != null) {
bh.unregisterDevice(oid);
}
- ScheduledFuture> sc = refreshTimeout;
- if (sc != null) {
- sc.cancel(true);
+ ScheduledFuture> rcst = requestChannelStateTimeout;
+ if (rcst != null) {
+ rcst.cancel(true);
+ }
+ ScheduledFuture> rt = refreshTimeout;
+ if (rt != null) {
+ rt.cancel(true);
}
super.dispose();
}
diff --git a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/i18n/openwebnet.properties b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/i18n/openwebnet.properties
index bf3bac400..dd528e287 100644
--- a/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/i18n/openwebnet.properties
+++ b/bundles/org.openhab.binding.openwebnet/src/main/resources/OH-INF/i18n/openwebnet.properties
@@ -14,5 +14,6 @@ offline.conf-error-auth = Authentication failed. Check gateway password in confi
offline.comm-error-disconnected = Disconnected from gateway.
offline.comm-error-timeout = Connection to gateway timed out.
offline.comm-error-connection = Could not connect to gateway.
+offline.comm-error-state = Could not get channel state.
unknown.waiting-state = Waiting state update...