]> git.basschouten.com Git - openhab-addons.git/commitdiff
[deconz] fix lastSeenPolling and compile warnings (#8918)
authorJ-N-K <J-N-K@users.noreply.github.com>
Tue, 3 Nov 2020 22:23:57 +0000 (23:23 +0100)
committerGitHub <noreply@github.com>
Tue, 3 Nov 2020 22:23:57 +0000 (14:23 -0800)
Signed-off-by: Jan N. Klug <jan.n.klug@rub.de>
bundles/org.openhab.binding.deconz/README.md
bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/discovery/ThingDiscoveryService.java
bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/DeconzBaseThingHandler.java
bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/GroupThingHandler.java
bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/LightThingHandler.java
bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/SensorBaseThingHandler.java
bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/SensorThermostatThingHandler.java
bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/SensorThingHandler.java
bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/ThingConfig.java
bundles/org.openhab.binding.deconz/src/main/resources/OH-INF/config/config.xml

index 188da3cb0f6e6d39b7fb3ca272de396ca5da8af4..d10d17bf8dd917e560789ccbbdcc1f9a8264b1c7 100644 (file)
@@ -81,7 +81,7 @@ Auto-discovered things do not need to be configured.
 All sensor-things have an additional `lastSeenPolling` parameter.
 Due to limitations in the API of deCONZ, the `lastSeen` channel (available some sensors) is only available when using polling.
 Allowed values are all positive integers, the unit is minutes.
-The default-value is `0`, which means "no polling at all".
+The default-value is `1440`, which means "once a day".
 
 `dimmablelight`, `extendedcolorlight`, `colorlight` and `colortemperaturelight` have an additional optional parameter `transitiontime`.
 The transition time is the time to move between two states and is configured in seconds.
index 5cfbfeb876b8f88f781399a5319c38e66fb77a91..d848feaf08e84a6c85f567e9eb8cdb5566c87fc4 100644 (file)
@@ -163,11 +163,11 @@ public class ThingDiscoveryService extends AbstractDiscoveryService implements D
         properties.put(Thing.PROPERTY_VENDOR, light.manufacturername);
         properties.put(Thing.PROPERTY_MODEL_ID, light.modelid);
 
-        if (light.ctmax != null && light.ctmin != null) {
-            properties.put(PROPERTY_CT_MAX,
-                    Integer.toString(Util.constrainToRange(light.ctmax, ZCL_CT_MIN, ZCL_CT_MAX)));
-            properties.put(PROPERTY_CT_MIN,
-                    Integer.toString(Util.constrainToRange(light.ctmin, ZCL_CT_MIN, ZCL_CT_MAX)));
+        Integer ctmax = light.ctmax;
+        Integer ctmin = light.ctmin;
+        if (ctmax != null && ctmin != null) {
+            properties.put(PROPERTY_CT_MAX, Integer.toString(Util.constrainToRange(ctmax, ZCL_CT_MIN, ZCL_CT_MAX)));
+            properties.put(PROPERTY_CT_MIN, Integer.toString(Util.constrainToRange(ctmin, ZCL_CT_MIN, ZCL_CT_MAX)));
         }
 
         switch (lightType) {
index 8125b2cde97f30237dfea130eba37ce9f1af8667..9676e07e28fc0ccadc0be02c0b182a20d3918fb5 100644 (file)
@@ -19,6 +19,7 @@ import java.util.concurrent.CompletionException;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.function.Consumer;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -119,7 +120,7 @@ public abstract class DeconzBaseThingHandler<T extends DeconzBaseMessage> extend
             registerListener();
 
             // get initial values
-            requestState();
+            requestState(this::processStateResponse);
         } else {
             // if the bridge is not ONLINE, we assume communication is not possible, so we unregister the listener and
             // set the thing status to OFFLINE
@@ -131,7 +132,7 @@ public abstract class DeconzBaseThingHandler<T extends DeconzBaseMessage> extend
     protected abstract @Nullable T parseStateResponse(AsyncHttpClient.Result r);
 
     /**
-     * processes a newly received state response
+     * processes a newly received (initial) state response
      *
      * MUST set the thing status!
      *
@@ -142,7 +143,7 @@ public abstract class DeconzBaseThingHandler<T extends DeconzBaseMessage> extend
     /**
      * Perform a request to the REST API for retrieving the full light state with all data and configuration.
      */
-    protected void requestState() {
+    protected void requestState(Consumer<@Nullable T> processor) {
         AsyncHttpClient asyncHttpClient = http;
         if (asyncHttpClient == null) {
             return;
@@ -162,10 +163,11 @@ public abstract class DeconzBaseThingHandler<T extends DeconzBaseMessage> extend
             }
 
             stopInitializationJob();
-            initializationJob = scheduler.schedule((Runnable) this::requestState, 10, TimeUnit.SECONDS);
+            initializationJob = scheduler.schedule(() -> requestState(this::processStateResponse), 10,
+                    TimeUnit.SECONDS);
 
             return null;
-        }).thenAccept(this::processStateResponse);
+        }).thenAccept(processor);
     }
 
     /**
index 4d1acae5220139ffab6fabc884acc4b1571afe0c..dad89c31a51383f478ccf4c17b57773123940e36 100644 (file)
@@ -91,8 +91,9 @@ public class GroupThingHandler extends DeconzBaseThingHandler<GroupMessage> {
             case CHANNEL_COLOR:
                 if (command instanceof HSBType) {
                     HSBType hsbCommand = (HSBType) command;
-                    newGroupAction.bri = Util.fromPercentType(hsbCommand.getBrightness());
-                    if (newGroupAction.bri > 0) {
+                    Integer bri = Util.fromPercentType(hsbCommand.getBrightness());
+                    newGroupAction.bri = bri;
+                    if (bri > 0) {
                         newGroupAction.hue = (int) (hsbCommand.getHue().doubleValue() * HUE_FACTOR);
                         newGroupAction.sat = Util.fromPercentType(hsbCommand.getSaturation());
                     }
@@ -118,7 +119,8 @@ public class GroupThingHandler extends DeconzBaseThingHandler<GroupMessage> {
                 return;
         }
 
-        if (newGroupAction.bri != null && newGroupAction.bri > 0) {
+        Integer bri = newGroupAction.bri;
+        if (bri != null && bri > 0) {
             newGroupAction.on = true;
         }
 
index 6ba83ec2b755267b94fe8678230525db0b17f6f5..1e79bcaf4005f71da0b843327eff48c184d93186 100644 (file)
@@ -228,16 +228,17 @@ public class LightThingHandler extends DeconzBaseThingHandler<LightMessage> {
                 return;
         }
 
-        if (newLightState.on != null && !newLightState.on) {
+        Boolean newOn = newLightState.on;
+        if (newOn != null && !newOn) {
             // if light shall be off, no other commands are allowed, so reset the new light state
             newLightState.clear();
             newLightState.on = false;
         }
 
         sendCommand(newLightState, command, channelUID, () -> {
+            Integer transitionTime = newLightState.transitiontime;
             lastCommandExpireTimestamp = System.currentTimeMillis()
-                    + (newLightState.transitiontime != null ? newLightState.transitiontime
-                            : DEFAULT_COMMAND_EXPIRY_TIME);
+                    + (transitionTime != null ? transitionTime : DEFAULT_COMMAND_EXPIRY_TIME);
             lastCommand = newLightState;
         });
     }
@@ -248,16 +249,18 @@ public class LightThingHandler extends DeconzBaseThingHandler<LightMessage> {
             return null;
         } else if (r.getResponseCode() == 200) {
             LightMessage lightMessage = gson.fromJson(r.getBody(), LightMessage.class);
-            if (lightMessage != null && needsPropertyUpdate) {
+            if (needsPropertyUpdate) {
                 // if we did not receive an ctmin/ctmax, then we probably don't need it
                 needsPropertyUpdate = false;
 
-                if (lightMessage.ctmin != null && lightMessage.ctmax != null) {
+                Integer ctmax = lightMessage.ctmax;
+                Integer ctmin = lightMessage.ctmin;
+                if (ctmin != null && ctmax != null) {
                     Map<String, String> properties = new HashMap<>(thing.getProperties());
                     properties.put(PROPERTY_CT_MAX,
-                            Integer.toString(Util.constrainToRange(lightMessage.ctmax, ZCL_CT_MIN, ZCL_CT_MAX)));
+                            Integer.toString(Util.constrainToRange(ctmax, ZCL_CT_MIN, ZCL_CT_MAX)));
                     properties.put(PROPERTY_CT_MIN,
-                            Integer.toString(Util.constrainToRange(lightMessage.ctmin, ZCL_CT_MIN, ZCL_CT_MAX)));
+                            Integer.toString(Util.constrainToRange(ctmin, ZCL_CT_MIN, ZCL_CT_MAX)));
                     updateProperties(properties);
                 }
             }
@@ -278,6 +281,8 @@ public class LightThingHandler extends DeconzBaseThingHandler<LightMessage> {
 
     private void valueUpdated(String channelId, LightState newState) {
         Integer bri = newState.bri;
+        Integer hue = newState.hue;
+        Integer sat = newState.sat;
         Boolean on = newState.on;
 
         switch (channelId) {
@@ -292,15 +297,13 @@ public class LightThingHandler extends DeconzBaseThingHandler<LightMessage> {
             case CHANNEL_COLOR:
                 if (on != null && on == false) {
                     updateState(channelId, OnOffType.OFF);
-                } else if (bri != null && newState.colormode != null && newState.colormode.equals("xy")) {
+                } else if (bri != null && "xy".equals(newState.colormode)) {
                     final double @Nullable [] xy = newState.xy;
                     if (xy != null && xy.length == 2) {
                         HSBType color = HSBType.fromXY((float) xy[0], (float) xy[1]);
                         updateState(channelId, new HSBType(color.getHue(), color.getSaturation(), toPercentType(bri)));
                     }
-                } else if (bri != null && newState.hue != null && newState.sat != null) {
-                    final Integer hue = newState.hue;
-                    final Integer sat = newState.sat;
+                } else if (bri != null && hue != null && sat != null) {
                     updateState(channelId,
                             new HSBType(new DecimalType(hue / HUE_FACTOR), toPercentType(sat), toPercentType(bri)));
                 }
@@ -340,7 +343,7 @@ public class LightThingHandler extends DeconzBaseThingHandler<LightMessage> {
                     return;
                 }
                 lightStateCache = lightState;
-                if (lightState.reachable != null && lightState.reachable) {
+                if (Boolean.TRUE.equals(lightState.reachable)) {
                     updateStatus(ThingStatus.ONLINE);
                     thing.getChannels().stream().map(c -> c.getUID().getId()).forEach(c -> valueUpdated(c, lightState));
                 } else {
index 9f9ff4284f3f395124d570a78f02261aad35b3d1..d21b60a9b502608f148524b6dfe65529aa85542f 100644 (file)
@@ -164,23 +164,31 @@ public abstract class SensorBaseThingHandler extends DeconzBaseThingHandler<Sens
         // "Last seen" is the last "ping" from the device, whereas "last update" is the last status changed.
         // For example, for a fire sensor, the device pings regularly, without necessarily updating channels.
         // So to monitor a sensor is still alive, the "last seen" is necessary.
+        // Because "last seen" is never updated by the WebSocket API - if this is supported, then we have to
+        // manually poll it after the defined time
         String lastSeen = stateResponse.lastseen;
         if (lastSeen != null && config.lastSeenPolling > 0) {
             createChannel(CHANNEL_LAST_SEEN, ChannelKind.STATE);
             updateState(CHANNEL_LAST_SEEN, Util.convertTimestampToDateTime(lastSeen));
-            // Because "last seen" is never updated by the WebSocket API - if this is supported, then we have to
-            // manually poll it after the defined time (default is off)
-            if (config.lastSeenPolling > 0) {
-                lastSeenPollingJob = scheduler.schedule((Runnable) this::requestState, config.lastSeenPolling,
-                        TimeUnit.MINUTES);
-                logger.trace("lastSeen polling enabled for thing {} with interval of {} minutes", thing.getUID(),
-                        config.lastSeenPolling);
-            }
+            lastSeenPollingJob = scheduler.schedule(() -> requestState(this::processLastSeen), config.lastSeenPolling,
+                    TimeUnit.MINUTES);
+            logger.trace("lastSeen polling enabled for thing {} with interval of {} minutes", thing.getUID(),
+                    config.lastSeenPolling);
         }
 
         updateStatus(ThingStatus.ONLINE);
     }
 
+    private void processLastSeen(@Nullable SensorMessage stateResponse) {
+        if (stateResponse == null) {
+            return;
+        }
+        String lastSeen = stateResponse.lastseen;
+        if (lastSeen != null) {
+            updateState(CHANNEL_LAST_SEEN, Util.convertTimestampToDateTime(lastSeen));
+        }
+    }
+
     protected void createChannel(String channelId, ChannelKind kind) {
         ThingHandlerCallback callback = getCallback();
         if (callback != null) {
index ee4ace7a8c36ce284a9699a2fe91dbda512c2dec..13862fd514792a30e91736413ca3e30f749380c5 100644 (file)
@@ -22,6 +22,8 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
+import javax.measure.quantity.Temperature;
+
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.deconz.internal.dto.SensorConfig;
@@ -125,7 +127,8 @@ public class SensorThermostatThingHandler extends SensorBaseThingHandler {
     @Override
     protected void valueUpdated(ChannelUID channelUID, SensorConfig newConfig) {
         super.valueUpdated(channelUID, newConfig);
-        String mode = newConfig.mode != null ? newConfig.mode.name() : ThermostatMode.UNKNOWN.name();
+        ThermostatMode thermostatMode = newConfig.mode;
+        String mode = thermostatMode != null ? thermostatMode.name() : ThermostatMode.UNKNOWN.name();
         String channelID = channelUID.getId();
         switch (channelID) {
             case CHANNEL_HEATSETPOINT:
@@ -135,9 +138,7 @@ public class SensorThermostatThingHandler extends SensorBaseThingHandler {
                 updateQuantityTypeChannel(channelID, newConfig.offset, CELSIUS, 1.0 / 100);
                 break;
             case CHANNEL_THERMOSTAT_MODE:
-                if (mode != null) {
-                    updateState(channelUID, new StringType(mode));
-                }
+                updateState(channelUID, new StringType(mode));
                 break;
         }
     }
@@ -169,7 +170,13 @@ public class SensorThermostatThingHandler extends SensorBaseThingHandler {
         if (command instanceof DecimalType) {
             newTemperature = ((DecimalType) command).toBigDecimal();
         } else if (command instanceof QuantityType) {
-            newTemperature = ((QuantityType) command).toUnit(CELSIUS).toBigDecimal();
+            @SuppressWarnings("unchecked")
+            QuantityType<Temperature> temperatureCelsius = ((QuantityType<Temperature>) command).toUnit(CELSIUS);
+            if (temperatureCelsius != null) {
+                newTemperature = temperatureCelsius.toBigDecimal();
+            } else {
+                return null;
+            }
         } else {
             return null;
         }
index 21217ed21f1b4930c1f80b9f6c4d95914bcba277..a36e6663fa7e56b93de2c77f0fb7739c2e7fb9c9 100644 (file)
@@ -34,8 +34,6 @@ import org.openhab.core.thing.ThingTypeUID;
 import org.openhab.core.thing.type.ChannelKind;
 import org.openhab.core.types.Command;
 import org.openhab.core.types.RefreshType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.gson.Gson;
 
@@ -65,8 +63,6 @@ public class SensorThingHandler extends SensorBaseThingHandler {
     private static final List<String> CONFIG_CHANNELS = Arrays.asList(CHANNEL_BATTERY_LEVEL, CHANNEL_BATTERY_LOW,
             CHANNEL_TEMPERATURE);
 
-    private final Logger logger = LoggerFactory.getLogger(SensorThingHandler.class);
-
     public SensorThingHandler(Thing thing, Gson gson) {
         super(thing, gson);
     }
index 92d2915666f572ff4ce10d7bea06bd2992f625a6..a43e07577901f94bc39ffe530e2b9f89f37df985 100644 (file)
@@ -23,6 +23,6 @@ import org.eclipse.jdt.annotation.Nullable;
 @NonNullByDefault
 public class ThingConfig {
     public String id = "";
-    public int lastSeenPolling = 0;
+    public int lastSeenPolling = 1440;
     public @Nullable Double transitiontime;
 }
index 0ab34e1c0d7c06e5ec2482259aa34aae91d49225..132f255a4b43e7c2676d39bf080e05ddc33aa756 100644 (file)
@@ -42,8 +42,8 @@
                <parameter name="lastSeenPolling" type="integer" min="0" unit="min">
                        <label>LastSeen Poll Interval</label>
                        <description>Interval to poll the deCONZ Gateway for this sensor's "lastSeen" channel. Polling is disabled when set
-                               to 0.</description>
-                       <default>0</default>
+                               to 1440 (once per day).</description>
+                       <default>1440</default>
                </parameter>
        </config-description>