Skip to content

refactor: use dirigera 1.6.0 instead of local model patches - #67

Merged
nrbrt merged 1 commit into
nrbrt:mainfrom
Leggin:use-dirigera-1.6.0
Oct 26, 2026
Merged

nrbrt merged 1 commit into
nrbrt:mainfrom
Leggin:use-dirigera-1.6.0

Conversation

@Leggin

@Leggin Leggin commented Oct 23, 2026

Copy link
Copy Markdown

Describe your changes

I maintain the dirigera library. Several things this integration patches around in dirigera_lib_patch.py, or works around with direct PATCH calls, are covered by the library now, so this bumps it to 1.6.0 (released today) and uses it instead. dirigera_lib_patch.py shrinks by about 120 lines.

  • Lights: the library's Light keeps colorMode as attributes.color_mode since 1.6.0 (Add color_mode to lights and make motion sensor is_on optional Leggin/dirigera#148). Removes LightX, LightAttributesX, dict_to_light_x and the HubX.get_lights / get_light_by_id overrides. The hs-first fallback in set_state() stays for bulbs that don't report colorMode.
  • Motion sensors: MotionSensorAttributes.is_on is optional since 1.6.0, so MYGGSPRAY parses as a plain MotionSensor. Removes MotionSensorX / MotionSensorAttributesX. HubX.get_motion_sensors still includes occupancySensor devices, and runtime discovery uses the library's dict_to_motion_sensor.
  • Controllers: ControllerX was identical to the library's Controller (same optional fields and methods since dirigera 1.2), so it and the get_controllers override are removed.
  • Colour temperature: the single-bulb path calls Light.set_color_temperature() instead of PATCHing the hub directly. The bypass was there for "library validation issues", which were fixed in the library (mired bounds, Fix color temperature range check for bulbs reporting mired bounds Leggin/dirigera#137). min_color_temp_kelvin / max_color_temp_kelvin now use the library's rule: bounds below 1000 are mireds and get converted, and the order doesn't matter. Before, a KAJPLATS reporting 153..454 showed up in HA as 454..153 "Kelvin". Requests are clamped to that range. The manual write-through to the model goes away because the library updates it.
  • Blinds stop: _send_stop uses Blind.set_state(BlindsStateEnum.STOPPED) (dirigera ≥ 1.3.0) instead of its own PATCH.
  • Outlets: HubX.get_outlets selects outlets by deviceType instead of type. On some firmware the metering half of a GRILLPLATS also has type: "outlet", and parsing it as an Outlet failed on the missing isOn (get_outlets() fails for new IKEA GRILLPLATS plug: missing attributes.isOn Leggin/dirigera#131). The library made the same fix in 1.3.0, but this override kept the old filter. The energy merge is unchanged.

Not changed: Matter filtering, the /devices batch cache, TIMMERFLOTTE merging, the energy merge into outlets, the empty scenes for controller triggers, HackScene, and device sets, which still PATCH directly because the library has no device-set API.

One behaviour difference: a bulb that accepts colorTemperature but reports no min/max now gets the library's ValueError instead of an unchecked PATCH. IKEA bulbs report the range.

Tests

  • Full suite: 102 passed with dirigera==1.6.0, python-dateutil, pytest and pytest-asyncio. With dirigera==1.2.6 installed, the 7 tests that use the real library fail, so the new pin is needed.
  • New tests/test_light_color_temp_range.py checks the range for Kelvin bounds in either order and for mired bounds. It also checks that the library accepts the whole range HA is offered and rejects values just outside it, so the two can't drift apart.
  • tests/test_light_color_mode.py: the LightX tests are replaced by tests on the library Light: it keeps colorMode, reports None without it, and accepts the listener's writes. The set_state() tests are unchanged.
  • tests/test_blinds_stop.py: the fake blind gets a set_state() that behaves like the library's (PATCH first, then the model). The test now also asserts BlindsStateEnum.STOPPED.
  • I also ran HubX against hub-shaped payloads on 1.2.6 (before) and 1.6.0 (after): lights, controllers, motion sensors including a MYGGSPRAY without isOn, empty-scene creation, and a GRILLPLATS whose metering half has type: "outlet". That last one raised a ValidationError before this change and works now. Everything else gave identical results.
  • Not tested on a real hub or inside Home Assistant. It would be good to try a colour-temperature change and a blinds stop on real hardware before merging.

Checklist before submitting a pull request

  • Updated base lib and added the required version in the requirements.txt and manifest.json

Checklist for reviewer

  • Select "Squash and merge" to keep commit timeline clean

dirigera 1.6.0 covers several things this integration patched around,
so bump it and rely on the library:

- lights keep colorMode as attributes.color_mode: drop LightX and the
  HubX.get_lights / get_light_by_id overrides
- motion sensor is_on is optional, so MYGGSPRAY parses as MotionSensor:
  drop MotionSensorX (get_motion_sensors still includes occupancySensor)
- ControllerX was identical to the library's Controller: drop it and the
  get_controllers override
- set colour temperature with Light.set_color_temperature() instead of a
  direct PATCH; report the Kelvin range with the library's mired rule
  and clamp requests to it
- stop blinds with Blind.set_state(BlindsStateEnum.STOPPED)
- select outlets by deviceType, so a GRILLPLATS metering half with type
  "outlet" no longer fails to parse (missing isOn)
@nrbrt
nrbrt merged commit e002855 into nrbrt:main Oct 26, 2026
nrbrt added a commit that referenced this pull request Oct 26, 2026
)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016G9Pu8TcL6HFd6wuvdY3ca
@nrbrt

nrbrt commented Oct 26, 2026

Copy link
Copy Markdown
Owner

Thanks, this is a welcome cleanup. I merged it on top of v0.3.24 and released it as v0.3.25. Tested on a real hub with colour-temperature changes on a TRÅDFRI colour bulb (2700 K, 4000 K, an out-of-range 6500 K clamped to 4000 K, and 3000 K confirmed in the hub's state); no errors in the log. I couldn't test the blinds stop, we have no blinds here.

nrbrt pushed a commit that referenced this pull request Oct 26, 2026
get_environment_sensors() merged a TIMMERFLOTTE pair into whichever half
the hub listed first. When the humidity half (<rel>_2) comes first, the
merged sensor takes its id, generic name and empty room, and
get_environment_sensor_by_id(<rel>_1) raises ValueError on refresh.

Sort each relationId group so the half with the temperature, the room and
the _1 suffix wins, deep-copy instead of writing into the /devices
response, and inherit the room from the other half if the primary lacks
one. Adds tests/test_split_environment_sensor.py, which fails on the old
merge for the reversed order and passes for the order real hubs use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Squashed from PR #57; the import conflict with #67 resolved on merge.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016G9Pu8TcL6HFd6wuvdY3ca
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants