Skip to content

Multistate actions proposal#380

Open
RealByron wants to merge 6 commits intoromasku:mainfrom
RealByron:multistate_pb
Open

Multistate actions proposal#380
RealByron wants to merge 6 commits intoromasku:mainfrom
RealByron:multistate_pb

Conversation

@RealByron
Copy link
Copy Markdown
Contributor

Multi-press action reporting

Summary

Replaces the previous action-dispatch system (which hardcoded relay/binding actions per press count) with pure reporting: the firmware detects how many times a button was pressed and reports it as a multistate value. All automation logic lives in Z2M/ZHA.

This makes multi-press fully generic — supporting triple press (or more) requires zero firmware changes, just setting max_press_count = 3 via ZCL.

New multistate values:

Value Event Notes
2 long_press N=1 hold — backward compatible
5 single_press timer_confirm fired, N=1
6 single_release released after hold, N=1
7 double_press timer_confirm fired, N=2
8 double_hold timer_hold fired, N=2
9 double_release released after hold, N=2
10 triple_press N=3 (needs max_press_count=3)
formula: 3n+1 / 3n+2 / 3n+3 for n≥2

New ZCL attributes (OnOff Switch Config cluster, per endpoint):

  • 0xFF06 confirm_release_ms — window after release before confirming press count (default 200 ms)
  • 0xFF07 max_press_count — maximum press count to detect (default 2, set to 3 for triple-press)

Both attributes are persisted in NVM and survive reboots.

Backward compatibility: relay_mode, binded_mode, and the legacy long_press (value 2) are fully preserved.

Changes

  • src/zigbee/switch_cluster.c — generic MULTISTATE_N_* formula, dynamic multistate_num_of_states, removed action-dispatch system
  • src/zigbee/switch_cluster.h — removed 6 action fields, reduced attr_infos[16][10]
  • src/zigbee/consts.h — removed SWITCH_ACTION_* enum and ACTION_N_* attribute IDs
  • src/device_config/config_parser.cI handler uses ordered counter for switch indicator assignment; relay_clusters assignment guarded by relay_clusters_cnt > 0
  • device_db.yamlREMOTE_MOES_SWITCH_TS0044 config_str updated (S tokens + BTC5)
  • helper_scripts/templates/switch_custom.js.jinja — updated pressAction lookup (up to triple press), added confirmReleaseMs and maxPressCount converter functions
  • tests/ — removed action-dispatch tests, added single_press, double_press, triple_press multistate value tests

@RealByron
Copy link
Copy Markdown
Contributor Author

WIP, need some tests on real device (TBD soon)
But we can discuss on the general idea

@romasku
Copy link
Copy Markdown
Owner

romasku commented Mar 28, 2026

Hi,
Thank you for the PR! I didn't do a full review, but from what I saw, it looks very nice.

I have some questions:

  • Am I right that after N presses, multistate will be in MULTISTATE_N_PRESS(N) indefinitely, and will never return to MULTISTATE_RELEASED? It seems a bit wrong to me.
  • Why do you call switch_cluster_flash_indicator in switch_cluster_binding_action_on/switch_cluster_binding_action_off/...? I thought calling it from a switch_cluster_on_button_press should be enough.

@andrei-lazarov
Copy link
Copy Markdown
Collaborator

If we rework this, we should definitely switch to the cleaner mqtt events (actions), like all other remotes from Z2M.
The current action sensor is confusing for users. We should drop it and warn users about the breaking change.

image image

Not sure how it would affect the firmware, this is mostly about the converter / UX.

There would be one 'action' field per device, so the possible values would include the gang (1,2,3,4) corresponding to the button pressed.

  • single press: n_initial (press), n_single (release + confirm period)
  • single long press: n_initial (press), n_hold (reached long press duration), n_long (released)
  • double press: n_initial (press), n_double (release after second press + confirm period)
  • triple press: n_initial (press), n_triple (release after third press)

Double/triple initial-press and hold are overkill imo, but I'm not totally against them..

And for rocker switches it would be just n_on and n_off.

We must also keep in mind what happens if multiple buttons are pressed at once.
I expect 1_initial, 2_initial, 1_single, 2_single in quick succession.

@RealByron
Copy link
Copy Markdown
Contributor Author

RealByron commented Mar 28, 2026

Hi, Thank you for the PR! I didn't do a full review, but from what I saw, it looks very nice.

I have some questions:

  • Am I right that after N presses, multistate will be in MULTISTATE_N_PRESS(N) indefinitely, and will never return to MULTISTATE_RELEASED? It seems a bit wrong to me.

I add a test for that, at last release (passing 200 ms timeout) only the the max bp action will be fired

  • Why do you call switch_cluster_flash_indicator in switch_cluster_binding_action_on/switch_cluster_binding_action_off/...? I thought calling it from a switch_cluster_on_button_press should be enough.

I though that a flash led on bp event should be nice, to see that event are fired. But we can simplify.

@RealByron
Copy link
Copy Markdown
Contributor Author

RealByron commented Mar 28, 2026

If we rework this, we should definitely switch to the cleaner mqtt events (actions), like all other remotes from Z2M. The current action sensor is confusing for users. We should drop it and warn users about the breaking change.

image image
Not sure how it would affect the firmware, this is mostly about the converter / UX.

There would be one 'action' field per device, so the possible values would include the gang (1,2,3,4) corresponding to the button pressed.

  • single press: n_initial (press), n_single (release + confirm period)
  • single long press: n_initial (press), n_hold (reached long press duration), n_long (released)
  • double press: n_initial (press), n_double (release after second press + confirm period)
  • triple press: n_initial (press), n_triple (release after third press)

fully agreed with that but I was not able to deduce impact for users... Too risky for me as I'm not very familiar with usage of this firmware.

@RealByron
Copy link
Copy Markdown
Contributor Author

We must also keep in mind what happens if multiple buttons are pressed at once.
I expect 1_initial, 2_initial, 1_single, 2_single in quick succession.

I just added a test for that

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.

3 participants