[dirigera] Add device set support - #20691
Conversation
Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com> add unit test & bugfixing Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR adds native support to the DIRIGERA binding for IKEA “deviceSet” light groups (“Light Sets”), enabling group-level commands to be sent via the dedicated /devices/set/{id} endpoint and discovering these sets as their own Things.
Changes:
- Add a new
light-setThing type (XML + i18n + README) and handler (LightSetHandler) to control grouped lights as one unit. - Extend the model to discover light-set IDs embedded in member devices and expose member device IDs for set initialization/status.
- Add REST API support for patching device sets and introduce tests validating endpoint routing and basic channel behavior.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| bundles/org.openhab.binding.dirigera/src/test/java/org/openhab/binding/dirigera/internal/model/TestModel.java | Updates discovery count expectations to include discovered light sets. |
| bundles/org.openhab.binding.dirigera/src/test/java/org/openhab/binding/dirigera/internal/mock/DirigeraAPISimu.java | Adds simulated /devices/set/{id} patch handling and a non-blocking patch peek helper for tests. |
| bundles/org.openhab.binding.dirigera/src/test/java/org/openhab/binding/dirigera/internal/handler/lights/TestLightSet.java | New tests for light-set handler creation, refresh/state behavior, and correct endpoint routing. |
| bundles/org.openhab.binding.dirigera/src/main/resources/OH-INF/thing/light-set.xml | Introduces the light-set thing type and channels. |
| bundles/org.openhab.binding.dirigera/src/main/resources/OH-INF/i18n/dirigera.properties | Adds i18n keys for the new light-set thing type and channels. |
| bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/network/DirigeraAPIImpl.java | Implements sendSetAttributes to PATCH device sets via /devices/set/{id}. |
| bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/model/DirigeraModel.java | Discovers light-set IDs from deviceSet arrays and provides set metadata/member lookup. |
| bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/interfaces/ThingStatusListener.java | Adds a placeholder interface for future status-listener expansion. |
| bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/interfaces/Model.java | Adds constants and a getMemberDeviceIds(setId) API for light sets. |
| bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/interfaces/DirigeraAPI.java | Extends the API interface with sendSetAttributes. |
| bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/handler/light/LightSetHandler.java | New handler implementing light-set status aggregation and routing commands to set endpoint. |
| bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/handler/light/BaseLight.java | Switches to polymorphic sendAttributes() to allow light-set override to work. |
| bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/handler/BaseHandler.java | Adds a sendSetAttributes wrapper for the new API call. |
| bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/DirigeraHandlerFactory.java | Registers LightSetHandler for the new thing type. |
| bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/Constants.java | Adds new thing type UID, endpoint URL constant, and attribute-to-channel mapping for light sets. |
| bundles/org.openhab.binding.dirigera/README.md | Documents the new light-set Thing, channels, and behavior caveats. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
15b93b3 to
f338617
Compare
Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com> fix unit test Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com> fix unit test Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com> fix unit test Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
f338617 to
70c7e26
Compare
Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (6)
bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/handler/light/LightSetHandler.java:169
- This always forwards member attributes to the light handler even when the update came from a member that just reported
isReachable=false. If another member is still reachable,onlineis set to true before the delegate call, soBaseHandler/light handlers can overwrite the set's power/brightness/color with stale data from the unreachable bulb. Skip delegating attributes for unreachable member updates (or only delegate when the source member is reachable).
super.handleUpdate(stripped);
bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/handler/light/LightSetHandler.java:140
- The copy here is shallow: the nested
attributesobject is shared withupdate, so removingcustomNamemutates the original websocket payload.DirigeraHandlerpasses the sameJSONObjectinstance to every handler registered for a device ID, so if a light-set handler runs before the member's own handler, the member handler will no longer see itscustomNameupdate. Create a deep copy of the attributes object before stripping fields.
JSONObject stripped = new JSONObject(update, update.keySet().toArray(new String[0]));
// strip customName for each member update
if (update.has(JSON_KEY_ATTRIBUTES)) {
stripped.getJSONObject(JSON_KEY_ATTRIBUTES).remove(ATTRIBUTES_KEY_CUSTOM_NAME);
}
bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/handler/light/LightSetHandler.java:184
- Disposing a light-set unregisters each member ID, but the gateway's current unregister implementation removes the whole
deviceTreeentry for that ID rather than only this handler. If a member bulb also has its own thing handler, disposing the set stops websocket updates for that bulb until it re-registers. Either fix unregister to remove only the supplied handler or avoid unregistering shared member IDs here.
memberDeviceIds.forEach(memberId -> {
try {
gateway().unregisterDevice(child, memberId);
bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/handler/light/LightSetHandler.java:103
- Registering each member ID through
gateway().registerDevice(...)also adds that member ID to the gateway's persistedknownDeviceslist. If a user adds only the light-set thing, its bulbs become marked as known even though they do not have their own thing handlers, so discovery will stop offering those bulbs (and the entries remain after dispose because unregister does not remove known devices). Use a subscription path that does not persist member IDs as known devices, or change registration to distinguish aliases from real things.
gateway().registerDevice(child, config.id);
memberDeviceIds.forEach(memberId -> gateway().registerDevice(child, memberId));
bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/handler/light/LightSetHandler.java:73
- This status description is a raw English string, unlike the other device status messages in this binding that use
@text/...keys for localization. Add an i18n entry and reference it here so the OFFLINE reason is localizable like the surrounding status messages.
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"No member devices found for light set");
bundles/org.openhab.binding.dirigera/src/main/java/org/openhab/binding/dirigera/internal/handler/light/LightSetHandler.java:95
- This synthetic update does not actually initialize the set name:
LightSetHandler.handleUpdate()unconditionally removescustomNamefrom every update before delegating toBaseHandler, so thecustom-namechannel remains unset. Only stripcustomNamefor member-device updates (or set the channel directly here) so the light-set name from metadata is published.
JSONObject nameInit = new JSONObject();
JSONObject attributes = new JSONObject();
attributes.put(ATTRIBUTES_KEY_CUSTOM_NAME, nameStr);
nameInit.put(JSON_KEY_ATTRIBUTES, attributes);
super.handleUpdate(nameInit);
* initial contribution Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
* initial contribution Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
* initial contribution Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com>
* initial contribution Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com> Signed-off-by: olemr <olemr@olemr.com>
* initial contribution Signed-off-by: Bernd Weymann <bernd.weymann@gmail.com> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
DIRIGERA gateway allows to organize light bulbs / LED strips in a
Set. This native support allows to change light settings immediately to a set of lights without delay.Setsare defined in IKEA Home smart app and they are now supported via discovery. Managing these (add / delete / modify) stays in the app, no openHAB support.Fixes #20101