[hue] Add support for Geofence sensor (#8731)

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
Christoph Weitkamp 2020-10-14 19:05:20 +02:00 committed by GitHub
parent bef1046258
commit b9beaad5cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 164 additions and 45 deletions

View File

@ -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
}

View File

@ -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");

View File

@ -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<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.unmodifiableSet(
Stream.of(HueBridgeHandler.SUPPORTED_THING_TYPES.stream(), HueLightHandler.SUPPORTED_THING_TYPES.stream(),
public static final Set<ThingTypeUID> 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())) {

View File

@ -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<ThingTypeUID> 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()));

View File

@ -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<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_GEOFENCE_SENSOR);
public GeofencePresenceHandler(Thing thing) {
super(thing);
}
@Override
protected SensorConfigUpdate doConfigurationUpdate(Map<String, Object> 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);
}
}
}

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<config-description:config-descriptions
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0 https://openhab.org/schemas/config-description-1.0.0.xsd">
<config-description uri="thing-type:hue:presencesensor">
<parameter name="sensorId" type="text">
<label>Sensor ID</label>
<description>The identifier that is used within the hue bridge.</description>
<required>true</required>
</parameter>
<parameter name="on" type="boolean">
<label>Sensor Status</label>
<description>Enables or disables the sensor.</description>
</parameter>
<parameter name="ledindication" type="boolean">
<label>LED Indication</label>
<description>Turns device LED during normal operation on or off. Devices might still indicate exceptional operation
(Reset, SW Update, Battery Low).</description>
</parameter>
<parameter name="sensitivity" type="integer" min="0" step="1">
<label>Sensitivity</label>
<description>The current sensitivity of the presence sensor. Cannot exceed maximum sensitivity.</description>
</parameter>
<parameter name="sensitivitymax" type="integer" readOnly="true">
<label>Maximum Sensitivity</label>
<description>The maximum sensitivity of the presence sensor.</description>
</parameter>
</config-description>
<config-description uri="thing-type:hue:geofecnesensor">
<parameter name="sensorId" type="text">
<label>Sensor ID</label>
<description>The identifier that is used within the hue bridge.</description>
<required>true</required>
</parameter>
<parameter name="on" type="boolean">
<label>Sensor Status</label>
<description>Enables or disables the sensor.</description>
</parameter>
</config-description>
</config-description:config-descriptions>

View File

@ -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

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="hue" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
<!-- Geofence Sensor -->
<thing-type id="geofencesensor">
<supported-bridge-type-refs>
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Geofence Sensor</label>
<description>A sensor providing geofence based presence detection.</description>
<channels>
<channel id="presence" typeId="system.motion"/>
<channel id="last_updated" typeId="last_updated"/>
</channels>
<representation-property>uniqueId</representation-property>
<config-description-ref uri="thing-type:hue:geofencesensor"/>
</thing-type>
</thing:thing-descriptions>

View File

@ -9,7 +9,7 @@
<bridge-type-ref id="bridge"/>
</supported-bridge-type-refs>
<label>Hue Presence Sensor</label>
<label>Presence Sensor</label>
<description>A motion sensor providing presence detection.</description>
<channels>
@ -21,29 +21,6 @@
<representation-property>uniqueId</representation-property>
<config-description>
<parameter name="sensorId" type="text">
<label>Sensor ID</label>
<description>The identifier that is used within the hue bridge.</description>
<required>true</required>
</parameter>
<parameter name="on" type="boolean">
<label>Sensor Status</label>
<description>Enables or disables the sensor.</description>
</parameter>
<parameter name="ledindication" type="boolean">
<label>LED Indication</label>
<description>Turns device LED during normal operation on or off. Devices might still indicate exceptional operation
(Reset, SW Update, Battery Low).</description>
</parameter>
<parameter name="sensitivity" type="integer" min="0" step="1">
<label>Sensitivity</label>
<description>The current sensitivity of the presence sensor. Cannot exceed maximum sensitivity.</description>
</parameter>
<parameter name="sensitivitymax" type="integer" readOnly="true">
<label>Maximum Sensitivity</label>
<description>The maximum sensitivity of the presence sensor.</description>
</parameter>
</config-description>
<config-description-ref uri="thing-type:hue:presencesensor"/>
</thing-type>
</thing:thing-descriptions>