Add Matter support (generic event-entity connection type) + IKEA BILRESA scroll wheel - #59
Open
tz8 wants to merge 10 commits into
Open
Add Matter support (generic event-entity connection type) + IKEA BILRESA scroll wheel#59tz8 wants to merge 10 commits into
tz8 wants to merge 10 commits into
Conversation
Matter remotes (e.g. IKEA BILRESA scroll wheel) do not fire a dedicated bus
event like zha_event/deconz_event. They surface as Home Assistant event.*
entities, where a button press is a state_changed and the action lives in
new_state.attributes.event_type. Neither existing intake path (MQTT topic or
bus event matched by identifier_key) could handle this.
Adds a third, generic connection type keyed on `event_type: state_changed`:
- schema.py: BLUEPRINT_STATE_SCHEMA (optional `state_domain`, default `event`)
- __init__.py: blueprint schema dispatch recognises `state_changed`
- helpers.py: format_state_event() flattens a state_changed into
{entity_id, device_id, endpoint, event_type, state, ...attrs};
matter_endpoint_from_unique_id() derives the Matter endpoint
- models.py: Blueprint.is_state/state_domain; create_event_listeners() state
branch — config path scopes async_track_state_change_event to the device's
entities (identifier = HA device_id, resolved via the entity registry; an
entity_id also works), discovery path listens to global state_changed
filtered by domain. Identifier equality check skipped for state switches
(already entity-scoped); never falls back to a global listener on the config
path so an unresolved device can't become a catch-all.
The type is deliberately generic (any event.* entity) — no `matter` dependency
and no frontend changes; auto-discovery works via the existing mechanism.
Also adds blueprint matter-ikea-bilresa-scroll-wheel.yaml (one button, nine
Endpoint actions — the editor has no button selector without a background
image), and bumps the version to 4.4.0 so blueprints redeploy.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Now that a device image is present, rework the blueprint from the one-button / nine-actions fallback into nine real buttons (the editor only offers a button selector when a background image exists). The nine Matter endpoints are laid out as a neutral 3x3 grid over the 474x700 remote image; endpoint-to-gesture mapping is still TBD per unit, so buttons stay labelled by endpoint. Each button carries the standard action set (press / press 2x / press 3x / hold / hold released) via a shared YAML anchor. - blueprints/matter-ikea-bilresa-scroll-wheel.png: device image (RGBA, transparent) - blueprints/matter-ikea-bilresa-scroll-wheel.yaml: 9 buttons with grid coords Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rework the BILRESA blueprint to match how the device actually works: the three LEDs on the lower part select one of three modes (pressing the lower part only cycles the LED and emits no HA event), and per mode the wheel offers scroll left / press / scroll right - nine generic-switch endpoints total. Since Switch Manager buttons have no titles (they're identified only by their position on the background image), the endpoint meaning is baked into the image: the device photo plus a labelled 3x3 control matrix (rows = LED 1/2/3, columns = scroll left / press / scroll right, cells = EP1..EP9). The nine button rects sit on the matrix cells. Actions are now gesture-specific: scroll cells have a single "Scroll" action (fires per turn; notch count in data.totalNumberOfPressesCounted), press cells have Press / Hold / Hold (released), mirroring the familiar Rodret layout. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Redesign per the device's real interaction model (matches the Rodret/e2201 UX in Switch Manager): the three lower LEDs become three clickable circular buttons (left = LED 1, middle = LED 2, right = LED 3), each highlighting blue on select / press like any other switch. Each LED button aggregates that mode's three Matter endpoints (rotate right / rotate left / press) into six actions: Press, Press 2x, Hold, Hold (released), Rotate right, Rotate left. Buttons and actions use template conditions on data.endpoint / data.event_type to route each endpoint+event to exactly one action (verified: no ambiguous or double matches; unknown endpoints ignored). Restores the clean device photo as the background (the previous commit had replaced it with a labelled composite) and places three circle buttons over the LED dots. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Matter batches fast scrolling into a single multi_press_N event (N = notches,
capped at 8). format_state_event now derives an integer data.presses (parsed from
multi_press_N, else 1) so a rotate sequence can react proportionally, e.g.
`repeat: count: {{ data.presses }}` or `brightness_step_pct: {{ data.presses * 5 }}`.
Blueprint info documents the repeat pattern and notes that very fast turns can be
dropped by Matter below HA (not recoverable at this layer; smooth real-time scroll
would need the Matter-server MultiPressOngoing path).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…aling) Blueprint actions can declare `repeat: <data-field>`; when set, Switch Manager runs that action's sequence N times where N is the integer value of that field in the event data (clamped 1..50, run sequentially so steps apply in order). The user's action stays a single clean step defined in the visual editor - no templates, no manual multi_press handling. The BILRESA rotate actions use `repeat: presses`, so a batched scroll of N notches (multi_press_N) runs the user's "-5%" step N times. Press/hold actions are untouched (they don't declare repeat). - schema.py: BLUEPRINT_ACTION_SCHEMA gains optional `repeat` - models.py: BlueprintButtonAction.repeat; _processIncoming computes the count; ManagedSwitchConfigButtonAction.run loops sequentially - blueprint: repeat: presses on all six rotate actions; info simplified Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Existing blueprints (e.g. zigbee2mqtt-ers-10tzbvk-aa-event, the Tuya smart knob) use lowercase action titles. Align the BILRESA titles: press / press 2x / hold / hold (released) / rotate right / rotate left. Titles are display-only (matching is by condition, configs reference actions by index), so this is cosmetic. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… in one call New blueprint action property `scale_field` (string or list). When set, the matched action runs ONCE with the named service-data field(s) multiplied by the event's notch count (data.presses), built on the fly from a deep copy of the user's raw sequence. This dims by (step * notches) in a single, race-free light.turn_on call instead of many relative brightness_step_pct steps that a bulb can't accumulate. The user's action stays a plain, template-free step (e.g. brightness_step_pct: 5) - scaling is a blueprint concern, invisible in the visual editor. - schema.py: BLUEPRINT_ACTION_SCHEMA gains optional `scale_field` - models.py: scale_sequence_fields()/_scale_number() (recursive, type/sign preserving, templates untouched); BlueprintButtonAction.scale_field; ManagedSwitchConfigButtonAction._make_script() + run(scale=...); _processIncoming prefers scale_field over repeat - blueprint: rotate actions now scale_field: brightness_step_pct (was repeat); info recommends queued mode for slow scrolling Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add Matter support (generic event-entity connection type) + IKEA BILRESA scroll wheel
The device image now conforms to the repo's 800x500 guideline (339x500). The three LED circle buttons are repositioned to the new image space (centers 124/148/173 x 336, r 10). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses #51 (request to add the IKEA BILRESA scroll-wheel remote) — here via Matter.
What this adds
Switch Manager currently receives events either over MQTT or from a dedicated bus
event (
zha_event,deconz_event, …). Matter remotes fire neither — in HomeAssistant they surface as
event.*entities, where a button press is astate_changedand the action lives innew_state.attributes.event_type.This PR adds a third, generic connection type keyed on
event_type: state_changed,so any blueprint can react to
event.*entities. Matter is the first beneficiary,but nothing here is Matter-specific: no new dependency, no frontend changes, and
auto-discovery works through the existing mechanism.
It also ships a ready-to-use visual blueprint for the IKEA BILRESA scroll-wheel
remote (the device requested in #51) and two small, generic blueprint-action options
that make batched scroll events pleasant to use.
Backward compatibility
blueprints that opt in with
event_type: state_changed.scale_field,repeat) are optional; actions withoutthem behave exactly as before.
1.
state_changedconnection typeschema.py:BLUEPRINT_STATE_SCHEMA(optionalstate_domain, defaultevent).__init__.py: blueprint schema dispatch recognisesstate_changed.helpers.py:format_state_event()flattens astate_changedinto{ entity_id, device_id, endpoint, event_type, presses, state, …attrs };matter_endpoint_from_unique_id()derives the Matter endpoint from the HA unique_id.models.py:Blueprint.is_state/state_domain; a state branch increate_event_listeners().Listener scoping:
async_track_state_change_eventscoped to the target device'sentities (identifier = HA
device_id, resolved via the entity registry; a rawentity_idalso works). It never falls back to a global listener, so an unresolveddevice cannot become a catch-all.
state_changed, filtered by domain and to realtriggers (skips restore/add) — same "press a button to discover it" UX as
zha_event.2. Two optional action options for batched events
Matter batches fast scrolling into a single
multi_press_Nevent (N = notches, cappedat 8), unlike Zigbee which sends one event per notch.
data.presses(parsed frommulti_press_N, else 1) exposes the count, and actions can use it without the enduser writing templates:
scale_field: <field>(string or list) — runs the action once with the namedservice-data field(s) multiplied by
data.presses. The BILRESA rotate actions usescale_field: brightness_step_pct, so a fast flick dims bystep × notchesin asingle, race-free
light.turn_on(repeated relative steps otherwise read stalebrightness and don't accumulate). Scaling runs on a deep copy of the raw sequence,
is type/sign preserving, leaves templates untouched, and never mutates the original.
repeat: <data-field>— runs the action's sequence N times (clamped, sequential).Better for discrete actions (scenes, counters, media next).
3. IKEA BILRESA blueprint (visual)
matter-ikea-bilresa-scroll-wheel.yaml(+ image). This is a visual blueprint: itships a transparent device photo with three positioned circular button regions (using
the blueprint circle shape), which the editor renders as clickable, colour-highlighted
markers (selected / pressed) — the same image-based style as the visual blueprints in
the repo, not the image-less list style.
The remote's three lower LEDs select one of three modes (pressing the lower part only
cycles the LED and emits no HA event); each mode exposes the same wheel gestures as
Matter generic-switch endpoints. The three buttons are the three LEDs (left = LED 1,
middle = LED 2, right = LED 3), each with six actions: press / press 2x / hold /
hold (released) / rotate right / rotate left. Matching uses template conditions on
data.endpoint/data.event_type.Testing
Verified on a live BILRESA over Matter. Auto-discovery finds the device, and all nine
endpoints (three LEDs × rotate right / rotate left / press) route to exactly the right
action across all three modes. Rotate dimming scales correctly — the debug log shows e.g.
Running scaled sequence (x7)for a fast flick, while press actions run unscaled.Notes
the monitor shows the real
endpointand the blueprint conditions can be adjusted.hold/hold (released)are wired up but depend on the device emittinglong_press/long_release; where unsupported those tabs are simply inactive.buttons are positioned over the LED dots and highlight on select/press.
state_changedconnection type, (b) thescale_field/repeataction options, and(c) the BILRESA blueprint.
Blueprint Checklist
Zigbee2MQTT
N/A — this device is added over Matter, not Zigbee2MQTT.