From b9beaad5cd35658922e2b1a4cad70a2de05a3a22 Mon Sep 17 00:00:00 2001 From: Christoph Weitkamp Date: Wed, 14 Oct 2020 19:05:20 +0200 Subject: [PATCH] [hue] Add support for Geofence sensor (#8731) Signed-off-by: Christoph Weitkamp --- bundles/org.openhab.binding.hue/README.md | 31 +++++----- .../hue/internal/HueBindingConstants.java | 1 + .../hue/internal/HueThingHandlerFactory.java | 16 ++++-- .../discovery/HueLightDiscoveryService.java | 3 + .../sensors/GeofencePresenceHandler.java | 57 +++++++++++++++++++ .../main/resources/OH-INF/config/config.xml | 44 ++++++++++++++ .../resources/OH-INF/i18n/hue_de.properties | 6 ++ .../resources/OH-INF/thing/GeofenceSensor.xml | 24 ++++++++ .../resources/OH-INF/thing/PresenceSensor.xml | 27 +-------- 9 files changed, 164 insertions(+), 45 deletions(-) create mode 100644 bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/sensors/GeofencePresenceHandler.java create mode 100644 bundles/org.openhab.binding.hue/src/main/resources/OH-INF/config/config.xml create mode 100644 bundles/org.openhab.binding.hue/src/main/resources/OH-INF/thing/GeofenceSensor.xml diff --git a/bundles/org.openhab.binding.hue/README.md b/bundles/org.openhab.binding.hue/README.md index a878f486c28..5580dca06ae 100644 --- a/bundles/org.openhab.binding.hue/README.md +++ b/bundles/org.openhab.binding.hue/README.md @@ -9,8 +9,8 @@ The integration happens through the Hue bridge, which acts as an IP gateway to t The Hue bridge is required as a "bridge" for accessing any other Hue device. It supports the ZigBee LightLink protocol as well as the upwards compatible ZigBee 3.0 protocol. -There are two types of Hue bridges, generally refered to as v1 (the rounded version) and v2 (the squared version). -Only noticable difference between the two generation of bridges is the added support for Apple HomeKit in v2. +There are two types of Hue bridges, generally referred to as v1 (the rounded version) and v2 (the squared version). +Only noticeable difference between the two generation of bridges is the added support for Apple HomeKit in v2. Both bridges are fully supported by this binding. Almost all available Hue devices are supported by this binding. @@ -52,19 +52,20 @@ The Hue Motion Sensor registers a `ZLLLightLevel` sensor (0106), a `ZLLPresence` The Hue CLIP Sensor saves scene states with status or flag for HUE rules. They are presented by the following ZigBee Device ID and _Thing type_: -| Device type | ZigBee Device ID | Thing type | -|-----------------------------|------------------|------------| -| Light Sensor | 0x0106 | 0106 | -| Occupancy Sensor | 0x0107 | 0107 | -| Temperature Sensor | 0x0302 | 0302 | -| Non-Colour Controller | 0x0820 | 0820 | -| Non-Colour Scene Controller | 0x0830 | 0830 | -| CLIP Generic Status Sensor | 0x0840 | 0840 | -| CLIP Generic Flag Sensor | 0x0850 | 0850 | +| Device type | ZigBee Device ID | Thing type | +|-----------------------------|------------------|----------------| +| Light Sensor | 0x0106 | 0106 | +| Occupancy Sensor | 0x0107 | 0107 | +| Temperature Sensor | 0x0302 | 0302 | +| Non-Colour Controller | 0x0820 | 0820 | +| Non-Colour Scene Controller | 0x0830 | 0830 | +| CLIP Generic Status Sensor | 0x0840 | 0840 | +| CLIP Generic Flag Sensor | 0x0850 | 0850 | +| Geofence Sensor | | geofencesensor | The Hue Dimmer Switch has 4 buttons and registers as a Non-Colour Controller switch, while the Hue Tap (also 4 buttons) registers as a Non-Colour Scene Controller in accordance with the ZLL standard. -Also, Hue bridge support CLIP Generic Status Sensor and CLIP Generic Flag Sensor. These sensors save state for rules and calculate what actions to do. CLIP Sensor set or get by json through IP. +Also, Hue bridge support CLIP Generic Status Sensor and CLIP Generic Flag Sensor. These sensors save state for rules and calculate what actions to do. CLIP Sensor set or get by JSON through IP. The type of a specific device can be found in the configuration section for things in the PaperUI. It is part of the unique thing id which could look like: @@ -234,14 +235,14 @@ The `tap_switch_event` can trigger one of the following events: This binding includes a rule action, which allows to change a light channel with a specific fading time from within rules. There is a separate instance for each light, which can be retrieved e.g. through -``` +```php val hueActions = getActions("hue","hue:0210:00178810d0dc:1") ``` where the first parameter always has to be `hue` and the second is the full Thing UID of the light that should be used. Once this action instance is retrieved, you can invoke the `fadingLightCommand(String channel, Command command, DecimalType fadeTime)` method on it: -``` +```php hueActions.fadingLightCommand("color", new PercentType(100), new DecimalType(1000)) ``` @@ -366,7 +367,7 @@ If ommited the rule gets triggered by any key action and you can determine the e Be aware that the events have a '.0' attached to them, like `2001.0` or `34.0`. So, testing for specific events looks like this: -``` +```php if (receivedEvent.getEvent() == "1000.0")) { //do stuff } diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueBindingConstants.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueBindingConstants.java index ee73ea2d92f..1e3f23eae00 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueBindingConstants.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueBindingConstants.java @@ -50,6 +50,7 @@ public class HueBindingConstants { public static final ThingTypeUID THING_TYPE_CLIP_GENERIC_STATUS = new ThingTypeUID(BINDING_ID, "0840"); public static final ThingTypeUID THING_TYPE_CLIP_GENERIC_FLAG = new ThingTypeUID(BINDING_ID, "0850"); public static final ThingTypeUID THING_TYPE_PRESENCE_SENSOR = new ThingTypeUID(BINDING_ID, "0107"); + public static final ThingTypeUID THING_TYPE_GEOFENCE_SENSOR = new ThingTypeUID(BINDING_ID, "geofencesensor"); public static final ThingTypeUID THING_TYPE_TEMPERATURE_SENSOR = new ThingTypeUID(BINDING_ID, "0302"); public static final ThingTypeUID THING_TYPE_LIGHT_LEVEL_SENSOR = new ThingTypeUID(BINDING_ID, "0106"); diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueThingHandlerFactory.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueThingHandlerFactory.java index cc6940c3380..21fdc431ebe 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueThingHandlerFactory.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueThingHandlerFactory.java @@ -31,6 +31,7 @@ import org.openhab.binding.hue.internal.handler.HueLightHandler; import org.openhab.binding.hue.internal.handler.HueStateDescriptionOptionProvider; import org.openhab.binding.hue.internal.handler.sensors.ClipHandler; import org.openhab.binding.hue.internal.handler.sensors.DimmerSwitchHandler; +import org.openhab.binding.hue.internal.handler.sensors.GeofencePresenceHandler; import org.openhab.binding.hue.internal.handler.sensors.LightLevelHandler; import org.openhab.binding.hue.internal.handler.sensors.PresenceHandler; import org.openhab.binding.hue.internal.handler.sensors.TapSwitchHandler; @@ -63,12 +64,14 @@ import org.osgi.service.component.annotations.Reference; @Component(service = ThingHandlerFactory.class, configurationPid = "binding.hue") public class HueThingHandlerFactory extends BaseThingHandlerFactory { - public static final Set SUPPORTED_THING_TYPES = Collections.unmodifiableSet( - Stream.of(HueBridgeHandler.SUPPORTED_THING_TYPES.stream(), HueLightHandler.SUPPORTED_THING_TYPES.stream(), + public static final Set SUPPORTED_THING_TYPES = Collections.unmodifiableSet(Stream + .of(HueBridgeHandler.SUPPORTED_THING_TYPES.stream(), HueLightHandler.SUPPORTED_THING_TYPES.stream(), DimmerSwitchHandler.SUPPORTED_THING_TYPES.stream(), TapSwitchHandler.SUPPORTED_THING_TYPES.stream(), - PresenceHandler.SUPPORTED_THING_TYPES.stream(), TemperatureHandler.SUPPORTED_THING_TYPES.stream(), - LightLevelHandler.SUPPORTED_THING_TYPES.stream(), ClipHandler.SUPPORTED_THING_TYPES.stream(), - HueGroupHandler.SUPPORTED_THING_TYPES.stream()).flatMap(i -> i).collect(Collectors.toSet())); + PresenceHandler.SUPPORTED_THING_TYPES.stream(), + GeofencePresenceHandler.SUPPORTED_THING_TYPES.stream(), + TemperatureHandler.SUPPORTED_THING_TYPES.stream(), LightLevelHandler.SUPPORTED_THING_TYPES.stream(), + ClipHandler.SUPPORTED_THING_TYPES.stream(), HueGroupHandler.SUPPORTED_THING_TYPES.stream()) + .flatMap(i -> i).collect(Collectors.toSet())); private final HueStateDescriptionOptionProvider stateOptionProvider; @@ -90,6 +93,7 @@ public class HueThingHandlerFactory extends BaseThingHandlerFactory { } else if (DimmerSwitchHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID) || TapSwitchHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID) || PresenceHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID) + || GeofencePresenceHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID) || TemperatureHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID) || LightLevelHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID) || ClipHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) { @@ -157,6 +161,8 @@ public class HueThingHandlerFactory extends BaseThingHandlerFactory { return new TapSwitchHandler(thing); } else if (PresenceHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) { return new PresenceHandler(thing); + } else if (GeofencePresenceHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) { + return new GeofencePresenceHandler(thing); } else if (TemperatureHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) { return new TemperatureHandler(thing); } else if (LightLevelHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) { diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/discovery/HueLightDiscoveryService.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/discovery/HueLightDiscoveryService.java index f83fc78eec1..7d301df4c85 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/discovery/HueLightDiscoveryService.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/discovery/HueLightDiscoveryService.java @@ -35,6 +35,7 @@ import org.openhab.binding.hue.internal.handler.HueGroupHandler; import org.openhab.binding.hue.internal.handler.HueLightHandler; import org.openhab.binding.hue.internal.handler.sensors.ClipHandler; import org.openhab.binding.hue.internal.handler.sensors.DimmerSwitchHandler; +import org.openhab.binding.hue.internal.handler.sensors.GeofencePresenceHandler; import org.openhab.binding.hue.internal.handler.sensors.LightLevelHandler; import org.openhab.binding.hue.internal.handler.sensors.PresenceHandler; import org.openhab.binding.hue.internal.handler.sensors.TapSwitchHandler; @@ -67,6 +68,7 @@ public class HueLightDiscoveryService extends AbstractDiscoveryService { public static final Set SUPPORTED_THING_TYPES = Collections.unmodifiableSet(Stream .of(HueLightHandler.SUPPORTED_THING_TYPES.stream(), DimmerSwitchHandler.SUPPORTED_THING_TYPES.stream(), TapSwitchHandler.SUPPORTED_THING_TYPES.stream(), PresenceHandler.SUPPORTED_THING_TYPES.stream(), + GeofencePresenceHandler.SUPPORTED_THING_TYPES.stream(), TemperatureHandler.SUPPORTED_THING_TYPES.stream(), LightLevelHandler.SUPPORTED_THING_TYPES.stream(), ClipHandler.SUPPORTED_THING_TYPES.stream(), HueGroupHandler.SUPPORTED_THING_TYPES.stream()) .flatMap(i -> i).collect(Collectors.toSet())); @@ -89,6 +91,7 @@ public class HueLightDiscoveryService extends AbstractDiscoveryService { new SimpleEntry<>("clipgenericstatus", "0840"), new SimpleEntry<>("clipgenericflag", "0850"), new SimpleEntry<>("zllpresence", "0107"), + new SimpleEntry<>("geofence", "0107"), new SimpleEntry<>("zlltemperature", "0302"), new SimpleEntry<>("zlllightlevel", "0106") ).collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue())); diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/sensors/GeofencePresenceHandler.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/sensors/GeofencePresenceHandler.java new file mode 100644 index 00000000000..5de121485d7 --- /dev/null +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/sensors/GeofencePresenceHandler.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2010-2020 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.hue.internal.handler.sensors; + +import static org.openhab.binding.hue.internal.FullSensor.STATE_PRESENCE; +import static org.openhab.binding.hue.internal.HueBindingConstants.*; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.hue.internal.FullSensor; +import org.openhab.binding.hue.internal.SensorConfigUpdate; +import org.openhab.binding.hue.internal.handler.HueSensorHandler; +import org.openhab.core.config.core.Configuration; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.thing.Thing; +import org.openhab.core.thing.ThingTypeUID; + +/** + * Geofence Presence Sensor + * + * @author Christoph Weitkamp - Initial contribution + */ +@NonNullByDefault +public class GeofencePresenceHandler extends HueSensorHandler { + public static final Set SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_GEOFENCE_SENSOR); + + public GeofencePresenceHandler(Thing thing) { + super(thing); + } + + @Override + protected SensorConfigUpdate doConfigurationUpdate(Map configurationParameters) { + return new SensorConfigUpdate(); + } + + @Override + protected void doSensorStateChanged(FullSensor sensor, Configuration config) { + Object presence = sensor.getState().get(STATE_PRESENCE); + if (presence != null) { + boolean value = Boolean.parseBoolean(String.valueOf(presence)); + updateState(CHANNEL_PRESENCE, value ? OnOffType.ON : OnOffType.OFF); + } + } +} diff --git a/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/config/config.xml new file mode 100644 index 00000000000..c41e388f3cb --- /dev/null +++ b/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/config/config.xml @@ -0,0 +1,44 @@ + + + + + + + The identifier that is used within the hue bridge. + true + + + + Enables or disables the sensor. + + + + Turns device LED during normal operation on or off. Devices might still indicate exceptional operation + (Reset, SW Update, Battery Low). + + + + The current sensitivity of the presence sensor. Cannot exceed maximum sensitivity. + + + + The maximum sensitivity of the presence sensor. + + + + + + + The identifier that is used within the hue bridge. + true + + + + Enables or disables the sensor. + + + + diff --git a/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/i18n/hue_de.properties b/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/i18n/hue_de.properties index 22f95d12888..2b74818df10 100644 --- a/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/i18n/hue_de.properties +++ b/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/i18n/hue_de.properties @@ -29,6 +29,8 @@ thing-type.hue.0107.label = Bewegungsmelder thing-type.hue.0107.description = Bewegungsmelder mit einstellbarer Sensitivität. thing-type.hue.0302.label = Temperatursensor thing-type.hue.0302.description = Temperatursensor +thing-type.hue.geofencesensor.label = Geofencing Sensor +thing-type.hue.geofencesensor.description = Ein Sensor zur Geofencing basierten Anwesenheitserkennung. # thing type configuration thing-type.config.hue.bridge.ipAddress.label = IP-Adresse @@ -90,6 +92,10 @@ thing-type.config.hue.0302.on.label = Sensor Status thing-type.config.hue.0302.on.description = Aktiviert oder deaktiviert den Sensor. thing-type.config.hue.0302.ledindication.label = LED-Anzeige thing-type.config.hue.0302.ledindication.description = Aktiviert oder deaktiviert die LED-Anzeige des Sensors. +thing-type.config.hue.geofencesensor.sensorId.label = ID des Sensors +thing-type.config.hue.geofencesensor.sensorId.description = ID zur Identifikation des Sensors. +thing-type.config.hue.geofencesensor.on.label = Sensor Status +thing-type.config.hue.geofencesensor.on.description = Aktiviert oder deaktiviert den Sensor. # channel types channel-type.hue.color.label = Farbe diff --git a/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/thing/GeofenceSensor.xml b/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/thing/GeofenceSensor.xml new file mode 100644 index 00000000000..02330d79559 --- /dev/null +++ b/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/thing/GeofenceSensor.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + A sensor providing geofence based presence detection. + + + + + + + uniqueId + + + + diff --git a/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/thing/PresenceSensor.xml b/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/thing/PresenceSensor.xml index d3f486f8ff2..d4790ff8c84 100644 --- a/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/thing/PresenceSensor.xml +++ b/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/thing/PresenceSensor.xml @@ -9,7 +9,7 @@ - + A motion sensor providing presence detection. @@ -21,29 +21,6 @@ uniqueId - - - - The identifier that is used within the hue bridge. - true - - - - Enables or disables the sensor. - - - - Turns device LED during normal operation on or off. Devices might still indicate exceptional operation - (Reset, SW Update, Battery Low). - - - - The current sensitivity of the presence sensor. Cannot exceed maximum sensitivity. - - - - The maximum sensitivity of the presence sensor. - - +