[hue] Add channels for time of last sensor update (API v2) (#15552)
* Add channels for last motion/temperature sensor update (API v2) * Add channel for last light level sensor update (API v2) * Add channel for last rotary steps update (API v2) * Add channel for last button update (API v2) Resolves #15546 Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>pull/15814/head
parent
bdba338f44
commit
1702631303
|
@ -59,30 +59,35 @@ 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) |
|
||||
| rotary-steps | (String) | Informs about the number of rotary steps of the last rotary dial movement. (Trigger Channel) |
|
||||
| motion | Switch | Shows if motion has been detected by the sensor. (Read Only) |
|
||||
| motion-enabled | Switch | Supports enabling / disabling the motion sensor. (Advanced) |
|
||||
| light-level | Number:Illuminance | Shows the current light level measured by the sensor. (Read Only) |
|
||||
| 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-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. |
|
||||
|
||||
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.
|
||||
|
|
|
@ -151,12 +151,17 @@ public class HueBindingConstants {
|
|||
public static final String CHANNEL_2_ALERT = CHANNEL_ALERT;
|
||||
public static final String CHANNEL_2_EFFECT = CHANNEL_EFFECT;
|
||||
public static final String CHANNEL_2_BUTTON_LAST_EVENT = "button-last-event";
|
||||
public static final String CHANNEL_2_BUTTON_LAST_UPDATED = "button-last-updated";
|
||||
public static final String CHANNEL_2_ROTARY_STEPS = "rotary-steps";
|
||||
public static final String CHANNEL_2_ROTARY_STEPS_LAST_UPDATED = "rotary-steps-last-updated";
|
||||
public static final String CHANNEL_2_MOTION = "motion";
|
||||
public static final String CHANNEL_2_MOTION_LAST_UPDATED = "motion-last-updated";
|
||||
public static final String CHANNEL_2_MOTION_ENABLED = "motion-enabled";
|
||||
public static final String CHANNEL_2_LIGHT_LEVEL = "light-level";
|
||||
public static final String CHANNEL_2_LIGHT_LEVEL_LAST_UPDATED = "light-level-last-updated";
|
||||
public static final String CHANNEL_2_LIGHT_LEVEL_ENABLED = "light-level-enabled";
|
||||
public static final String CHANNEL_2_TEMPERATURE = CHANNEL_TEMPERATURE;
|
||||
public static final String CHANNEL_2_TEMPERATURE_LAST_UPDATED = "temperature-last-updated";
|
||||
public static final String CHANNEL_2_TEMPERATURE_ENABLED = "temperature-enabled";
|
||||
public static final String CHANNEL_2_BATTERY_LEVEL = "battery-level";
|
||||
public static final String CHANNEL_2_BATTERY_LOW = "battery-low";
|
||||
|
|
|
@ -81,12 +81,14 @@ import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
|
|||
import org.openhab.binding.hue.internal.exceptions.ApiException;
|
||||
import org.openhab.binding.hue.internal.exceptions.HttpUnauthorizedException;
|
||||
import org.openhab.binding.hue.internal.handler.Clip2BridgeHandler;
|
||||
import org.openhab.binding.hue.internal.serialization.InstantDeserializer;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.io.net.http.HttpUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
@ -556,7 +558,8 @@ public class Clip2Bridge implements Closeable {
|
|||
private final String registrationUrl;
|
||||
private final String applicationKey;
|
||||
private final Clip2BridgeHandler bridgeHandler;
|
||||
private final Gson jsonParser = new Gson();
|
||||
private final Gson jsonParser = new GsonBuilder().registerTypeAdapter(Instant.class, new InstantDeserializer())
|
||||
.create();
|
||||
private final Semaphore streamMutex = new Semaphore(MAX_CONCURRENT_STREAMS, true); // i.e. fair
|
||||
private final ReadWriteLock sessionUseCreateLock = new ReentrantReadWriteLock(true); // i.e. fair
|
||||
private final Map<Integer, Future<?>> fatalErrorTasks = new ConcurrentHashMap<>();
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
*/
|
||||
package org.openhab.binding.hue.internal.dto.clip2;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.ButtonEventType;
|
||||
|
@ -28,16 +26,29 @@ import com.google.gson.annotations.SerializedName;
|
|||
@NonNullByDefault
|
||||
public class Button {
|
||||
private @Nullable @SerializedName("last_event") String lastEvent;
|
||||
private @Nullable @SerializedName("button_report") ButtonReport buttonReport;
|
||||
private @SerializedName("repeat_interval") int repeatInterval;
|
||||
|
||||
/**
|
||||
* @return the last button event as an enum.
|
||||
* @throws IllegalArgumentException if lastEvent is null or bad.
|
||||
* The underlying field is deprecated in the CLIP 2 API.
|
||||
* Moved to button_report/event
|
||||
*
|
||||
* @return the last button event as an enum (null if none or invalid).
|
||||
*/
|
||||
public ButtonEventType getLastEvent() throws IllegalArgumentException {
|
||||
public @Nullable ButtonEventType getLastEvent() {
|
||||
String lastEvent = this.lastEvent;
|
||||
if (Objects.nonNull(lastEvent)) {
|
||||
return ButtonEventType.valueOf(lastEvent.toUpperCase());
|
||||
if (lastEvent == null) {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalArgumentException("lastEvent field is null");
|
||||
|
||||
try {
|
||||
return ButtonEventType.valueOf(lastEvent.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable ButtonReport getButtonReport() {
|
||||
return buttonReport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* 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.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.ButtonEventType;
|
||||
|
||||
/**
|
||||
* DTO for CLIP 2 button report.
|
||||
*
|
||||
* @author Jacob Laursen - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ButtonReport {
|
||||
private @NonNullByDefault({}) Instant updated;
|
||||
private @Nullable String event;
|
||||
|
||||
/**
|
||||
* @return last time the value of this property is updated.
|
||||
*/
|
||||
public Instant getLastChanged() {
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return event which can be sent by a button control (null if none or invalid).
|
||||
*/
|
||||
public @Nullable ButtonEventType getLastEvent() {
|
||||
String event = this.event;
|
||||
if (event == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return ButtonEventType.valueOf(event.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@
|
|||
package org.openhab.binding.hue.internal.dto.clip2;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
|
@ -30,11 +31,22 @@ import com.google.gson.annotations.SerializedName;
|
|||
public class LightLevel {
|
||||
private @SerializedName("light_level") int lightLevel;
|
||||
private @SerializedName("light_level_valid") boolean lightLevelValid;
|
||||
private @Nullable @SerializedName("light_level_report") LightLevelReport lightLevelReport;
|
||||
|
||||
/**
|
||||
* The underlying field is deprecated in the CLIP 2 API.
|
||||
* Moved to light_level_report/light_level
|
||||
* Should be used only as fallback for older firmwares.
|
||||
*/
|
||||
public int getLightLevel() {
|
||||
return lightLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* The underlying field is deprecated in the CLIP 2 API.
|
||||
* Indication whether the value presented in light_level is valid
|
||||
* Should be used only as fallback for older firmwares.
|
||||
*/
|
||||
public boolean isLightLevelValid() {
|
||||
return lightLevelValid;
|
||||
}
|
||||
|
@ -56,4 +68,8 @@ public class LightLevel {
|
|||
public State isLightLevelValidState() {
|
||||
return OnOffType.from(lightLevelValid);
|
||||
}
|
||||
|
||||
public @Nullable LightLevelReport getLightLevelReport() {
|
||||
return lightLevelReport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* DTO for CLIP 2 light level sensor report.
|
||||
*
|
||||
* @author Jacob Laursen - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class LightLevelReport {
|
||||
private @NonNullByDefault({}) Instant changed;
|
||||
private @SerializedName("light_level") int lightLevel;
|
||||
|
||||
/**
|
||||
* @return last time the value of this property is changed.
|
||||
*/
|
||||
public Instant getLastChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Light level in 10000*log10(lux) +1 measured by sensor.
|
||||
* Logarithmic scale used because the human eye adjusts to light levels and small changes at low lux levels
|
||||
* are more noticeable than at high lux levels. This allows use of linear scale configuration sliders.
|
||||
*
|
||||
* @return light level in 10000*log10(lux) +1 measured by sensor
|
||||
*/
|
||||
public int getLightLevel() {
|
||||
return lightLevel;
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@
|
|||
package org.openhab.binding.hue.internal.dto.clip2;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
@ -28,11 +29,24 @@ import com.google.gson.annotations.SerializedName;
|
|||
public class Motion {
|
||||
private boolean motion;
|
||||
private @SerializedName("motion_valid") boolean motionValid;
|
||||
private @Nullable @SerializedName("motion_report") MotionReport motionReport;
|
||||
|
||||
/**
|
||||
* The underlying field is deprecated in the CLIP 2 API.
|
||||
* Moved to motion_report/motion.
|
||||
* Should be used only as fallback for older firmwares.
|
||||
*
|
||||
* @return true if motion is detected
|
||||
*/
|
||||
public boolean isMotion() {
|
||||
return motion;
|
||||
}
|
||||
|
||||
/**
|
||||
* The underlying field is deprecated in the CLIP 2 API.
|
||||
* Motion is valid when motion_report property is present, invalid when absent.
|
||||
* Should be used only as fallback for older firmwares.
|
||||
*/
|
||||
public boolean isMotionValid() {
|
||||
return motionValid;
|
||||
}
|
||||
|
@ -44,4 +58,8 @@ public class Motion {
|
|||
public State getMotionValidState() {
|
||||
return OnOffType.from(motionValid);
|
||||
}
|
||||
|
||||
public @Nullable MotionReport getMotionReport() {
|
||||
return motionReport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* DTO for CLIP 2 motion sensor report.
|
||||
*
|
||||
* @author Jacob Laursen - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MotionReport {
|
||||
private @NonNullByDefault({}) Instant changed;
|
||||
private boolean motion;
|
||||
|
||||
/**
|
||||
* @return last time the value of this property is changed.
|
||||
*/
|
||||
public Instant getLastChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if motion is detected
|
||||
*/
|
||||
public boolean isMotion() {
|
||||
return motion;
|
||||
}
|
||||
}
|
|
@ -29,18 +29,33 @@ import com.google.gson.annotations.SerializedName;
|
|||
@NonNullByDefault
|
||||
public class RelativeRotary {
|
||||
private @Nullable @SerializedName("last_event") RotationEvent lastEvent;
|
||||
private @Nullable @SerializedName("rotary_report") RotaryReport rotaryReport;
|
||||
|
||||
public State getActionState() {
|
||||
RotationEvent lastEvent = getLastEvent();
|
||||
return Objects.nonNull(lastEvent) ? lastEvent.getActionState() : UnDefType.NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* The underlying field is deprecated in the CLIP 2 API.
|
||||
* Renamed to RelativeRotaryReport. Indicate which type of rotary event is received.
|
||||
* Should be used only as fallback for older firmwares.
|
||||
*/
|
||||
public @Nullable RotationEvent getLastEvent() {
|
||||
return lastEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* The underlying field is deprecated in the CLIP 2 API.
|
||||
* Renamed to RelativeRotaryReport.
|
||||
* Should be used only as fallback for older firmwares.
|
||||
*/
|
||||
public State getStepsState() {
|
||||
RotationEvent lastEvent = getLastEvent();
|
||||
return Objects.nonNull(lastEvent) ? lastEvent.getStepsState() : UnDefType.NULL;
|
||||
}
|
||||
|
||||
public @Nullable RotaryReport getRotaryReport() {
|
||||
return rotaryReport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ import java.math.BigDecimal;
|
|||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
@ -24,6 +27,7 @@ import java.util.Optional;
|
|||
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.EffectType;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.SceneRecallAction;
|
||||
|
@ -31,12 +35,15 @@ 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.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.PercentType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
@ -189,15 +196,36 @@ public class Resource {
|
|||
*/
|
||||
public State getButtonEventState(Map<String, Integer> controlIds) {
|
||||
Button button = this.button;
|
||||
if (Objects.nonNull(button)) {
|
||||
try {
|
||||
return new DecimalType(
|
||||
(controlIds.getOrDefault(getId(), 0).intValue() * 1000) + button.getLastEvent().ordinal());
|
||||
} catch (IllegalArgumentException e) {
|
||||
// fall through
|
||||
}
|
||||
if (button == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
return UnDefType.NULL;
|
||||
ButtonEventType event;
|
||||
ButtonReport buttonReport = button.getButtonReport();
|
||||
if (buttonReport == null) {
|
||||
event = button.getLastEvent();
|
||||
} else {
|
||||
event = buttonReport.getLastEvent();
|
||||
}
|
||||
if (event == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
return new DecimalType((controlIds.getOrDefault(getId(), 0).intValue() * 1000) + event.ordinal());
|
||||
}
|
||||
|
||||
public State getButtonLastUpdatedState(ZoneId zoneId) {
|
||||
Button button = this.button;
|
||||
if (button == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
ButtonReport buttonReport = button.getButtonReport();
|
||||
if (buttonReport == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
Instant lastChanged = buttonReport.getLastChanged();
|
||||
if (Instant.EPOCH.equals(lastChanged)) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
|
||||
}
|
||||
|
||||
public List<ResourceReference> getChildren() {
|
||||
|
@ -386,8 +414,31 @@ public class Resource {
|
|||
}
|
||||
|
||||
public State getLightLevelState() {
|
||||
LightLevel light = this.light;
|
||||
return Objects.nonNull(light) ? light.getLightLevelState() : UnDefType.NULL;
|
||||
LightLevel lightLevel = this.light;
|
||||
if (lightLevel == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
LightLevelReport lightLevelReport = lightLevel.getLightLevelReport();
|
||||
if (lightLevelReport == null) {
|
||||
return lightLevel.getLightLevelState();
|
||||
}
|
||||
return new QuantityType<>(Math.pow(10f, (double) lightLevelReport.getLightLevel() / 10000f) - 1f, Units.LUX);
|
||||
}
|
||||
|
||||
public State getLightLevelLastUpdatedState(ZoneId zoneId) {
|
||||
LightLevel lightLevel = this.light;
|
||||
if (lightLevel == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
LightLevelReport lightLevelReport = lightLevel.getLightLevelReport();
|
||||
if (lightLevelReport == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
Instant lastChanged = lightLevelReport.getLastChanged();
|
||||
if (Instant.EPOCH.equals(lastChanged)) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
|
||||
}
|
||||
|
||||
public @Nullable MetaData getMetaData() {
|
||||
|
@ -410,7 +461,30 @@ public class Resource {
|
|||
|
||||
public State getMotionState() {
|
||||
Motion motion = this.motion;
|
||||
return Objects.nonNull(motion) ? motion.getMotionState() : UnDefType.NULL;
|
||||
if (motion == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
MotionReport motionReport = motion.getMotionReport();
|
||||
if (motionReport == null) {
|
||||
return motion.getMotionState();
|
||||
}
|
||||
return OnOffType.from(motionReport.isMotion());
|
||||
}
|
||||
|
||||
public State getMotionLastUpdatedState(ZoneId zoneId) {
|
||||
Motion motion = this.motion;
|
||||
if (motion == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
MotionReport motionReport = motion.getMotionReport();
|
||||
if (motionReport == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
Instant lastChanged = motionReport.getLastChanged();
|
||||
if (Instant.EPOCH.equals(lastChanged)) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
|
||||
}
|
||||
|
||||
public State getMotionValidState() {
|
||||
|
@ -473,14 +547,36 @@ public class Resource {
|
|||
return relativeRotary;
|
||||
}
|
||||
|
||||
public State getRelativeRotaryActionState() {
|
||||
RelativeRotary relativeRotary = this.relativeRotary;
|
||||
return Objects.nonNull(relativeRotary) ? relativeRotary.getActionState() : UnDefType.NULL;
|
||||
}
|
||||
|
||||
public State getRotaryStepsState() {
|
||||
RelativeRotary relativeRotary = this.relativeRotary;
|
||||
return Objects.nonNull(relativeRotary) ? relativeRotary.getStepsState() : UnDefType.NULL;
|
||||
if (relativeRotary == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
RotaryReport rotaryReport = relativeRotary.getRotaryReport();
|
||||
if (rotaryReport == null) {
|
||||
return relativeRotary.getStepsState();
|
||||
}
|
||||
Rotation rotation = rotaryReport.getRotation();
|
||||
if (rotation == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
return rotation.getStepsState();
|
||||
}
|
||||
|
||||
public State getRotaryStepsLastUpdatedState(ZoneId zoneId) {
|
||||
RelativeRotary relativeRotary = this.relativeRotary;
|
||||
if (relativeRotary == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
RotaryReport rotaryReport = relativeRotary.getRotaryReport();
|
||||
if (rotaryReport == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
Instant lastChanged = rotaryReport.getLastChanged();
|
||||
if (Instant.EPOCH.equals(lastChanged)) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -559,7 +655,30 @@ public class Resource {
|
|||
|
||||
public State getTemperatureState() {
|
||||
Temperature temperature = this.temperature;
|
||||
return Objects.nonNull(temperature) ? temperature.getTemperatureState() : UnDefType.NULL;
|
||||
if (temperature == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
TemperatureReport temperatureReport = temperature.getTemperatureReport();
|
||||
if (temperatureReport == null) {
|
||||
return temperature.getTemperatureState();
|
||||
}
|
||||
return new QuantityType<>(temperatureReport.getTemperature(), SIUnits.CELSIUS);
|
||||
}
|
||||
|
||||
public State getTemperatureLastUpdatedState(ZoneId zoneId) {
|
||||
Temperature temperature = this.temperature;
|
||||
if (temperature == null) {
|
||||
return UnDefType.NULL;
|
||||
}
|
||||
TemperatureReport temperatureReport = temperature.getTemperatureReport();
|
||||
if (temperatureReport == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
Instant lastChanged = temperatureReport.getLastChanged();
|
||||
if (Instant.EPOCH.equals(lastChanged)) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new DateTimeType(ZonedDateTime.ofInstant(lastChanged, zoneId));
|
||||
}
|
||||
|
||||
public State getTemperatureValidState() {
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* 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.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.RotationEventType;
|
||||
|
||||
/**
|
||||
* DTO for CLIP 2 relative rotary report.
|
||||
*
|
||||
* @author Jacob Laursen - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RotaryReport {
|
||||
private @NonNullByDefault({}) Instant updated;
|
||||
private @Nullable String action;
|
||||
private @Nullable Rotation rotation;
|
||||
|
||||
/**
|
||||
* @return last time the value of this property is changed.
|
||||
*/
|
||||
public Instant getLastChanged() {
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return which type of rotary event is received
|
||||
*/
|
||||
public @Nullable RotationEventType getAction() {
|
||||
String action = this.action;
|
||||
return action == null ? null : RotationEventType.valueOf(action.toUpperCase());
|
||||
}
|
||||
|
||||
public @Nullable Rotation getRotation() {
|
||||
return rotation;
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@
|
|||
package org.openhab.binding.hue.internal.dto.clip2;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
|
@ -30,11 +31,24 @@ import com.google.gson.annotations.SerializedName;
|
|||
public class Temperature {
|
||||
private float temperature;
|
||||
private @SerializedName("temperature_valid") boolean temperatureValid;
|
||||
private @Nullable @SerializedName("temperature_report") TemperatureReport temperatureReport;
|
||||
|
||||
/**
|
||||
* The underlying field is deprecated in the CLIP 2 API.
|
||||
* Moved to temperature_report/temperature.
|
||||
* Should be used only as fallback for older firmwares.
|
||||
*
|
||||
* @return temperature in 1.00 degrees Celsius
|
||||
*/
|
||||
public float getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
|
||||
/**
|
||||
* The underlying field is deprecated in the CLIP 2 API.
|
||||
* Indication whether the value presented in temperature is valid
|
||||
* Should be used only as fallback for older firmwares.
|
||||
*/
|
||||
public boolean isTemperatureValid() {
|
||||
return temperatureValid;
|
||||
}
|
||||
|
@ -46,4 +60,8 @@ public class Temperature {
|
|||
public State getTemperatureValidState() {
|
||||
return OnOffType.from(temperatureValid);
|
||||
}
|
||||
|
||||
public @Nullable TemperatureReport getTemperatureReport() {
|
||||
return temperatureReport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* DTO for CLIP 2 temperature sensor report.
|
||||
*
|
||||
* @author Jacob Laursen - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class TemperatureReport {
|
||||
private @NonNullByDefault({}) Instant changed;
|
||||
private float temperature;
|
||||
|
||||
/**
|
||||
* @return last time the value of this property is changed.
|
||||
*/
|
||||
public Instant getLastChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return temperature in 1.00 degrees Celsius
|
||||
*/
|
||||
public float getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import org.openhab.binding.hue.internal.handler.sensors.TapSwitchHandler;
|
|||
import org.openhab.binding.hue.internal.handler.sensors.TemperatureHandler;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.i18n.TranslationProvider;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
|
@ -82,6 +83,7 @@ public class HueThingHandlerFactory extends BaseThingHandlerFactory {
|
|||
private final Clip2StateDescriptionProvider clip2StateDescriptionProvider;
|
||||
private final TranslationProvider i18nProvider;
|
||||
private final LocaleProvider localeProvider;
|
||||
private final TimeZoneProvider timeZoneProvider;
|
||||
private final ThingRegistry thingRegistry;
|
||||
private final ItemChannelLinkRegistry itemChannelLinkRegistry;
|
||||
|
||||
|
@ -90,13 +92,14 @@ public class HueThingHandlerFactory extends BaseThingHandlerFactory {
|
|||
final @Reference HueStateDescriptionProvider stateDescriptionProvider,
|
||||
final @Reference Clip2StateDescriptionProvider clip2StateDescriptionProvider,
|
||||
final @Reference TranslationProvider i18nProvider, final @Reference LocaleProvider localeProvider,
|
||||
final @Reference ThingRegistry thingRegistry,
|
||||
final @Reference TimeZoneProvider timeZoneProvider, final @Reference ThingRegistry thingRegistry,
|
||||
final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry) {
|
||||
this.httpClientFactory = httpClientFactory;
|
||||
this.stateDescriptionProvider = stateDescriptionProvider;
|
||||
this.clip2StateDescriptionProvider = clip2StateDescriptionProvider;
|
||||
this.i18nProvider = i18nProvider;
|
||||
this.localeProvider = localeProvider;
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
this.thingRegistry = thingRegistry;
|
||||
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
|
||||
}
|
||||
|
@ -184,7 +187,8 @@ public class HueThingHandlerFactory extends BaseThingHandlerFactory {
|
|||
return new Clip2BridgeHandler((Bridge) thing, httpClientFactory, thingRegistry, localeProvider,
|
||||
i18nProvider);
|
||||
} else if (Clip2ThingHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
|
||||
return new Clip2ThingHandler(thing, clip2StateDescriptionProvider, thingRegistry, itemChannelLinkRegistry);
|
||||
return new Clip2ThingHandler(thing, clip2StateDescriptionProvider, timeZoneProvider, thingRegistry,
|
||||
itemChannelLinkRegistry);
|
||||
} else if (HueBridgeHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
|
||||
return new HueBridgeHandler((Bridge) thing, httpClientFactory.getCommonHttpClient(),
|
||||
stateDescriptionProvider, i18nProvider, localeProvider);
|
||||
|
|
|
@ -57,6 +57,7 @@ import org.openhab.binding.hue.internal.dto.clip2.enums.ZigbeeStatus;
|
|||
import org.openhab.binding.hue.internal.dto.clip2.helper.Setters;
|
||||
import org.openhab.binding.hue.internal.exceptions.ApiException;
|
||||
import org.openhab.binding.hue.internal.exceptions.AssetNotLoadedException;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.HSBType;
|
||||
|
@ -160,11 +161,13 @@ public class Clip2ThingHandler extends BaseThingHandler {
|
|||
private final ThingRegistry thingRegistry;
|
||||
private final ItemChannelLinkRegistry itemChannelLinkRegistry;
|
||||
private final Clip2StateDescriptionProvider stateDescriptionProvider;
|
||||
private final TimeZoneProvider timeZoneProvider;
|
||||
|
||||
private String resourceId = "?";
|
||||
private Resource thisResource;
|
||||
private Duration dynamicsDuration = Duration.ZERO;
|
||||
private Instant dynamicsExpireTime = Instant.MIN;
|
||||
private Instant buttonGroupLastUpdated = Instant.MIN;
|
||||
|
||||
private boolean disposing;
|
||||
private boolean hasConnectivityIssue;
|
||||
|
@ -180,7 +183,8 @@ public class Clip2ThingHandler extends BaseThingHandler {
|
|||
private @Nullable Future<?> updateServiceContributorsTask;
|
||||
|
||||
public Clip2ThingHandler(Thing thing, Clip2StateDescriptionProvider stateDescriptionProvider,
|
||||
ThingRegistry thingRegistry, ItemChannelLinkRegistry itemChannelLinkRegistry) {
|
||||
TimeZoneProvider timeZoneProvider, ThingRegistry thingRegistry,
|
||||
ItemChannelLinkRegistry itemChannelLinkRegistry) {
|
||||
super(thing);
|
||||
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
@ -197,6 +201,7 @@ public class Clip2ThingHandler extends BaseThingHandler {
|
|||
this.thingRegistry = thingRegistry;
|
||||
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
|
||||
this.stateDescriptionProvider = stateDescriptionProvider;
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -829,11 +834,23 @@ public class Clip2ThingHandler extends BaseThingHandler {
|
|||
case BUTTON:
|
||||
if (fullUpdate) {
|
||||
addSupportedChannel(CHANNEL_2_BUTTON_LAST_EVENT);
|
||||
addSupportedChannel(CHANNEL_2_BUTTON_LAST_UPDATED);
|
||||
controlIds.put(resource.getId(), resource.getControlId());
|
||||
} else {
|
||||
State buttonState = resource.getButtonEventState(controlIds);
|
||||
updateState(CHANNEL_2_BUTTON_LAST_EVENT, buttonState, fullUpdate);
|
||||
}
|
||||
// Update channel from timestamp if last button pressed.
|
||||
State buttonLastUpdatedState = resource.getButtonLastUpdatedState(timeZoneProvider.getTimeZone());
|
||||
if (buttonLastUpdatedState instanceof DateTimeType) {
|
||||
Instant buttonLastUpdatedInstant = ((DateTimeType) buttonLastUpdatedState).getInstant();
|
||||
if (buttonLastUpdatedInstant.isAfter(buttonGroupLastUpdated)) {
|
||||
updateState(CHANNEL_2_BUTTON_LAST_UPDATED, buttonLastUpdatedState, fullUpdate);
|
||||
buttonGroupLastUpdated = buttonLastUpdatedInstant;
|
||||
}
|
||||
} else if (Instant.MIN.equals(buttonGroupLastUpdated)) {
|
||||
updateState(CHANNEL_2_BUTTON_LAST_UPDATED, buttonLastUpdatedState, fullUpdate);
|
||||
}
|
||||
break;
|
||||
|
||||
case DEVICE_POWER:
|
||||
|
@ -865,24 +882,33 @@ public class Clip2ThingHandler extends BaseThingHandler {
|
|||
|
||||
case LIGHT_LEVEL:
|
||||
updateState(CHANNEL_2_LIGHT_LEVEL, resource.getLightLevelState(), fullUpdate);
|
||||
updateState(CHANNEL_2_LIGHT_LEVEL_LAST_UPDATED,
|
||||
resource.getLightLevelLastUpdatedState(timeZoneProvider.getTimeZone()), fullUpdate);
|
||||
updateState(CHANNEL_2_LIGHT_LEVEL_ENABLED, resource.getEnabledState(), fullUpdate);
|
||||
break;
|
||||
|
||||
case MOTION:
|
||||
updateState(CHANNEL_2_MOTION, resource.getMotionState(), fullUpdate);
|
||||
updateState(CHANNEL_2_MOTION_LAST_UPDATED,
|
||||
resource.getMotionLastUpdatedState(timeZoneProvider.getTimeZone()), fullUpdate);
|
||||
updateState(CHANNEL_2_MOTION_ENABLED, resource.getEnabledState(), fullUpdate);
|
||||
break;
|
||||
|
||||
case RELATIVE_ROTARY:
|
||||
if (fullUpdate) {
|
||||
addSupportedChannel(CHANNEL_2_ROTARY_STEPS);
|
||||
addSupportedChannel(CHANNEL_2_ROTARY_STEPS_LAST_UPDATED);
|
||||
} else {
|
||||
updateState(CHANNEL_2_ROTARY_STEPS, resource.getRotaryStepsState(), fullUpdate);
|
||||
}
|
||||
updateState(CHANNEL_2_ROTARY_STEPS_LAST_UPDATED,
|
||||
resource.getRotaryStepsLastUpdatedState(timeZoneProvider.getTimeZone()), fullUpdate);
|
||||
break;
|
||||
|
||||
case TEMPERATURE:
|
||||
updateState(CHANNEL_2_TEMPERATURE, resource.getTemperatureState(), fullUpdate);
|
||||
updateState(CHANNEL_2_TEMPERATURE_LAST_UPDATED,
|
||||
resource.getTemperatureLastUpdatedState(timeZoneProvider.getTimeZone()), fullUpdate);
|
||||
updateState(CHANNEL_2_TEMPERATURE_ENABLED, resource.getEnabledState(), fullUpdate);
|
||||
break;
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* 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.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeParseException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
/**
|
||||
* The {@link InstantDeserializer} converts a formatted UTC string to {@link Instant}.
|
||||
*
|
||||
* @author Jacob Laursen - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class InstantDeserializer implements JsonDeserializer<Instant> {
|
||||
|
||||
@Override
|
||||
public @Nullable Instant deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2)
|
||||
throws JsonParseException {
|
||||
String content = element.getAsString();
|
||||
try {
|
||||
return Instant.parse(content);
|
||||
} catch (DateTimeParseException e) {
|
||||
throw new JsonParseException("Could not parse as Instant: " + content, e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,16 +40,26 @@ thing-type.hue.bridge.description = The Hue Bridge represents the Philips Hue Br
|
|||
thing-type.hue.device.label = Hue Device
|
||||
thing-type.hue.device.description = A Hue API v2 device with channels depending on its actual capabilities.
|
||||
thing-type.hue.device.channel.alert.description = Activate the alert for the light.
|
||||
thing-type.hue.device.channel.button-last-updated.label = Button Last Updated
|
||||
thing-type.hue.device.channel.button-last-updated.description = The date and time when a button was last pressed.
|
||||
thing-type.hue.device.channel.color-xy-only.description = Set the color xy parameter of the light without changing other state parameters.
|
||||
thing-type.hue.device.channel.dimming-only.description = Set the dimming parameter of the light without changing other state parameters.
|
||||
thing-type.hue.device.channel.effect.description = Activate the effect for the light.
|
||||
thing-type.hue.device.channel.light-level.description = Current light level.
|
||||
thing-type.hue.device.channel.light-level-enabled.description = Light level sensor enabled.
|
||||
thing-type.hue.device.channel.light-level-last-updated.label = Light Level Last Updated
|
||||
thing-type.hue.device.channel.light-level-last-updated.description = The date and time when the light level was last updated.
|
||||
thing-type.hue.device.channel.motion-enabled.description = Motion sensor enabled.
|
||||
thing-type.hue.device.channel.motion-last-updated.label = Motion Last Updated
|
||||
thing-type.hue.device.channel.motion-last-updated.description = The date and time when the motion value was last updated.
|
||||
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.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.
|
||||
thing-type.hue.device.channel.temperature-last-updated.label = Temperature Last Updated
|
||||
thing-type.hue.device.channel.temperature-last-updated.description = The date and time when the temperature was last updated.
|
||||
thing-type.hue.geofencesensor.label = Geofence Sensor
|
||||
thing-type.hue.geofencesensor.description = A sensor providing geofence based presence detection.
|
||||
thing-type.hue.group.label = Hue Group
|
||||
|
|
|
@ -24,14 +24,30 @@
|
|||
<description>Activate the effect for the light.</description>
|
||||
</channel>
|
||||
<channel id="button-last-event" typeId="button-last-event"/>
|
||||
<channel id="button-last-updated" typeId="last-updated-v2">
|
||||
<label>Button Last Updated</label>
|
||||
<description>The date and time when a button was last pressed.</description>
|
||||
</channel>
|
||||
<channel id="rotary-steps" typeId="rotary-steps"/>
|
||||
<channel id="rotary-steps-last-updated" typeId="last-updated-v2">
|
||||
<label>Rotary Steps Last Updated</label>
|
||||
<description>The date and time when the rotary steps were last updated.</description>
|
||||
</channel>
|
||||
<channel id="motion" typeId="system.motion"/>
|
||||
<channel id="motion-last-updated" typeId="last-updated-v2">
|
||||
<label>Motion Last Updated</label>
|
||||
<description>The date and time when the motion value was last updated.</description>
|
||||
</channel>
|
||||
<channel id="motion-enabled" typeId="sensor-enabled">
|
||||
<description>Motion sensor enabled.</description>
|
||||
</channel>
|
||||
<channel id="light-level" typeId="illuminance">
|
||||
<description>Current light level.</description>
|
||||
</channel>
|
||||
<channel id="light-level-last-updated" typeId="last-updated-v2">
|
||||
<label>Light Level Last Updated</label>
|
||||
<description>The date and time when the light level was last updated.</description>
|
||||
</channel>
|
||||
<channel id="light-level-enabled" typeId="sensor-enabled">
|
||||
<description>Light level sensor enabled.</description>
|
||||
</channel>
|
||||
|
@ -39,6 +55,10 @@
|
|||
<label>Temperature</label>
|
||||
<description>Temperature at the sensor location.</description>
|
||||
</channel>
|
||||
<channel id="temperature-last-updated" typeId="last-updated-v2">
|
||||
<label>Temperature Last Updated</label>
|
||||
<description>The date and time when the temperature was last updated.</description>
|
||||
</channel>
|
||||
<channel id="temperature-enabled" typeId="sensor-enabled">
|
||||
<description>Temperature sensor enabled.</description>
|
||||
</channel>
|
||||
|
@ -58,6 +78,10 @@
|
|||
</channel>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="thingTypeVersion">1</property>
|
||||
</properties>
|
||||
|
||||
<representation-property>resourceId</representation-property>
|
||||
|
||||
<config-description>
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
|
||||
|
||||
<thing-type uid="hue:device">
|
||||
|
||||
<instruction-set targetVersion="1">
|
||||
<add-channel id="motion-last-updated">
|
||||
<type>hue:last-updated-v2</type>
|
||||
<label>Motion Last Updated</label>
|
||||
<description>The date and time when the motion value was last updated.</description>
|
||||
</add-channel>
|
||||
<add-channel id="temperature-last-updated">
|
||||
<type>hue:last-updated-v2</type>
|
||||
<label>Temperature Last Updated</label>
|
||||
<description>The date and time when the temperature was last updated.</description>
|
||||
</add-channel>
|
||||
<add-channel id="light-level-last-updated">
|
||||
<type>hue:last-updated-v2</type>
|
||||
<label>Light Level Last Updated</label>
|
||||
<description>The date and time when the light level was last updated.</description>
|
||||
</add-channel>
|
||||
<add-channel id="button-last-updated">
|
||||
<type>hue:last-updated-v2</type>
|
||||
<label>Button Last Updated</label>
|
||||
<description>The date and time when a button was last pressed.</description>
|
||||
</add-channel>
|
||||
<add-channel id="rotary-steps-last-updated">
|
||||
<type>hue:last-updated-v2</type>
|
||||
<label>Rotary Steps Last Updated</label>
|
||||
<description>The date and time when the rotary steps were last updated.</description>
|
||||
</add-channel>
|
||||
</instruction-set>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</update:update-descriptions>
|
|
@ -19,7 +19,10 @@ import java.io.FileReader;
|
|||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -55,6 +58,8 @@ import org.openhab.binding.hue.internal.dto.clip2.enums.ResourceType;
|
|||
import org.openhab.binding.hue.internal.dto.clip2.enums.RotationEventType;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.enums.ZigbeeStatus;
|
||||
import org.openhab.binding.hue.internal.dto.clip2.helper.Setters;
|
||||
import org.openhab.binding.hue.internal.serialization.InstantDeserializer;
|
||||
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;
|
||||
|
@ -66,6 +71,7 @@ import org.openhab.core.types.UnDefType;
|
|||
import org.openhab.core.util.ColorUtil;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
@ -79,7 +85,8 @@ import com.google.gson.JsonSyntaxException;
|
|||
@NonNullByDefault
|
||||
class Clip2DtoTest {
|
||||
|
||||
private static final Gson GSON = new Gson();
|
||||
private static final Gson GSON = new GsonBuilder().registerTypeAdapter(Instant.class, new InstantDeserializer())
|
||||
.create();
|
||||
private static final Double MINIMUM_DIMMING_LEVEL = Double.valueOf(12.34f);
|
||||
|
||||
/**
|
||||
|
@ -107,6 +114,24 @@ class Clip2DtoTest {
|
|||
assertNotNull(resources);
|
||||
List<Resource> list = resources.getResources();
|
||||
assertNotNull(list);
|
||||
assertEquals(1, list.size());
|
||||
Resource item = list.get(0);
|
||||
assertEquals(ResourceType.BUTTON, item.getType());
|
||||
Button button = item.getButton();
|
||||
assertNotNull(button);
|
||||
assertEquals(new DecimalType(2003),
|
||||
item.getButtonEventState(Map.of("00000000-0000-0000-0000-000000000001", 2)));
|
||||
assertEquals(new DateTimeType("2023-09-17T18:51:36.959+0000"),
|
||||
item.getButtonLastUpdatedState(ZoneId.of("UTC")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testButtonDeprecated() {
|
||||
String json = load(ResourceType.BUTTON.name().toLowerCase() + "_deprecated");
|
||||
Resources resources = GSON.fromJson(json, Resources.class);
|
||||
assertNotNull(resources);
|
||||
List<Resource> list = resources.getResources();
|
||||
assertNotNull(list);
|
||||
assertEquals(43, list.size());
|
||||
Resource item = list.get(0);
|
||||
assertEquals(ResourceType.BUTTON, item.getType());
|
||||
|
@ -317,6 +342,24 @@ class Clip2DtoTest {
|
|||
Boolean enabled = item.getEnabled();
|
||||
assertNotNull(enabled);
|
||||
assertTrue(enabled);
|
||||
assertEquals(QuantityType.valueOf("1.2792921774337476 lx"), item.getLightLevelState());
|
||||
assertEquals(new DateTimeType("2023-09-11T19:20:02.958+0000"),
|
||||
item.getLightLevelLastUpdatedState(ZoneId.of("UTC")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLightLevelDeprecated() {
|
||||
String json = load(ResourceType.LIGHT_LEVEL.name().toLowerCase() + "_deprecated");
|
||||
Resources resources = GSON.fromJson(json, Resources.class);
|
||||
assertNotNull(resources);
|
||||
List<Resource> list = resources.getResources();
|
||||
assertNotNull(list);
|
||||
assertEquals(1, list.size());
|
||||
Resource item = list.get(0);
|
||||
assertEquals(ResourceType.LIGHT_LEVEL, item.getType());
|
||||
Boolean enabled = item.getEnabled();
|
||||
assertNotNull(enabled);
|
||||
assertTrue(enabled);
|
||||
LightLevel lightLevel = item.getLightLevel();
|
||||
assertNotNull(lightLevel);
|
||||
assertEquals(12725, lightLevel.getLightLevel());
|
||||
|
@ -324,8 +367,8 @@ class Clip2DtoTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testRelativeRotary() {
|
||||
String json = load(ResourceType.RELATIVE_ROTARY.name().toLowerCase());
|
||||
void testRelativeRotaryDeprecated() {
|
||||
String json = load(ResourceType.RELATIVE_ROTARY.name().toLowerCase() + "_deprecated");
|
||||
Resources resources = GSON.fromJson(json, Resources.class);
|
||||
assertNotNull(resources);
|
||||
List<Resource> list = resources.getResources();
|
||||
|
@ -493,6 +536,24 @@ class Clip2DtoTest {
|
|||
Boolean enabled = item.getEnabled();
|
||||
assertNotNull(enabled);
|
||||
assertTrue(enabled);
|
||||
assertEquals(OnOffType.ON, item.getMotionState());
|
||||
assertEquals(new DateTimeType("2023-09-04T20:04:30.395+0000"),
|
||||
item.getMotionLastUpdatedState(ZoneId.of("UTC")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSensor2MotionDeprecated() {
|
||||
String json = load(ResourceType.MOTION.name().toLowerCase() + "_deprecated");
|
||||
Resources resources = GSON.fromJson(json, Resources.class);
|
||||
assertNotNull(resources);
|
||||
List<Resource> list = resources.getResources();
|
||||
assertNotNull(list);
|
||||
assertEquals(1, list.size());
|
||||
Resource item = list.get(0);
|
||||
assertEquals(ResourceType.MOTION, item.getType());
|
||||
Boolean enabled = item.getEnabled();
|
||||
assertNotNull(enabled);
|
||||
assertTrue(enabled);
|
||||
Motion motion = item.getMotion();
|
||||
assertNotNull(motion);
|
||||
assertTrue(motion.isMotion());
|
||||
|
@ -563,6 +624,27 @@ class Clip2DtoTest {
|
|||
assertEquals(1, list.size());
|
||||
Resource item = list.get(0);
|
||||
assertEquals(ResourceType.TEMPERATURE, item.getType());
|
||||
Boolean enabled = item.getEnabled();
|
||||
assertNotNull(enabled);
|
||||
assertTrue(enabled);
|
||||
assertEquals(QuantityType.valueOf("23.34 °C"), item.getTemperatureState());
|
||||
assertEquals(new DateTimeType("2023-09-06T18:22:07.016+0000"),
|
||||
item.getTemperatureLastUpdatedState(ZoneId.of("UTC")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTemperatureDeprecated() {
|
||||
String json = load(ResourceType.TEMPERATURE.name().toLowerCase() + "_deprecated");
|
||||
Resources resources = GSON.fromJson(json, Resources.class);
|
||||
assertNotNull(resources);
|
||||
List<Resource> list = resources.getResources();
|
||||
assertNotNull(list);
|
||||
assertEquals(1, list.size());
|
||||
Resource item = list.get(0);
|
||||
assertEquals(ResourceType.TEMPERATURE, item.getType());
|
||||
Boolean enabled = item.getEnabled();
|
||||
assertNotNull(enabled);
|
||||
assertTrue(enabled);
|
||||
Temperature temperature = item.getTemperature();
|
||||
assertNotNull(temperature);
|
||||
assertEquals(17.2, temperature.getTemperature(), 0.1);
|
||||
|
|
|
@ -1,551 +1,32 @@
|
|||
{
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "d1ae958e-8908-449a-9897-7f10f9b8d4c2",
|
||||
"id_v1": "/sensors/110",
|
||||
"owner": {
|
||||
"rid": "112853f9-c4c4-4d65-ba96-b4c2ab26d94d",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "a83354b7-bae5-4618-8c8d-079c83e0ca2b",
|
||||
"id_v1": "/sensors/236",
|
||||
"owner": {
|
||||
"rid": "cfecbbd0-e918-42a2-b714-2bad33061d95",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "e20d90ae-b2d8-40ea-9905-66bcde9fd863",
|
||||
"id_v1": "/sensors/63",
|
||||
"owner": {
|
||||
"rid": "0e22f8de-eff5-440a-a9ed-06d547d125d7",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "4e61a948-22aa-4332-9b97-76245dd9fb87",
|
||||
"id_v1": "/sensors/6",
|
||||
"owner": {
|
||||
"rid": "b56191ea-8d18-4257-b5d2-cfc3fc86a1ee",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "2f78855c-717a-4b77-8513-dd68ca5337b8",
|
||||
"id_v1": "/sensors/6",
|
||||
"owner": {
|
||||
"rid": "b56191ea-8d18-4257-b5d2-cfc3fc86a1ee",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "7c495cbd-4dd1-4f22-950c-4dd6017b81ec",
|
||||
"id_v1": "/sensors/6",
|
||||
"owner": {
|
||||
"rid": "b56191ea-8d18-4257-b5d2-cfc3fc86a1ee",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "a15c9be9-14b9-4d98-8d9f-989d6cb54496",
|
||||
"id_v1": "/sensors/6",
|
||||
"owner": {
|
||||
"rid": "b56191ea-8d18-4257-b5d2-cfc3fc86a1ee",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "e1e6b2f9-3ace-41ae-b16c-e68f82b5a949",
|
||||
"id_v1": "/sensors/24",
|
||||
"owner": {
|
||||
"rid": "b5fe0539-171c-4733-bf0b-244635a309be",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "717c978e-383d-4900-ab2a-2685983f6174",
|
||||
"id_v1": "/sensors/24",
|
||||
"owner": {
|
||||
"rid": "b5fe0539-171c-4733-bf0b-244635a309be",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "0456ba22-2f1d-4375-8e33-31465420cd96",
|
||||
"id_v1": "/sensors/24",
|
||||
"owner": {
|
||||
"rid": "b5fe0539-171c-4733-bf0b-244635a309be",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "92c00fa4-ae65-462c-9130-a28f5bc52bd9",
|
||||
"id_v1": "/sensors/24",
|
||||
"owner": {
|
||||
"rid": "b5fe0539-171c-4733-bf0b-244635a309be",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "85c18ad0-297d-4fb9-a33a-37f2da70752d",
|
||||
"id_v1": "/sensors/118",
|
||||
"owner": {
|
||||
"rid": "a0509519-3ecb-47d0-9183-25db1e4ea2b2",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "79af0ff1-a4ed-476d-a381-eabd4d3ee6bd",
|
||||
"id_v1": "/sensors/135",
|
||||
"owner": {
|
||||
"rid": "8c5b05ba-b4f4-47b2-8ba0-fc44363192bc",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "8a16c730-094a-4aa1-abd8-9cb758468d62",
|
||||
"id_v1": "/sensors/8",
|
||||
"owner": {
|
||||
"rid": "68ff07d0-6543-4967-9889-e0bc0bc16c31",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "3fed0654-68ec-43e1-b3db-f1a3eba076b9",
|
||||
"id_v1": "/sensors/8",
|
||||
"owner": {
|
||||
"rid": "68ff07d0-6543-4967-9889-e0bc0bc16c31",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "df6e2ba8-94f4-43ce-9bec-72c252616062",
|
||||
"id_v1": "/sensors/8",
|
||||
"owner": {
|
||||
"rid": "68ff07d0-6543-4967-9889-e0bc0bc16c31",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "a46f615d-6760-479c-ba6d-2837a18902e8",
|
||||
"id_v1": "/sensors/8",
|
||||
"owner": {
|
||||
"rid": "68ff07d0-6543-4967-9889-e0bc0bc16c31",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "c34bb678-b910-4a06-8019-3e0ce922f17f",
|
||||
"id_v1": "/sensors/18",
|
||||
"owner": {
|
||||
"rid": "96bec26d-d7c6-4c00-98cd-6f96733296a0",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "286b1b18-ff43-40be-a2ff-b1edc24ecb7c",
|
||||
"id_v1": "/sensors/18",
|
||||
"owner": {
|
||||
"rid": "96bec26d-d7c6-4c00-98cd-6f96733296a0",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "2be1abd3-00a4-4985-b2c9-9bdd4cbe1e4b",
|
||||
"id_v1": "/sensors/18",
|
||||
"owner": {
|
||||
"rid": "96bec26d-d7c6-4c00-98cd-6f96733296a0",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "dc9f1653-11a8-4794-b706-464cf53e9722",
|
||||
"id_v1": "/sensors/18",
|
||||
"owner": {
|
||||
"rid": "96bec26d-d7c6-4c00-98cd-6f96733296a0",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "ac4ebfeb-2045-4698-96de-0b6b5421a1d8",
|
||||
"id_v1": "/sensors/4",
|
||||
"owner": {
|
||||
"rid": "81d9a9d5-228c-45df-828e-0d224929b3d1",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "8a5159f1-93de-4c07-9d32-1fe555fde285",
|
||||
"id_v1": "/sensors/4",
|
||||
"owner": {
|
||||
"rid": "81d9a9d5-228c-45df-828e-0d224929b3d1",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "14debc09-496e-4429-8c22-4975c135bbdf",
|
||||
"id_v1": "/sensors/4",
|
||||
"owner": {
|
||||
"rid": "81d9a9d5-228c-45df-828e-0d224929b3d1",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "9672e2a9-a3a9-4aec-b31e-f2338114b22b",
|
||||
"id_v1": "/sensors/4",
|
||||
"owner": {
|
||||
"rid": "81d9a9d5-228c-45df-828e-0d224929b3d1",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "f385a946-c638-4631-b6a6-c490cf809606",
|
||||
"id_v1": "/sensors/245",
|
||||
"owner": {
|
||||
"rid": "56b560bc-a127-4634-8d80-9946104a4028",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "ba204102-de9f-479e-818a-02ed880caac2",
|
||||
"id_v1": "/sensors/12",
|
||||
"owner": {
|
||||
"rid": "a1155885-4bbe-469f-83bb-f964f8e13e82",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "0032a38b-cf67-478f-934a-520a156a2baf",
|
||||
"id_v1": "/sensors/12",
|
||||
"owner": {
|
||||
"rid": "a1155885-4bbe-469f-83bb-f964f8e13e82",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "4ce58cbd-5d0f-45ec-920d-ad601fd9cc07",
|
||||
"id_v1": "/sensors/12",
|
||||
"owner": {
|
||||
"rid": "a1155885-4bbe-469f-83bb-f964f8e13e82",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "813a331a-f26a-4ab2-948c-9b4c398939d0",
|
||||
"id_v1": "/sensors/12",
|
||||
"owner": {
|
||||
"rid": "a1155885-4bbe-469f-83bb-f964f8e13e82",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "91ba8839-2bac-4175-9f8c-ed192842d549",
|
||||
"id_v1": "/sensors/20",
|
||||
"owner": {
|
||||
"rid": "e130feac-3a5c-452e-a97d-5bca470783b3",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "f95addfc-2f7c-453f-924d-ba496e07e5f9",
|
||||
"id_v1": "/sensors/20",
|
||||
"owner": {
|
||||
"rid": "e130feac-3a5c-452e-a97d-5bca470783b3",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "6615f1f1-f3f1-4a05-b8f7-581097458e34",
|
||||
"id_v1": "/sensors/20",
|
||||
"owner": {
|
||||
"rid": "e130feac-3a5c-452e-a97d-5bca470783b3",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "b0d5a0af-31fd-4189-9150-c551ff9033d7",
|
||||
"id_v1": "/sensors/20",
|
||||
"owner": {
|
||||
"rid": "e130feac-3a5c-452e-a97d-5bca470783b3",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "9d3820db-4a20-4925-80f6-c74582ffb871",
|
||||
"id_v1": "/sensors/26",
|
||||
"owner": {
|
||||
"rid": "e12b3d9c-0b23-4edd-a967-66f5b5cefa92",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "a9e1a40b-a13d-4966-b0b1-2b0b5dfe1986",
|
||||
"id_v1": "/sensors/26",
|
||||
"owner": {
|
||||
"rid": "e12b3d9c-0b23-4edd-a967-66f5b5cefa92",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "8ba063d7-df16-48f5-bb9b-f45849ec1bd3",
|
||||
"id_v1": "/sensors/26",
|
||||
"owner": {
|
||||
"rid": "e12b3d9c-0b23-4edd-a967-66f5b5cefa92",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "4fc9dcd2-6f71-46c4-b3d0-5d7b496be6f9",
|
||||
"id_v1": "/sensors/26",
|
||||
"owner": {
|
||||
"rid": "e12b3d9c-0b23-4edd-a967-66f5b5cefa92",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "824ea347-28d1-4e45-b886-1555a160190b",
|
||||
"id_v1": "/sensors/14",
|
||||
"owner": {
|
||||
"rid": "431026fb-298c-4726-8ce4-47450fea13c4",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "801ede68-21b0-4e6e-98be-eb1a60557ac6",
|
||||
"id_v1": "/sensors/14",
|
||||
"owner": {
|
||||
"rid": "431026fb-298c-4726-8ce4-47450fea13c4",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "1218d0c3-9a9c-4984-84a5-c12ad085ef2d",
|
||||
"id_v1": "/sensors/14",
|
||||
"owner": {
|
||||
"rid": "431026fb-298c-4726-8ce4-47450fea13c4",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "eb2c07bc-1d09-4096-a044-dec29b40619a",
|
||||
"id_v1": "/sensors/14",
|
||||
"owner": {
|
||||
"rid": "431026fb-298c-4726-8ce4-47450fea13c4",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "6bae5b99-349c-4045-8c8f-d4a60562b1d3",
|
||||
"id_v1": "/sensors/124",
|
||||
"owner": {
|
||||
"rid": "f78c5b4b-2f52-4bc3-8097-1ddf97949cc5",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
}
|
||||
]
|
||||
}
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000001",
|
||||
"id_v1": "/sensors/76",
|
||||
"owner": {
|
||||
"rid": "00000000-0000-0000-0000-000000000000",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"button": {
|
||||
"last_event": "long_release",
|
||||
"button_report": {
|
||||
"updated": "2023-09-17T18:51:36.959Z",
|
||||
"event": "long_release"
|
||||
},
|
||||
"repeat_interval": 800,
|
||||
"event_values": [
|
||||
"initial_press",
|
||||
"repeat",
|
||||
"short_release",
|
||||
"long_release",
|
||||
"long_press"
|
||||
]
|
||||
},
|
||||
"type": "button"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,551 @@
|
|||
{
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "d1ae958e-8908-449a-9897-7f10f9b8d4c2",
|
||||
"id_v1": "/sensors/110",
|
||||
"owner": {
|
||||
"rid": "112853f9-c4c4-4d65-ba96-b4c2ab26d94d",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "a83354b7-bae5-4618-8c8d-079c83e0ca2b",
|
||||
"id_v1": "/sensors/236",
|
||||
"owner": {
|
||||
"rid": "cfecbbd0-e918-42a2-b714-2bad33061d95",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "e20d90ae-b2d8-40ea-9905-66bcde9fd863",
|
||||
"id_v1": "/sensors/63",
|
||||
"owner": {
|
||||
"rid": "0e22f8de-eff5-440a-a9ed-06d547d125d7",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "4e61a948-22aa-4332-9b97-76245dd9fb87",
|
||||
"id_v1": "/sensors/6",
|
||||
"owner": {
|
||||
"rid": "b56191ea-8d18-4257-b5d2-cfc3fc86a1ee",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "2f78855c-717a-4b77-8513-dd68ca5337b8",
|
||||
"id_v1": "/sensors/6",
|
||||
"owner": {
|
||||
"rid": "b56191ea-8d18-4257-b5d2-cfc3fc86a1ee",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "7c495cbd-4dd1-4f22-950c-4dd6017b81ec",
|
||||
"id_v1": "/sensors/6",
|
||||
"owner": {
|
||||
"rid": "b56191ea-8d18-4257-b5d2-cfc3fc86a1ee",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "a15c9be9-14b9-4d98-8d9f-989d6cb54496",
|
||||
"id_v1": "/sensors/6",
|
||||
"owner": {
|
||||
"rid": "b56191ea-8d18-4257-b5d2-cfc3fc86a1ee",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "e1e6b2f9-3ace-41ae-b16c-e68f82b5a949",
|
||||
"id_v1": "/sensors/24",
|
||||
"owner": {
|
||||
"rid": "b5fe0539-171c-4733-bf0b-244635a309be",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "717c978e-383d-4900-ab2a-2685983f6174",
|
||||
"id_v1": "/sensors/24",
|
||||
"owner": {
|
||||
"rid": "b5fe0539-171c-4733-bf0b-244635a309be",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "0456ba22-2f1d-4375-8e33-31465420cd96",
|
||||
"id_v1": "/sensors/24",
|
||||
"owner": {
|
||||
"rid": "b5fe0539-171c-4733-bf0b-244635a309be",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "92c00fa4-ae65-462c-9130-a28f5bc52bd9",
|
||||
"id_v1": "/sensors/24",
|
||||
"owner": {
|
||||
"rid": "b5fe0539-171c-4733-bf0b-244635a309be",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "85c18ad0-297d-4fb9-a33a-37f2da70752d",
|
||||
"id_v1": "/sensors/118",
|
||||
"owner": {
|
||||
"rid": "a0509519-3ecb-47d0-9183-25db1e4ea2b2",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "79af0ff1-a4ed-476d-a381-eabd4d3ee6bd",
|
||||
"id_v1": "/sensors/135",
|
||||
"owner": {
|
||||
"rid": "8c5b05ba-b4f4-47b2-8ba0-fc44363192bc",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "8a16c730-094a-4aa1-abd8-9cb758468d62",
|
||||
"id_v1": "/sensors/8",
|
||||
"owner": {
|
||||
"rid": "68ff07d0-6543-4967-9889-e0bc0bc16c31",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "3fed0654-68ec-43e1-b3db-f1a3eba076b9",
|
||||
"id_v1": "/sensors/8",
|
||||
"owner": {
|
||||
"rid": "68ff07d0-6543-4967-9889-e0bc0bc16c31",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "df6e2ba8-94f4-43ce-9bec-72c252616062",
|
||||
"id_v1": "/sensors/8",
|
||||
"owner": {
|
||||
"rid": "68ff07d0-6543-4967-9889-e0bc0bc16c31",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "a46f615d-6760-479c-ba6d-2837a18902e8",
|
||||
"id_v1": "/sensors/8",
|
||||
"owner": {
|
||||
"rid": "68ff07d0-6543-4967-9889-e0bc0bc16c31",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "c34bb678-b910-4a06-8019-3e0ce922f17f",
|
||||
"id_v1": "/sensors/18",
|
||||
"owner": {
|
||||
"rid": "96bec26d-d7c6-4c00-98cd-6f96733296a0",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "286b1b18-ff43-40be-a2ff-b1edc24ecb7c",
|
||||
"id_v1": "/sensors/18",
|
||||
"owner": {
|
||||
"rid": "96bec26d-d7c6-4c00-98cd-6f96733296a0",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "2be1abd3-00a4-4985-b2c9-9bdd4cbe1e4b",
|
||||
"id_v1": "/sensors/18",
|
||||
"owner": {
|
||||
"rid": "96bec26d-d7c6-4c00-98cd-6f96733296a0",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "dc9f1653-11a8-4794-b706-464cf53e9722",
|
||||
"id_v1": "/sensors/18",
|
||||
"owner": {
|
||||
"rid": "96bec26d-d7c6-4c00-98cd-6f96733296a0",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "ac4ebfeb-2045-4698-96de-0b6b5421a1d8",
|
||||
"id_v1": "/sensors/4",
|
||||
"owner": {
|
||||
"rid": "81d9a9d5-228c-45df-828e-0d224929b3d1",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "8a5159f1-93de-4c07-9d32-1fe555fde285",
|
||||
"id_v1": "/sensors/4",
|
||||
"owner": {
|
||||
"rid": "81d9a9d5-228c-45df-828e-0d224929b3d1",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "14debc09-496e-4429-8c22-4975c135bbdf",
|
||||
"id_v1": "/sensors/4",
|
||||
"owner": {
|
||||
"rid": "81d9a9d5-228c-45df-828e-0d224929b3d1",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "9672e2a9-a3a9-4aec-b31e-f2338114b22b",
|
||||
"id_v1": "/sensors/4",
|
||||
"owner": {
|
||||
"rid": "81d9a9d5-228c-45df-828e-0d224929b3d1",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "f385a946-c638-4631-b6a6-c490cf809606",
|
||||
"id_v1": "/sensors/245",
|
||||
"owner": {
|
||||
"rid": "56b560bc-a127-4634-8d80-9946104a4028",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "ba204102-de9f-479e-818a-02ed880caac2",
|
||||
"id_v1": "/sensors/12",
|
||||
"owner": {
|
||||
"rid": "a1155885-4bbe-469f-83bb-f964f8e13e82",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "0032a38b-cf67-478f-934a-520a156a2baf",
|
||||
"id_v1": "/sensors/12",
|
||||
"owner": {
|
||||
"rid": "a1155885-4bbe-469f-83bb-f964f8e13e82",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "4ce58cbd-5d0f-45ec-920d-ad601fd9cc07",
|
||||
"id_v1": "/sensors/12",
|
||||
"owner": {
|
||||
"rid": "a1155885-4bbe-469f-83bb-f964f8e13e82",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "813a331a-f26a-4ab2-948c-9b4c398939d0",
|
||||
"id_v1": "/sensors/12",
|
||||
"owner": {
|
||||
"rid": "a1155885-4bbe-469f-83bb-f964f8e13e82",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "91ba8839-2bac-4175-9f8c-ed192842d549",
|
||||
"id_v1": "/sensors/20",
|
||||
"owner": {
|
||||
"rid": "e130feac-3a5c-452e-a97d-5bca470783b3",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "f95addfc-2f7c-453f-924d-ba496e07e5f9",
|
||||
"id_v1": "/sensors/20",
|
||||
"owner": {
|
||||
"rid": "e130feac-3a5c-452e-a97d-5bca470783b3",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "6615f1f1-f3f1-4a05-b8f7-581097458e34",
|
||||
"id_v1": "/sensors/20",
|
||||
"owner": {
|
||||
"rid": "e130feac-3a5c-452e-a97d-5bca470783b3",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "b0d5a0af-31fd-4189-9150-c551ff9033d7",
|
||||
"id_v1": "/sensors/20",
|
||||
"owner": {
|
||||
"rid": "e130feac-3a5c-452e-a97d-5bca470783b3",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "9d3820db-4a20-4925-80f6-c74582ffb871",
|
||||
"id_v1": "/sensors/26",
|
||||
"owner": {
|
||||
"rid": "e12b3d9c-0b23-4edd-a967-66f5b5cefa92",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "a9e1a40b-a13d-4966-b0b1-2b0b5dfe1986",
|
||||
"id_v1": "/sensors/26",
|
||||
"owner": {
|
||||
"rid": "e12b3d9c-0b23-4edd-a967-66f5b5cefa92",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "8ba063d7-df16-48f5-bb9b-f45849ec1bd3",
|
||||
"id_v1": "/sensors/26",
|
||||
"owner": {
|
||||
"rid": "e12b3d9c-0b23-4edd-a967-66f5b5cefa92",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "4fc9dcd2-6f71-46c4-b3d0-5d7b496be6f9",
|
||||
"id_v1": "/sensors/26",
|
||||
"owner": {
|
||||
"rid": "e12b3d9c-0b23-4edd-a967-66f5b5cefa92",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "824ea347-28d1-4e45-b886-1555a160190b",
|
||||
"id_v1": "/sensors/14",
|
||||
"owner": {
|
||||
"rid": "431026fb-298c-4726-8ce4-47450fea13c4",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "801ede68-21b0-4e6e-98be-eb1a60557ac6",
|
||||
"id_v1": "/sensors/14",
|
||||
"owner": {
|
||||
"rid": "431026fb-298c-4726-8ce4-47450fea13c4",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 2
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "1218d0c3-9a9c-4984-84a5-c12ad085ef2d",
|
||||
"id_v1": "/sensors/14",
|
||||
"owner": {
|
||||
"rid": "431026fb-298c-4726-8ce4-47450fea13c4",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 3
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "eb2c07bc-1d09-4096-a044-dec29b40619a",
|
||||
"id_v1": "/sensors/14",
|
||||
"owner": {
|
||||
"rid": "431026fb-298c-4726-8ce4-47450fea13c4",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 4
|
||||
},
|
||||
"type": "button"
|
||||
},
|
||||
{
|
||||
"id": "6bae5b99-349c-4045-8c8f-d4a60562b1d3",
|
||||
"id_v1": "/sensors/124",
|
||||
"owner": {
|
||||
"rid": "f78c5b4b-2f52-4bc3-8097-1ddf97949cc5",
|
||||
"rtype": "device"
|
||||
},
|
||||
"metadata": {
|
||||
"control_id": 1
|
||||
},
|
||||
"button": {
|
||||
"last_event": "short_release"
|
||||
},
|
||||
"type": "button"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,19 +1,23 @@
|
|||
{
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "18597697-61dc-4090-9bc3-c7f5704f020e",
|
||||
"id_v1": "/sensors/32",
|
||||
"owner": {
|
||||
"rid": "70660557-692d-4d37-8b6b-e3ec63716a72",
|
||||
"rtype": "device"
|
||||
},
|
||||
"enabled": true,
|
||||
"light": {
|
||||
"light_level": 12725,
|
||||
"light_level_valid": true
|
||||
},
|
||||
"type": "light_level"
|
||||
}
|
||||
]
|
||||
}
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000002",
|
||||
"id_v1": "/sensors/4",
|
||||
"owner": {
|
||||
"rid": "00000000-0000-0000-0000-000000000000",
|
||||
"rtype": "device"
|
||||
},
|
||||
"enabled": true,
|
||||
"light": {
|
||||
"light_level": 2578,
|
||||
"light_level_valid": true,
|
||||
"light_level_report": {
|
||||
"changed": "2023-09-11T19:20:02.958Z",
|
||||
"light_level": 3578
|
||||
}
|
||||
},
|
||||
"type": "light_level"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "18597697-61dc-4090-9bc3-c7f5704f020e",
|
||||
"id_v1": "/sensors/32",
|
||||
"owner": {
|
||||
"rid": "70660557-692d-4d37-8b6b-e3ec63716a72",
|
||||
"rtype": "device"
|
||||
},
|
||||
"enabled": true,
|
||||
"light": {
|
||||
"light_level": 12725,
|
||||
"light_level_valid": true
|
||||
},
|
||||
"type": "light_level"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,19 +1,28 @@
|
|||
{
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "97244487-dd25-4f4c-b829-8eb5ffb82c29",
|
||||
"id_v1": "/sensors/30",
|
||||
"owner": {
|
||||
"rid": "70660557-692d-4d37-8b6b-e3ec63716a72",
|
||||
"rtype": "device"
|
||||
},
|
||||
"enabled": true,
|
||||
"motion": {
|
||||
"motion": true,
|
||||
"motion_valid": true
|
||||
},
|
||||
"type": "motion"
|
||||
}
|
||||
]
|
||||
}
|
||||
"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": "2023-09-04T20:04:30.395Z",
|
||||
"motion": true
|
||||
}
|
||||
},
|
||||
"sensitivity": {
|
||||
"status": "set",
|
||||
"sensitivity": 2,
|
||||
"sensitivity_max": 4
|
||||
},
|
||||
"type": "motion"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "97244487-dd25-4f4c-b829-8eb5ffb82c29",
|
||||
"id_v1": "/sensors/30",
|
||||
"owner": {
|
||||
"rid": "70660557-692d-4d37-8b6b-e3ec63716a72",
|
||||
"rtype": "device"
|
||||
},
|
||||
"enabled": true,
|
||||
"motion": {
|
||||
"motion": true,
|
||||
"motion_valid": true
|
||||
},
|
||||
"type": "motion"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,24 +1 @@
|
|||
{
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "12345678-7bd4d062-a33f-40e3-a7c0-91f64c39ac1a",
|
||||
"id_v1": "/sensors/2",
|
||||
"owner": {
|
||||
"rid": "497051e4-29c3-419b-babd-d916cffcf3a1",
|
||||
"rtype": "device"
|
||||
},
|
||||
"relative_rotary": {
|
||||
"last_event": {
|
||||
"action": "repeat",
|
||||
"rotation": {
|
||||
"direction": "clock_wise",
|
||||
"duration": 400,
|
||||
"steps": 30
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "relative_rotary"
|
||||
}
|
||||
]
|
||||
}
|
||||
{}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "12345678-7bd4d062-a33f-40e3-a7c0-91f64c39ac1a",
|
||||
"id_v1": "/sensors/2",
|
||||
"owner": {
|
||||
"rid": "497051e4-29c3-419b-babd-d916cffcf3a1",
|
||||
"rtype": "device"
|
||||
},
|
||||
"relative_rotary": {
|
||||
"last_event": {
|
||||
"action": "repeat",
|
||||
"rotation": {
|
||||
"direction": "clock_wise",
|
||||
"duration": 400,
|
||||
"steps": 30
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "relative_rotary"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,19 +1,23 @@
|
|||
{
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "f5f8010d-8356-4604-88dc-4f73912cbb6a",
|
||||
"id_v1": "/sensors/33",
|
||||
"owner": {
|
||||
"rid": "70660557-692d-4d37-8b6b-e3ec63716a72",
|
||||
"rtype": "device"
|
||||
},
|
||||
"enabled": true,
|
||||
"temperature": {
|
||||
"temperature": 17.26,
|
||||
"temperature_valid": true
|
||||
},
|
||||
"type": "temperature"
|
||||
}
|
||||
]
|
||||
}
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000004",
|
||||
"id_v1": "/sensors/5",
|
||||
"owner": {
|
||||
"rid": "00000000-0000-0000-0000-000000000000",
|
||||
"rtype": "device"
|
||||
},
|
||||
"enabled": true,
|
||||
"temperature": {
|
||||
"temperature": 23.35,
|
||||
"temperature_valid": true,
|
||||
"temperature_report": {
|
||||
"changed": "2023-09-06T18:22:07.016Z",
|
||||
"temperature": 23.34
|
||||
}
|
||||
},
|
||||
"type": "temperature"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"errors": [],
|
||||
"data": [
|
||||
{
|
||||
"id": "f5f8010d-8356-4604-88dc-4f73912cbb6a",
|
||||
"id_v1": "/sensors/33",
|
||||
"owner": {
|
||||
"rid": "70660557-692d-4d37-8b6b-e3ec63716a72",
|
||||
"rtype": "device"
|
||||
},
|
||||
"enabled": true,
|
||||
"temperature": {
|
||||
"temperature": 17.26,
|
||||
"temperature_valid": true
|
||||
},
|
||||
"type": "temperature"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue