mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[hue] Support new home security products (#15601)
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
This commit is contained in:
parent
5555d68f92
commit
4f6d33bb79
@ -59,35 +59,40 @@ The configuration of all things (as described above) is the same regardless of w
|
||||
|
||||
Device things support some of the following channels:
|
||||
|
||||
| Channel ID | Item Type | Description |
|
||||
|---------------------------|--------------------|---------------------------------------------------------------------------------------------------------------------|
|
||||
| color | Color | Supports full color control with hue, saturation and brightness values, or brightness only, or switching on or off. |
|
||||
| brightness | Dimmer | Supports control of the brightness value, or switching on or off. |
|
||||
| color-temperature | Dimmer | Supports control of the color temperature in percent from cold (0%) to warm (100%). |
|
||||
| color-temperature-abs | Number:Temperature | Supports control of the color temperature via a QuantityType having a temperature unit e.g. Kelvin. (Advanced) |
|
||||
| switch | Switch | Supports switching the device on and off. |
|
||||
| dynamics | Number:Time | Sets the duration of dynamic transitions between light states. (Advanced) |
|
||||
| alert | String | Allows setting an alert on a light e.g. flashing them. (Advanced) |
|
||||
| effect | String | Allows setting an effect on a light e.g. 'candle' effect. (Advanced) |
|
||||
| button-last-event | (String) | Informs which button was last pressed in the device. (Trigger Channel) |
|
||||
| button-last-updated | DateTime | The date and time when a button was last pressed. (Read Only) (Advanced) |
|
||||
| rotary-steps | (String) | Informs about the number of rotary steps of the last rotary dial movement. (Trigger Channel) |
|
||||
| rotary-steps-last-updated | DateTime | The date and time when the rotary steps were last updated. (Read Only) (Advanced) |
|
||||
| motion | Switch | Shows if motion has been detected by the sensor. (Read Only) |
|
||||
| motion-enabled | Switch | Supports enabling / disabling the motion sensor. (Advanced) |
|
||||
| motion-last-updated | DateTime | The date and time when the motion value was last updated. (Read Only) (Advanced) |
|
||||
| light-level | Number:Illuminance | Shows the current light level measured by the sensor. (Read Only) |
|
||||
| light-level-last-updated | DateTime | The date and time when the light level was last updated. (Read Only) (Advanced) |
|
||||
| light-level-enabled | Switch | Supports enabling / disabling the light level sensor. (Advanced) |
|
||||
| temperature | Number:Temperature | Shows the current temperature measured by the sensor. (Read Only) |
|
||||
| temperature-last-updated | DateTime | The date and time when the temperature was last updated. (Read Only) (Advanced) |
|
||||
| temperature-enabled | Switch | Supports enabling / disabling the temperature sensor. (Advanced) |
|
||||
| battery-level | Number | Shows the battery level. (Read Only) |
|
||||
| battery-low | Switch | Indicates whether the battery is low or not. (Read Only) |
|
||||
| last-updated | DateTime | The date and time when the thing state was last updated. (Read Only) (Advanced) |
|
||||
| color-xy-only | Color | Allows access to the `color-xy` parameter of the light(s) only. Has no impact on `dimming` or `on-off` parameters. |
|
||||
| dimming-only | Dimmer | Allows access to the `dimming` parameter of the light(s) only. Has no impact on `color-xy` or `on-off` parameters. |
|
||||
| on-off-only | Switch | Allows access to the `on-off` parameter of the light(s) only. Has no impact on `color-xy` or `dimming` parameters. |
|
||||
| Channel ID | Item Type | Description |
|
||||
|-------------------------------|--------------------|---------------------------------------------------------------------------------------------------------------------|
|
||||
| color | Color | Supports full color control with hue, saturation and brightness values, or brightness only, or switching on or off. |
|
||||
| brightness | Dimmer | Supports control of the brightness value, or switching on or off. |
|
||||
| color-temperature | Dimmer | Supports control of the color temperature in percent from cold (0%) to warm (100%). |
|
||||
| color-temperature-abs | Number:Temperature | Supports control of the color temperature via a QuantityType having a temperature unit e.g. Kelvin. (Advanced) |
|
||||
| switch | Switch | Supports switching the device on and off. |
|
||||
| dynamics | Number:Time | Sets the duration of dynamic transitions between light states. (Advanced) |
|
||||
| alert | String | Allows setting an alert on a light e.g. flashing them. (Advanced) |
|
||||
| effect | String | Allows setting an effect on a light e.g. 'candle' effect. (Advanced) |
|
||||
| button-last-event | (String) | Informs which button was last pressed in the device. (Trigger Channel) |
|
||||
| button-last-updated | DateTime | The date and time when a button was last pressed. (Read Only) (Advanced) |
|
||||
| rotary-steps | (String) | Informs about the number of rotary steps of the last rotary dial movement. (Trigger Channel) |
|
||||
| rotary-steps-last-updated | DateTime | The date and time when the rotary steps were last updated. (Read Only) (Advanced) |
|
||||
| motion | Switch | Shows if motion has been detected by the sensor. (Read Only) |
|
||||
| motion-enabled | Switch | Supports enabling / disabling the motion sensor. (Advanced) |
|
||||
| motion-last-updated | DateTime | The date and time when the motion value was last updated. (Read Only) (Advanced) |
|
||||
| light-level | Number:Illuminance | Shows the current light level measured by the sensor. (Read Only) |
|
||||
| light-level-last-updated | DateTime | The date and time when the light level was last updated. (Read Only) (Advanced) |
|
||||
| light-level-enabled | Switch | Supports enabling / disabling the light level sensor. (Advanced) |
|
||||
| temperature | Number:Temperature | Shows the current temperature measured by the sensor. (Read Only) |
|
||||
| temperature-last-updated | DateTime | The date and time when the temperature was last updated. (Read Only) (Advanced) |
|
||||
| temperature-enabled | Switch | Supports enabling / disabling the temperature sensor. (Advanced) |
|
||||
| battery-level | Number | Shows the battery level. (Read Only) |
|
||||
| battery-low | Switch | Indicates whether the battery is low or not. (Read Only) |
|
||||
| last-updated | DateTime | The date and time when the thing state was last updated. (Read Only) (Advanced) |
|
||||
| color-xy-only | Color | Allows access to the `color-xy` parameter of the light(s) only. Has no impact on `dimming` or `on-off` parameters. |
|
||||
| dimming-only | Dimmer | Allows access to the `dimming` parameter of the light(s) only. Has no impact on `color-xy` or `on-off` parameters. |
|
||||
| on-off-only | Switch | Allows access to the `on-off` parameter of the light(s) only. Has no impact on `color-xy` or `dimming` parameters. |
|
||||
| security-contact | Contact | Indicates whether a security contact has been triggered. (Read Only) |
|
||||
| security-contact-enabled | Switch | Supports enabling / disabling the security contact. (Advanced) |
|
||||
| security-contact-last-updated | DateTime | The date and time when the security contact state was last updated. (Read Only) (Advanced) |
|
||||
| security-tamper | Contact | Indicates whether a security tamper contact has been triggered. `Open` means tampering detected. (Read Only) |
|
||||
| security-tamper-last-updated | DateTime | The date and time when the security tamper contact state was last updated. (Read Only) (Advanced) |
|
||||
|
||||
The exact list of channels in a given device is determined at run time when the system is started.
|
||||
Each device reports its own live list of capabilities, and the respective list of channels is created accordingly.
|
||||
|
@ -169,6 +169,11 @@ public class HueBindingConstants {
|
||||
public static final String CHANNEL_2_COLOR_XY_ONLY = "color-xy-only";
|
||||
public static final String CHANNEL_2_DIMMING_ONLY = "dimming-only";
|
||||
public static final String CHANNEL_2_ON_OFF_ONLY = "on-off-only";
|
||||
public static final String CHANNEL_2_SECURITY_CONTACT = "security-contact";
|
||||
public static final String CHANNEL_2_SECURITY_CONTACT_ENABLED = "security-contact-enabled";
|
||||
public static final String CHANNEL_2_SECURITY_CONTACT_LAST_UPDATED = "security-contact-last-updated";
|
||||
public static final String CHANNEL_2_SECURITY_TAMPER = "security-tamper";
|
||||
public static final String CHANNEL_2_SECURITY_TAMPER_LAST_UPDATED = "security-tamper-last-updated";
|
||||
|
||||
// channel IDs that (optionally) support dynamics
|
||||
public static final Set<String> DYNAMIC_CHANNELS = Set.of(CHANNEL_2_BRIGHTNESS, CHANNEL_2_COLOR,
|
||||
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 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.dto.clip2;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.ContactStateType;
|
||||
|
||||
/**
|
||||
* DTO for CLIP 2 home security alarm contact.
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ContactReport {
|
||||
|
||||
private @NonNullByDefault({}) Instant changed;
|
||||
private @NonNullByDefault({}) String state;
|
||||
|
||||
public ContactStateType getContactState() throws IllegalArgumentException {
|
||||
return ContactStateType.valueOf(state.toUpperCase());
|
||||
}
|
||||
|
||||
public Instant getLastChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
public ContactReport setLastChanged(Instant changed) {
|
||||
this.changed = changed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContactReport setContactState(String state) {
|
||||
this.state = state;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -28,17 +28,20 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.ActionType;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.ButtonEventType;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.ContactStateType;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.EffectType;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.SceneRecallAction;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.SmartSceneRecallAction;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.SmartSceneState;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.TamperStateType;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.ZigbeeStatus;
|
||||
import org.openhab.binding.hue.internal.exceptions.DTOPresentButEmptyException;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.HSBType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.OpenClosedType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
@ -103,6 +106,8 @@ public class Resource {
|
||||
private @Nullable List<ResourceReference> children;
|
||||
private @Nullable JsonElement status;
|
||||
private @Nullable @SuppressWarnings("unused") Dynamics dynamics;
|
||||
private @Nullable @SerializedName("contact_report") ContactReport contactReport;
|
||||
private @Nullable @SerializedName("tamper_reports") List<TamperReport> tamperReports;
|
||||
private @Nullable String state;
|
||||
|
||||
/**
|
||||
@ -325,6 +330,20 @@ public class Resource {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
|
||||
public State getContactLastUpdatedState(ZoneId zoneId) {
|
||||
ContactReport contactReport = this.contactReport;
|
||||
return Objects.nonNull(contactReport)
|
||||
? new DateTimeType(ZonedDateTime.ofInstant(contactReport.getLastChanged(), zoneId))
|
||||
: UnDefType.NULL;
|
||||
}
|
||||
|
||||
public State getContactState() {
|
||||
ContactReport contactReport = this.contactReport;
|
||||
return Objects.isNull(contactReport) ? UnDefType.NULL
|
||||
: ContactStateType.CONTACT == contactReport.getContactState() ? OpenClosedType.CLOSED
|
||||
: OpenClosedType.OPEN;
|
||||
}
|
||||
|
||||
public int getControlId() {
|
||||
MetaData metadata = this.metadata;
|
||||
return Objects.nonNull(metadata) ? metadata.getControlId() : 0;
|
||||
@ -649,6 +668,33 @@ public class Resource {
|
||||
return new JsonObject();
|
||||
}
|
||||
|
||||
public State getTamperLastUpdatedState(ZoneId zoneId) {
|
||||
TamperReport report = getTamperReportsLatest();
|
||||
return Objects.nonNull(report) ? new DateTimeType(ZonedDateTime.ofInstant(report.getLastChanged(), zoneId))
|
||||
: UnDefType.NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* The the Hue bridge could return its raw list of tamper reports in any order, so sort the list (latest entry
|
||||
* first) according to the respective 'changed' instant and return the first entry i.e. the latest changed entry.
|
||||
*
|
||||
* @return the latest changed tamper report
|
||||
*/
|
||||
private @Nullable TamperReport getTamperReportsLatest() {
|
||||
List<TamperReport> reports = this.tamperReports;
|
||||
return Objects.nonNull(reports)
|
||||
? reports.stream().sorted((e1, e2) -> e2.getLastChanged().compareTo(e1.getLastChanged())).findFirst()
|
||||
.orElse(null)
|
||||
: null;
|
||||
}
|
||||
|
||||
public State getTamperState() {
|
||||
TamperReport report = getTamperReportsLatest();
|
||||
return Objects.nonNull(report)
|
||||
? TamperStateType.TAMPERED == report.getTamperState() ? OpenClosedType.OPEN : OpenClosedType.CLOSED
|
||||
: UnDefType.NULL;
|
||||
}
|
||||
|
||||
public @Nullable Temperature getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
@ -736,6 +782,11 @@ public class Resource {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Resource setContactReport(ContactReport contactReport) {
|
||||
this.contactReport = contactReport;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Resource setDimming(Dimming dimming) {
|
||||
this.dimming = dimming;
|
||||
return this;
|
||||
@ -815,6 +866,11 @@ public class Resource {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Resource setTamperReports(List<TamperReport> tamperReports) {
|
||||
this.tamperReports = tamperReports;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Resource setTimedEffects(TimedEffects timedEffects) {
|
||||
this.timedEffects = timedEffects;
|
||||
return this;
|
||||
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 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.dto.clip2;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.TamperStateType;
|
||||
|
||||
/**
|
||||
* DTO for CLIP 2 home security tamper switch.
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class TamperReport {
|
||||
|
||||
private @NonNullByDefault({}) Instant changed;
|
||||
private @NonNullByDefault({}) String state;
|
||||
|
||||
public Instant getLastChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
public TamperStateType getTamperState() throws IllegalArgumentException {
|
||||
return TamperStateType.valueOf(state.toUpperCase());
|
||||
}
|
||||
|
||||
public TamperReport setLastChanged(Instant changed) {
|
||||
this.changed = changed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TamperReport setTamperState(String state) {
|
||||
this.state = state;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 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.dto.clip2.enums;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Enum for security contact states.
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum ContactStateType {
|
||||
NO_CONTACT,
|
||||
CONTACT
|
||||
}
|
@ -31,6 +31,8 @@ public enum ResourceType {
|
||||
BRIDGE,
|
||||
BRIDGE_HOME,
|
||||
BUTTON,
|
||||
CAMERA_MOTION,
|
||||
CONTACT,
|
||||
DEVICE,
|
||||
DEVICE_POWER,
|
||||
ENTERTAINMENT,
|
||||
@ -47,6 +49,7 @@ public enum ResourceType {
|
||||
ROOM,
|
||||
RELATIVE_ROTARY,
|
||||
SCENE,
|
||||
TAMPER,
|
||||
SMART_SCENE,
|
||||
TEMPERATURE,
|
||||
ZGP_CONNECTIVITY,
|
||||
|
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 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.dto.clip2.enums;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Enum for tamper switch states.
|
||||
*
|
||||
* @author Andrew Fiddian-Green - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum TamperStateType {
|
||||
NOT_TAMPERED,
|
||||
TAMPERED
|
||||
}
|
@ -433,6 +433,10 @@ public class Clip2ThingHandler extends BaseThingHandler {
|
||||
putResource = new Resource(ResourceType.LIGHT_LEVEL).setEnabled(command);
|
||||
break;
|
||||
|
||||
case CHANNEL_2_SECURITY_CONTACT_ENABLED:
|
||||
putResource = new Resource(ResourceType.CONTACT).setEnabled(command);
|
||||
break;
|
||||
|
||||
case CHANNEL_2_SCENE:
|
||||
if (command instanceof StringType) {
|
||||
Resource scene = sceneResourceEntries.get(((StringType) command).toString());
|
||||
@ -888,6 +892,7 @@ public class Clip2ThingHandler extends BaseThingHandler {
|
||||
break;
|
||||
|
||||
case MOTION:
|
||||
case CAMERA_MOTION:
|
||||
updateState(CHANNEL_2_MOTION, resource.getMotionState(), fullUpdate);
|
||||
updateState(CHANNEL_2_MOTION_LAST_UPDATED,
|
||||
resource.getMotionLastUpdatedState(timeZoneProvider.getTimeZone()), fullUpdate);
|
||||
@ -920,6 +925,19 @@ public class Clip2ThingHandler extends BaseThingHandler {
|
||||
updateState(CHANNEL_2_SCENE, resource.getSceneState(), fullUpdate);
|
||||
break;
|
||||
|
||||
case CONTACT:
|
||||
updateState(CHANNEL_2_SECURITY_CONTACT, resource.getContactState(), fullUpdate);
|
||||
updateState(CHANNEL_2_SECURITY_CONTACT_LAST_UPDATED,
|
||||
resource.getContactLastUpdatedState(timeZoneProvider.getTimeZone()), fullUpdate);
|
||||
updateState(CHANNEL_2_SECURITY_CONTACT_ENABLED, resource.getEnabledState(), fullUpdate);
|
||||
break;
|
||||
|
||||
case TAMPER:
|
||||
updateState(CHANNEL_2_SECURITY_TAMPER, resource.getTamperState(), fullUpdate);
|
||||
updateState(CHANNEL_2_SECURITY_TAMPER_LAST_UPDATED,
|
||||
resource.getTamperLastUpdatedState(timeZoneProvider.getTimeZone()), fullUpdate);
|
||||
break;
|
||||
|
||||
case SMART_SCENE:
|
||||
updateState(CHANNEL_2_SCENE, resource.getSmartSceneState(), fullUpdate);
|
||||
break;
|
||||
|
@ -55,6 +55,15 @@ thing-type.hue.device.channel.motion-last-updated.description = The date and tim
|
||||
thing-type.hue.device.channel.on-off-only.description = Set the on/off parameter of the light without changing other state parameters.
|
||||
thing-type.hue.device.channel.rotary-steps-last-updated.label = Rotary Steps Last Updated
|
||||
thing-type.hue.device.channel.rotary-steps-last-updated.description = The date and time when the rotary steps were last updated.
|
||||
thing-type.hue.device.channel.security-contact.label = Security Contact
|
||||
thing-type.hue.device.channel.security-contact.description = Open or closed state of the contact.
|
||||
thing-type.hue.device.channel.security-contact-enabled.description = Security contact enabled.
|
||||
thing-type.hue.device.channel.security-contact-last-updated.label = Security Contact Last Updated
|
||||
thing-type.hue.device.channel.security-contact-last-updated.description = The date and time when the contact state was last updated.
|
||||
thing-type.hue.device.channel.security-tamper.label = Security Tamper Contact
|
||||
thing-type.hue.device.channel.security-tamper.description = Tamper or no tamper state of the sensor.
|
||||
thing-type.hue.device.channel.security-tamper-last-updated.label = Tamper Contact Last Updated
|
||||
thing-type.hue.device.channel.security-tamper-last-updated.description = The date and time when the tamper contact state was last updated.
|
||||
thing-type.hue.device.channel.temperature.label = Temperature
|
||||
thing-type.hue.device.channel.temperature.description = Temperature at the sensor location.
|
||||
thing-type.hue.device.channel.temperature-enabled.description = Temperature sensor enabled.
|
||||
@ -183,6 +192,8 @@ channel-type.hue.rotary-steps.description = The last 'steps' value (e.g. +/-30)
|
||||
channel-type.hue.scene-v2.label = Scene
|
||||
channel-type.hue.scene.label = Scene
|
||||
channel-type.hue.scene.description = The scene channel allows recalling a scene to all lights that belong to the scene.
|
||||
channel-type.hue.security-contact.label = Open/Closed
|
||||
channel-type.hue.security-tamper.label = Normal/Tamper
|
||||
channel-type.hue.sensor-enabled.label = Sensor Enabled
|
||||
channel-type.hue.status.label = Status
|
||||
channel-type.hue.status.description = Status of CLIP sensor.
|
||||
|
@ -62,6 +62,25 @@
|
||||
<channel id="temperature-enabled" typeId="sensor-enabled">
|
||||
<description>Temperature sensor enabled.</description>
|
||||
</channel>
|
||||
<channel id="security-contact" typeId="security-contact">
|
||||
<label>Security Contact</label>
|
||||
<description>Open or closed state of the contact.</description>
|
||||
</channel>
|
||||
<channel id="security-contact-enabled" typeId="sensor-enabled">
|
||||
<description>Security contact enabled.</description>
|
||||
</channel>
|
||||
<channel id="security-contact-last-updated" typeId="last-updated-v2">
|
||||
<label>Security Contact Last Updated</label>
|
||||
<description>The date and time when the contact state was last updated.</description>
|
||||
</channel>
|
||||
<channel id="security-tamper" typeId="security-tamper">
|
||||
<label>Security Tamper Contact</label>
|
||||
<description>Tamper or no tamper state of the sensor.</description>
|
||||
</channel>
|
||||
<channel id="security-tamper-last-updated" typeId="last-updated-v2">
|
||||
<label>Tamper Contact Last Updated</label>
|
||||
<description>The date and time when the tamper contact state was last updated.</description>
|
||||
</channel>
|
||||
<channel id="battery-level" typeId="system.battery-level"/>
|
||||
<channel id="battery-low" typeId="system.low-battery"/>
|
||||
<channel id="last-updated" typeId="last-updated-v2"/>
|
||||
|
@ -256,4 +256,16 @@
|
||||
<category>Switch</category>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="security-contact">
|
||||
<item-type>Contact</item-type>
|
||||
<label>Open/Closed</label>
|
||||
<category>Lock</category>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="security-tamper">
|
||||
<item-type>Contact</item-type>
|
||||
<label>Normal/Tamper</label>
|
||||
<category>Siren</category>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
|
@ -21,6 +21,7 @@ import java.lang.reflect.Field;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@ -31,6 +32,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.ActionEntry;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.Alerts;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.Button;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.ContactReport;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.Dimming;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.Effects;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.Event;
|
||||
@ -46,6 +48,7 @@ import org.openhab.binding.hue.internal.dto.clip2.ResourceReference;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.Resources;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.Rotation;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.RotationEvent;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.TamperReport;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.Temperature;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.TimedEffects;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.ActionType;
|
||||
@ -63,6 +66,7 @@ import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.HSBType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.OpenClosedType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
@ -707,6 +711,91 @@ class Clip2DtoTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSecurityContact() {
|
||||
String json = load(ResourceType.CONTACT.name().toLowerCase());
|
||||
Resources resources = GSON.fromJson(json, Resources.class);
|
||||
assertNotNull(resources);
|
||||
List<Resource> list = resources.getResources();
|
||||
assertNotNull(list);
|
||||
assertEquals(1, list.size());
|
||||
Resource resource = list.get(0);
|
||||
assertEquals(ResourceType.CONTACT, resource.getType());
|
||||
|
||||
assertEquals(OpenClosedType.CLOSED, resource.getContactState());
|
||||
assertEquals(new DateTimeType("2023-10-10T19:10:55.919Z"),
|
||||
resource.getContactLastUpdatedState(ZoneId.of("UTC")));
|
||||
|
||||
resource.setContactReport(new ContactReport().setLastChanged(Instant.now()).setContactState("no_contact"));
|
||||
assertEquals(OpenClosedType.OPEN, resource.getContactState());
|
||||
assertTrue(resource.getContactLastUpdatedState(ZoneId.of("UTC")) instanceof DateTimeType);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSecurityTamper() {
|
||||
String json = load(ResourceType.TAMPER.name().toLowerCase());
|
||||
Resources resources = GSON.fromJson(json, Resources.class);
|
||||
assertNotNull(resources);
|
||||
List<Resource> list = resources.getResources();
|
||||
assertNotNull(list);
|
||||
assertEquals(1, list.size());
|
||||
Resource resource = list.get(0);
|
||||
assertEquals(ResourceType.TAMPER, resource.getType());
|
||||
|
||||
assertEquals(OpenClosedType.CLOSED, resource.getTamperState());
|
||||
assertEquals(new DateTimeType("2023-01-01T00:00:00.001Z"),
|
||||
resource.getTamperLastUpdatedState(ZoneId.of("UTC")));
|
||||
|
||||
Instant start = Instant.now();
|
||||
List<TamperReport> tamperReports;
|
||||
State state;
|
||||
|
||||
tamperReports = new ArrayList<>();
|
||||
tamperReports.add(new TamperReport().setTamperState("not_tampered").setLastChanged(start));
|
||||
resource.setTamperReports(tamperReports);
|
||||
assertEquals(OpenClosedType.CLOSED, resource.getTamperState());
|
||||
state = resource.getTamperLastUpdatedState(ZoneId.of("UTC"));
|
||||
assertTrue(state instanceof DateTimeType);
|
||||
assertEquals(start, ((DateTimeType) state).getInstant());
|
||||
|
||||
tamperReports = new ArrayList<>();
|
||||
tamperReports.add(new TamperReport().setTamperState("not_tampered").setLastChanged(start));
|
||||
tamperReports.add(new TamperReport().setTamperState("tampered").setLastChanged(start.plusSeconds(1)));
|
||||
resource.setTamperReports(tamperReports);
|
||||
assertEquals(OpenClosedType.OPEN, resource.getTamperState());
|
||||
state = resource.getTamperLastUpdatedState(ZoneId.of("UTC"));
|
||||
assertTrue(state instanceof DateTimeType);
|
||||
assertEquals(start.plusSeconds(1), ((DateTimeType) state).getInstant());
|
||||
|
||||
tamperReports = new ArrayList<>();
|
||||
tamperReports.add(new TamperReport().setTamperState("not_tampered").setLastChanged(start));
|
||||
tamperReports.add(new TamperReport().setTamperState("tampered").setLastChanged(start.plusSeconds(1)));
|
||||
tamperReports.add(new TamperReport().setTamperState("not_tampered").setLastChanged(start.plusSeconds(2)));
|
||||
resource.setTamperReports(tamperReports);
|
||||
assertEquals(OpenClosedType.CLOSED, resource.getTamperState());
|
||||
state = resource.getTamperLastUpdatedState(ZoneId.of("UTC"));
|
||||
assertTrue(state instanceof DateTimeType);
|
||||
assertEquals(start.plusSeconds(2), ((DateTimeType) state).getInstant());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCameraMotion() {
|
||||
String json = load(ResourceType.CAMERA_MOTION.name().toLowerCase());
|
||||
Resources resources = GSON.fromJson(json, Resources.class);
|
||||
assertNotNull(resources);
|
||||
List<Resource> list = resources.getResources();
|
||||
assertNotNull(list);
|
||||
assertEquals(1, list.size());
|
||||
Resource resource = list.get(0);
|
||||
assertEquals(ResourceType.CAMERA_MOTION, resource.getType());
|
||||
|
||||
Boolean enabled = resource.getEnabled();
|
||||
assertNotNull(enabled);
|
||||
assertTrue(enabled);
|
||||
assertEquals(OnOffType.ON, resource.getMotionState());
|
||||
assertEquals(new DateTimeType("2020-04-01T20:04:30.395Z"),
|
||||
resource.getMotionLastUpdatedState(ZoneId.of("UTC")));
|
||||
}
|
||||
|
||||
void testFixedEffectSetter() {
|
||||
Resource source;
|
||||
Resource target;
|
||||
|
@ -0,0 +1,28 @@
|
||||
{
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000005",
|
||||
"id_v1": "/sensors/5",
|
||||
"owner": {
|
||||
"rid": "00000000-0000-0000-0000-000000000000",
|
||||
"rtype": "device"
|
||||
},
|
||||
"enabled": true,
|
||||
"motion": {
|
||||
"motion": false,
|
||||
"motion_valid": true,
|
||||
"motion_report": {
|
||||
"changed": "2020-04-01T20:04:30.395Z",
|
||||
"motion": true
|
||||
}
|
||||
},
|
||||
"sensitivity": {
|
||||
"status": "set",
|
||||
"sensitivity": 2,
|
||||
"sensitivity_max": 4
|
||||
},
|
||||
"type": "camera_motion"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"errors": [
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"id": "bcaee909-1b37-454b-814d-9928776ad350",
|
||||
"owner": {
|
||||
"rid": "faac7940-a303-4e8e-9f06-075fffb7229c",
|
||||
"rtype": "device"
|
||||
},
|
||||
"enabled": true,
|
||||
"contact_report": {
|
||||
"changed": "2023-10-10T19:10:55.919Z",
|
||||
"state": "contact"
|
||||
},
|
||||
"type": "contact"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
{
|
||||
"errors": [
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"id": "6c2ef541-fe03-4cae-ac60-3edcaa93b33e",
|
||||
"owner": {
|
||||
"rid": "faac7940-a303-4e8e-9f06-075fffb7229c",
|
||||
"rtype": "device"
|
||||
},
|
||||
"tamper_reports": [
|
||||
{
|
||||
"changed": "1970-01-01T00:00:00.000Z",
|
||||
"source": "battery_door",
|
||||
"state": "not_tampered"
|
||||
},
|
||||
{
|
||||
"changed": "2023-01-01T00:00:00.001Z",
|
||||
"source": "battery_door",
|
||||
"state": "not_tampered"
|
||||
},
|
||||
{
|
||||
"changed": "2023-01-01T00:00:00.000Z",
|
||||
"source": "battery_door",
|
||||
"state": "tampered"
|
||||
}
|
||||
],
|
||||
"type": "tamper"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user