diff --git a/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/SensorBaseThingHandler.java b/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/SensorBaseThingHandler.java index 275eec94f..b5891dbfe 100644 --- a/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/SensorBaseThingHandler.java +++ b/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/SensorBaseThingHandler.java @@ -16,6 +16,7 @@ import static org.openhab.binding.deconz.internal.BindingConstants.*; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -111,10 +112,8 @@ public abstract class SensorBaseThingHandler extends DeconzBaseThingHandler { } SensorMessage sensorMessage = (SensorMessage) stateResponse; - SensorConfig newSensorConfig = sensorMessage.config; - sensorConfig = newSensorConfig != null ? newSensorConfig : new SensorConfig(); - SensorState newSensorState = sensorMessage.state; - sensorState = newSensorState != null ? newSensorState : new SensorState(); + sensorConfig = Objects.requireNonNullElse(sensorMessage.config, new SensorConfig()); + sensorState = Objects.requireNonNullElse(sensorMessage.state, new SensorState()); // Add some information about the sensor if (!sensorConfig.reachable) { @@ -146,10 +145,6 @@ public abstract class SensorBaseThingHandler extends DeconzBaseThingHandler { ignoreConfigurationUpdate = false; - // Initial data - updateChannels(sensorConfig); - updateChannels(sensorState, true); - // "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. @@ -165,6 +160,10 @@ public abstract class SensorBaseThingHandler extends DeconzBaseThingHandler { config.lastSeenPolling); } + // Initial data + updateChannels(sensorConfig); + updateChannels(sensorState, true); + updateStatus(ThingStatus.ONLINE); } @@ -176,6 +175,11 @@ public abstract class SensorBaseThingHandler extends DeconzBaseThingHandler { } protected void createChannel(String channelId, ChannelKind kind) { + if (thing.getChannel(channelId) != null) { + // channel already exists, no update necessary + return; + } + ThingHandlerCallback callback = getCallback(); if (callback != null) { ChannelUID channelUID = new ChannelUID(thing.getUID(), channelId); @@ -192,7 +196,7 @@ public abstract class SensorBaseThingHandler extends DeconzBaseThingHandler { break; } Channel channel = callback.createChannelBuilder(channelUID, channelTypeUID).withKind(kind).build(); - updateThing(editThing().withoutChannel(channelUID).withChannel(channel).build()); + updateThing(editThing().withChannel(channel).build()); } } diff --git a/bundles/org.openhab.binding.deconz/src/test/java/org/openhab/binding/deconz/SensorsTest.java b/bundles/org.openhab.binding.deconz/src/test/java/org/openhab/binding/deconz/SensorsTest.java index d850220fe..47cfa80fe 100644 --- a/bundles/org.openhab.binding.deconz/src/test/java/org/openhab/binding/deconz/SensorsTest.java +++ b/bundles/org.openhab.binding.deconz/src/test/java/org/openhab/binding/deconz/SensorsTest.java @@ -32,6 +32,7 @@ import org.openhab.binding.deconz.internal.types.LightType; import org.openhab.binding.deconz.internal.types.LightTypeDeserializer; import org.openhab.binding.deconz.internal.types.ThermostatMode; import org.openhab.binding.deconz.internal.types.ThermostatModeGsonTypeAdapter; +import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; @@ -112,4 +113,29 @@ public class SensorsTest { Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelTemperatureUID), eq(new QuantityType<>(16.5, SIUnits.CELSIUS))); } + + @Test + public void fireSensorUpdateTest() throws IOException { + SensorMessage sensorMessage = DeconzTest.getObjectFromJson("fire.json", SensorMessage.class, gson); + assertNotNull(sensorMessage); + + ThingUID thingUID = new ThingUID("deconz", "sensor"); + ChannelUID channelBatteryLevelUID = new ChannelUID(thingUID, CHANNEL_BATTERY_LEVEL); + ChannelUID channelFireUID = new ChannelUID(thingUID, CHANNEL_FIRE); + ChannelUID channelTamperedUID = new ChannelUID(thingUID, CHANNEL_TAMPERED); + ChannelUID channelLastSeenUID = new ChannelUID(thingUID, CHANNEL_LAST_SEEN); + + Thing sensor = ThingBuilder.create(THING_TYPE_FIRE_SENSOR, thingUID) + .withChannel(ChannelBuilder.create(channelBatteryLevelUID, "Number").build()) + .withChannel(ChannelBuilder.create(channelFireUID, "Switch").build()) + .withChannel(ChannelBuilder.create(channelTamperedUID, "Switch").build()) + .withChannel(ChannelBuilder.create(channelLastSeenUID, "DateTime").build()).build(); + SensorThingHandler sensorThingHandler = new SensorThingHandler(sensor, gson); + sensorThingHandler.setCallback(thingHandlerCallback); + + sensorThingHandler.messageReceived("", sensorMessage); + + Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelFireUID), eq(OnOffType.OFF)); + Mockito.verify(thingHandlerCallback).stateUpdated(eq(channelBatteryLevelUID), eq(new DecimalType(98))); + } } diff --git a/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/fire.json b/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/fire.json new file mode 100644 index 000000000..81ce08b18 --- /dev/null +++ b/bundles/org.openhab.binding.deconz/src/test/resources/org/openhab/binding/deconz/fire.json @@ -0,0 +1,23 @@ +{ + "config": { + "battery": 98, + "on": true, + "pending" : [], + "reachable": false + }, + "ep": 1, + "etag": "717549a99371f3ea1a5f0b40f1537094", + "lastseen": null, + "manufacturername": "Heimann", + "modelid": "SMOK_YDLV10", + "name": "Smoke Sensor", + "state": { + "fire": false, + "lastupdated": "none", + "lowbattery": null, + "tampered": null + }, + "swversion": "20150330", + "type": "ZHAFire", + "uniqueid": "00:15:8d:00:01:ff:8a:09-01-0500" +} \ No newline at end of file