Skip to content

Commit 1702631

Browse files
authored
[hue] Add channels for time of last sensor update (API v2) (openhab#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 openhab#15546 Signed-off-by: Jacob Laursen <[email protected]>
1 parent bdba338 commit 1702631

31 files changed

+1463
-682
lines changed

bundles/org.openhab.binding.hue/doc/readme_v2.md

+29-24
Original file line numberDiff line numberDiff line change
@@ -59,30 +59,35 @@ The configuration of all things (as described above) is the same regardless of w
5959

6060
Device things support some of the following channels:
6161

62-
| Channel ID | Item Type | Description |
63-
|-----------------------|--------------------|---------------------------------------------------------------------------------------------------------------------|
64-
| color | Color | Supports full color control with hue, saturation and brightness values, or brightness only, or switching on or off. |
65-
| brightness | Dimmer | Supports control of the brightness value, or switching on or off. |
66-
| color-temperature | Dimmer | Supports control of the color temperature in percent from cold (0%) to warm (100%). |
67-
| color-temperature-abs | Number:Temperature | Supports control of the color temperature via a QuantityType having a temperature unit e.g. Kelvin. (Advanced) |
68-
| switch | Switch | Supports switching the device on and off. |
69-
| dynamics | Number:Time | Sets the duration of dynamic transitions between light states. (Advanced) |
70-
| alert | String | Allows setting an alert on a light e.g. flashing them. (Advanced) |
71-
| effect | String | Allows setting an effect on a light e.g. 'candle' effect. (Advanced) |
72-
| button-last-event | (String) | Informs which button was last pressed in the device. (Trigger Channel) |
73-
| rotary-steps | (String) | Informs about the number of rotary steps of the last rotary dial movement. (Trigger Channel) |
74-
| motion | Switch | Shows if motion has been detected by the sensor. (Read Only) |
75-
| motion-enabled | Switch | Supports enabling / disabling the motion sensor. (Advanced) |
76-
| light-level | Number:Illuminance | Shows the current light level measured by the sensor. (Read Only) |
77-
| light-level-enabled | Switch | Supports enabling / disabling the light level sensor. (Advanced) |
78-
| temperature | Number:Temperature | Shows the current temperature measured by the sensor. (Read Only) |
79-
| temperature-enabled | Switch | Supports enabling / disabling the temperature sensor. (Advanced) |
80-
| battery-level | Number | Shows the battery level. (Read Only) |
81-
| battery-low | Switch | Indicates whether the battery is low or not. (Read Only) |
82-
| last-updated | DateTime | The date and time when the thing state was last updated. (Read Only) (Advanced) |
83-
| 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. |
84-
| dimming-only | Dimmer | Allows access to the `dimming` parameter of the light(s) only. Has no impact on `color-xy` or `on-off` parameters. |
85-
| 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. |
62+
| Channel ID | Item Type | Description |
63+
|---------------------------|--------------------|---------------------------------------------------------------------------------------------------------------------|
64+
| color | Color | Supports full color control with hue, saturation and brightness values, or brightness only, or switching on or off. |
65+
| brightness | Dimmer | Supports control of the brightness value, or switching on or off. |
66+
| color-temperature | Dimmer | Supports control of the color temperature in percent from cold (0%) to warm (100%). |
67+
| color-temperature-abs | Number:Temperature | Supports control of the color temperature via a QuantityType having a temperature unit e.g. Kelvin. (Advanced) |
68+
| switch | Switch | Supports switching the device on and off. |
69+
| dynamics | Number:Time | Sets the duration of dynamic transitions between light states. (Advanced) |
70+
| alert | String | Allows setting an alert on a light e.g. flashing them. (Advanced) |
71+
| effect | String | Allows setting an effect on a light e.g. 'candle' effect. (Advanced) |
72+
| button-last-event | (String) | Informs which button was last pressed in the device. (Trigger Channel) |
73+
| button-last-updated | DateTime | The date and time when a button was last pressed. (Read Only) (Advanced) |
74+
| rotary-steps | (String) | Informs about the number of rotary steps of the last rotary dial movement. (Trigger Channel) |
75+
| rotary-steps-last-updated | DateTime | The date and time when the rotary steps were last updated. (Read Only) (Advanced) |
76+
| motion | Switch | Shows if motion has been detected by the sensor. (Read Only) |
77+
| motion-enabled | Switch | Supports enabling / disabling the motion sensor. (Advanced) |
78+
| motion-last-updated | DateTime | The date and time when the motion value was last updated. (Read Only) (Advanced) |
79+
| light-level | Number:Illuminance | Shows the current light level measured by the sensor. (Read Only) |
80+
| light-level-last-updated | DateTime | The date and time when the light level was last updated. (Read Only) (Advanced) |
81+
| light-level-enabled | Switch | Supports enabling / disabling the light level sensor. (Advanced) |
82+
| temperature | Number:Temperature | Shows the current temperature measured by the sensor. (Read Only) |
83+
| temperature-last-updated | DateTime | The date and time when the temperature was last updated. (Read Only) (Advanced) |
84+
| temperature-enabled | Switch | Supports enabling / disabling the temperature sensor. (Advanced) |
85+
| battery-level | Number | Shows the battery level. (Read Only) |
86+
| battery-low | Switch | Indicates whether the battery is low or not. (Read Only) |
87+
| last-updated | DateTime | The date and time when the thing state was last updated. (Read Only) (Advanced) |
88+
| 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. |
89+
| dimming-only | Dimmer | Allows access to the `dimming` parameter of the light(s) only. Has no impact on `color-xy` or `on-off` parameters. |
90+
| 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. |
8691

8792
The exact list of channels in a given device is determined at run time when the system is started.
8893
Each device reports its own live list of capabilities, and the respective list of channels is created accordingly.

bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueBindingConstants.java

+5
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,17 @@ public class HueBindingConstants {
151151
public static final String CHANNEL_2_ALERT = CHANNEL_ALERT;
152152
public static final String CHANNEL_2_EFFECT = CHANNEL_EFFECT;
153153
public static final String CHANNEL_2_BUTTON_LAST_EVENT = "button-last-event";
154+
public static final String CHANNEL_2_BUTTON_LAST_UPDATED = "button-last-updated";
154155
public static final String CHANNEL_2_ROTARY_STEPS = "rotary-steps";
156+
public static final String CHANNEL_2_ROTARY_STEPS_LAST_UPDATED = "rotary-steps-last-updated";
155157
public static final String CHANNEL_2_MOTION = "motion";
158+
public static final String CHANNEL_2_MOTION_LAST_UPDATED = "motion-last-updated";
156159
public static final String CHANNEL_2_MOTION_ENABLED = "motion-enabled";
157160
public static final String CHANNEL_2_LIGHT_LEVEL = "light-level";
161+
public static final String CHANNEL_2_LIGHT_LEVEL_LAST_UPDATED = "light-level-last-updated";
158162
public static final String CHANNEL_2_LIGHT_LEVEL_ENABLED = "light-level-enabled";
159163
public static final String CHANNEL_2_TEMPERATURE = CHANNEL_TEMPERATURE;
164+
public static final String CHANNEL_2_TEMPERATURE_LAST_UPDATED = "temperature-last-updated";
160165
public static final String CHANNEL_2_TEMPERATURE_ENABLED = "temperature-enabled";
161166
public static final String CHANNEL_2_BATTERY_LEVEL = "battery-level";
162167
public static final String CHANNEL_2_BATTERY_LOW = "battery-low";

bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/connection/Clip2Bridge.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,14 @@
8181
import org.openhab.binding.hue.internal.exceptions.ApiException;
8282
import org.openhab.binding.hue.internal.exceptions.HttpUnauthorizedException;
8383
import org.openhab.binding.hue.internal.handler.Clip2BridgeHandler;
84+
import org.openhab.binding.hue.internal.serialization.InstantDeserializer;
8485
import org.openhab.core.io.net.http.HttpClientFactory;
8586
import org.openhab.core.io.net.http.HttpUtil;
8687
import org.slf4j.Logger;
8788
import org.slf4j.LoggerFactory;
8889

8990
import com.google.gson.Gson;
91+
import com.google.gson.GsonBuilder;
9092
import com.google.gson.JsonArray;
9193
import com.google.gson.JsonElement;
9294
import com.google.gson.JsonParseException;
@@ -556,7 +558,8 @@ public static boolean isClip2Supported(String hostName) throws IOException {
556558
private final String registrationUrl;
557559
private final String applicationKey;
558560
private final Clip2BridgeHandler bridgeHandler;
559-
private final Gson jsonParser = new Gson();
561+
private final Gson jsonParser = new GsonBuilder().registerTypeAdapter(Instant.class, new InstantDeserializer())
562+
.create();
560563
private final Semaphore streamMutex = new Semaphore(MAX_CONCURRENT_STREAMS, true); // i.e. fair
561564
private final ReadWriteLock sessionUseCreateLock = new ReentrantReadWriteLock(true); // i.e. fair
562565
private final Map<Integer, Future<?>> fatalErrorTasks = new ConcurrentHashMap<>();

bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/dto/clip2/Button.java

+18-7
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
*/
1313
package org.openhab.binding.hue.internal.dto.clip2;
1414

15-
import java.util.Objects;
16-
1715
import org.eclipse.jdt.annotation.NonNullByDefault;
1816
import org.eclipse.jdt.annotation.Nullable;
1917
import org.openhab.binding.hue.internal.dto.clip2.enums.ButtonEventType;
@@ -28,16 +26,29 @@
2826
@NonNullByDefault
2927
public class Button {
3028
private @Nullable @SerializedName("last_event") String lastEvent;
29+
private @Nullable @SerializedName("button_report") ButtonReport buttonReport;
30+
private @SerializedName("repeat_interval") int repeatInterval;
3131

3232
/**
33-
* @return the last button event as an enum.
34-
* @throws IllegalArgumentException if lastEvent is null or bad.
33+
* The underlying field is deprecated in the CLIP 2 API.
34+
* Moved to button_report/event
35+
*
36+
* @return the last button event as an enum (null if none or invalid).
3537
*/
36-
public ButtonEventType getLastEvent() throws IllegalArgumentException {
38+
public @Nullable ButtonEventType getLastEvent() {
3739
String lastEvent = this.lastEvent;
38-
if (Objects.nonNull(lastEvent)) {
40+
if (lastEvent == null) {
41+
return null;
42+
}
43+
44+
try {
3945
return ButtonEventType.valueOf(lastEvent.toUpperCase());
46+
} catch (IllegalArgumentException e) {
47+
return null;
4048
}
41-
throw new IllegalArgumentException("lastEvent field is null");
49+
}
50+
51+
public @Nullable ButtonReport getButtonReport() {
52+
return buttonReport;
4253
}
4354
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Copyright (c) 2010-2023 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.binding.hue.internal.dto.clip2;
14+
15+
import java.time.Instant;
16+
17+
import org.eclipse.jdt.annotation.NonNullByDefault;
18+
import org.eclipse.jdt.annotation.Nullable;
19+
import org.openhab.binding.hue.internal.dto.clip2.enums.ButtonEventType;
20+
21+
/**
22+
* DTO for CLIP 2 button report.
23+
*
24+
* @author Jacob Laursen - Initial contribution
25+
*/
26+
@NonNullByDefault
27+
public class ButtonReport {
28+
private @NonNullByDefault({}) Instant updated;
29+
private @Nullable String event;
30+
31+
/**
32+
* @return last time the value of this property is updated.
33+
*/
34+
public Instant getLastChanged() {
35+
return updated;
36+
}
37+
38+
/**
39+
* @return event which can be sent by a button control (null if none or invalid).
40+
*/
41+
public @Nullable ButtonEventType getLastEvent() {
42+
String event = this.event;
43+
if (event == null) {
44+
return null;
45+
}
46+
47+
try {
48+
return ButtonEventType.valueOf(event.toUpperCase());
49+
} catch (IllegalArgumentException e) {
50+
return null;
51+
}
52+
}
53+
}

bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/dto/clip2/LightLevel.java

+16
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
package org.openhab.binding.hue.internal.dto.clip2;
1414

1515
import org.eclipse.jdt.annotation.NonNullByDefault;
16+
import org.eclipse.jdt.annotation.Nullable;
1617
import org.openhab.core.library.types.OnOffType;
1718
import org.openhab.core.library.types.QuantityType;
1819
import org.openhab.core.library.unit.Units;
@@ -30,11 +31,22 @@
3031
public class LightLevel {
3132
private @SerializedName("light_level") int lightLevel;
3233
private @SerializedName("light_level_valid") boolean lightLevelValid;
34+
private @Nullable @SerializedName("light_level_report") LightLevelReport lightLevelReport;
3335

36+
/**
37+
* The underlying field is deprecated in the CLIP 2 API.
38+
* Moved to light_level_report/light_level
39+
* Should be used only as fallback for older firmwares.
40+
*/
3441
public int getLightLevel() {
3542
return lightLevel;
3643
}
3744

45+
/**
46+
* The underlying field is deprecated in the CLIP 2 API.
47+
* Indication whether the value presented in light_level is valid
48+
* Should be used only as fallback for older firmwares.
49+
*/
3850
public boolean isLightLevelValid() {
3951
return lightLevelValid;
4052
}
@@ -56,4 +68,8 @@ public State getLightLevelState() {
5668
public State isLightLevelValidState() {
5769
return OnOffType.from(lightLevelValid);
5870
}
71+
72+
public @Nullable LightLevelReport getLightLevelReport() {
73+
return lightLevelReport;
74+
}
5975
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Copyright (c) 2010-2023 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.binding.hue.internal.dto.clip2;
14+
15+
import java.time.Instant;
16+
17+
import org.eclipse.jdt.annotation.NonNullByDefault;
18+
19+
import com.google.gson.annotations.SerializedName;
20+
21+
/**
22+
* DTO for CLIP 2 light level sensor report.
23+
*
24+
* @author Jacob Laursen - Initial contribution
25+
*/
26+
@NonNullByDefault
27+
public class LightLevelReport {
28+
private @NonNullByDefault({}) Instant changed;
29+
private @SerializedName("light_level") int lightLevel;
30+
31+
/**
32+
* @return last time the value of this property is changed.
33+
*/
34+
public Instant getLastChanged() {
35+
return changed;
36+
}
37+
38+
/**
39+
* Light level in 10000*log10(lux) +1 measured by sensor.
40+
* Logarithmic scale used because the human eye adjusts to light levels and small changes at low lux levels
41+
* are more noticeable than at high lux levels. This allows use of linear scale configuration sliders.
42+
*
43+
* @return light level in 10000*log10(lux) +1 measured by sensor
44+
*/
45+
public int getLightLevel() {
46+
return lightLevel;
47+
}
48+
}

bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/dto/clip2/Motion.java

+18
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
package org.openhab.binding.hue.internal.dto.clip2;
1414

1515
import org.eclipse.jdt.annotation.NonNullByDefault;
16+
import org.eclipse.jdt.annotation.Nullable;
1617
import org.openhab.core.library.types.OnOffType;
1718
import org.openhab.core.types.State;
1819
import org.openhab.core.types.UnDefType;
@@ -28,11 +29,24 @@
2829
public class Motion {
2930
private boolean motion;
3031
private @SerializedName("motion_valid") boolean motionValid;
32+
private @Nullable @SerializedName("motion_report") MotionReport motionReport;
3133

34+
/**
35+
* The underlying field is deprecated in the CLIP 2 API.
36+
* Moved to motion_report/motion.
37+
* Should be used only as fallback for older firmwares.
38+
*
39+
* @return true if motion is detected
40+
*/
3241
public boolean isMotion() {
3342
return motion;
3443
}
3544

45+
/**
46+
* The underlying field is deprecated in the CLIP 2 API.
47+
* Motion is valid when motion_report property is present, invalid when absent.
48+
* Should be used only as fallback for older firmwares.
49+
*/
3650
public boolean isMotionValid() {
3751
return motionValid;
3852
}
@@ -44,4 +58,8 @@ public State getMotionState() {
4458
public State getMotionValidState() {
4559
return OnOffType.from(motionValid);
4660
}
61+
62+
public @Nullable MotionReport getMotionReport() {
63+
return motionReport;
64+
}
4765
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright (c) 2010-2023 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.binding.hue.internal.dto.clip2;
14+
15+
import java.time.Instant;
16+
17+
import org.eclipse.jdt.annotation.NonNullByDefault;
18+
19+
/**
20+
* DTO for CLIP 2 motion sensor report.
21+
*
22+
* @author Jacob Laursen - Initial contribution
23+
*/
24+
@NonNullByDefault
25+
public class MotionReport {
26+
private @NonNullByDefault({}) Instant changed;
27+
private boolean motion;
28+
29+
/**
30+
* @return last time the value of this property is changed.
31+
*/
32+
public Instant getLastChanged() {
33+
return changed;
34+
}
35+
36+
/**
37+
* @return true if motion is detected
38+
*/
39+
public boolean isMotion() {
40+
return motion;
41+
}
42+
}

0 commit comments

Comments
 (0)