@@ -19,10 +19,12 @@ const u16 multistate_num_of_states = 3;
1919
2020
2121#define MULTISTATE_NOT_PRESSED 0
22- #define MULTISTATE_PRESS 1
22+ #define MULTISTATE_SINGLE_PRESS 1
2323#define MULTISTATE_LONG_PRESS 2
2424#define MULTISTATE_POSITION_ON 3
2525#define MULTISTATE_POSITION_OFF 4
26+ #define MULTISTATE_DOUBLE_PRESS 5
27+ #define MULTISTATE_SINGLE_RELEASE 6
2628
2729
2830extern zigbee_relay_cluster relay_clusters [];
@@ -47,6 +49,8 @@ static void switch_cluster_report_next_scene(zigbee_switch_cluster *cluster);
4749
4850bool switch_cluster_scenes_is_enabled (zigbee_switch_cluster * cluster );
4951
52+ static void switch_cluster_binding_recall_scene (zigbee_switch_cluster * cluster );
53+
5054status_t switch_cluster_callback_trampoline (zclIncomingAddrInfo_t * pAddrInfo , u8 cmdId , void * cmdPayload )
5155{
5256 return (ZCL_STA_SUCCESS );
@@ -63,6 +67,12 @@ void switch_cluster_callback_attr_write_trampoline(u8 endpoint, u16 clusterId, z
6367 {
6468 switch_cluster_fixup_scene_attrs (cluster );
6569 }
70+
71+ if (clusterId == 3 ) // relay mode
72+ {
73+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
74+ switch_cluster_report_action (cluster );
75+ }
6676}
6777
6878// (mandatory) Cluster revisions
@@ -91,8 +101,10 @@ void switch_cluster_add_to_endpoint(zigbee_switch_cluster *cluster, zigbee_endpo
91101 cluster -> button -> on_release = (ev_button_callback_t )switch_cluster_on_button_release ;
92102 cluster -> button -> on_long_press = (ev_button_callback_t )switch_cluster_on_button_long_press ;
93103 cluster -> button -> on_long_release = (ev_button_callback_t )switch_cluster_on_button_long_release ;
94- cluster -> button -> on_multi_press = (ev_button_multi_press_callback_t )switch_cluster_on_button_multi_press ;
104+ cluster -> button -> on_timeout_pressed = (ev_button_callback_t )switch_cluster_on_button_timeout_pressed ;
105+ cluster -> button -> on_timeout_released = (ev_button_callback_t )switch_cluster_on_button_timeout_released ;
95106 cluster -> button -> callback_param = cluster ;
107+ cluster -> button -> timeout_duration_ms = 250 ;
96108
97109 SETUP_ATTR (0 , ZCL_ATTRID_ONOFF_CONFIGURATION_SWITCH_TYPE , ZCL_DATA_TYPE_ENUM8 , ACCESS_CONTROL_READ , cluster -> mode );
98110 SETUP_ATTR (1 , ZCL_ATTRID_ONOFF_CONFIGURATION_SWITCH_ACTIONS , ZCL_DATA_TYPE_ENUM8 , ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE , cluster -> action );
@@ -355,6 +367,13 @@ void switch_cluster_on_button_press(zigbee_switch_cluster *cluster)
355367 }
356368
357369 if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY ) {
370+ if (cluster -> multistate_state == MULTISTATE_SINGLE_RELEASE ) {
371+ switch_cluster_binding_recall_scene (cluster );
372+
373+ cluster -> multistate_state = MULTISTATE_DOUBLE_PRESS ;
374+ switch_cluster_report_action (cluster );
375+ return ;
376+ }
358377
359378 if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_RISE ) {
360379 switch_cluster_relay_action_on (cluster );
@@ -364,27 +383,40 @@ void switch_cluster_on_button_press(zigbee_switch_cluster *cluster)
364383 switch_cluster_binding_action_on (cluster );
365384 }
366385
367- cluster -> multistate_state = MULTISTATE_PRESS ;
386+ cluster -> multistate_state = MULTISTATE_SINGLE_PRESS ;
368387 switch_cluster_report_action (cluster );
369388 return ;
370389 }
371390
372391 if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY_NC ) {
373-
374392 if (cluster -> multistate_state != MULTISTATE_LONG_PRESS ) {
375- if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_SHORT ) {
376- switch_cluster_relay_action_on (cluster );
393+ if (!switch_cluster_scenes_is_enabled (cluster )) {
394+ if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_SHORT ) {
395+ switch_cluster_relay_action_on (cluster );
396+ }
397+ if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
398+ switch_cluster_binding_action_on (cluster );
399+ }
400+
401+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
402+ switch_cluster_report_action (cluster );
377403 }
378- if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
379- switch_cluster_binding_action_on (cluster );
404+ else if (cluster -> multistate_state == MULTISTATE_SINGLE_PRESS )
405+ {
406+ cluster -> multistate_state = MULTISTATE_SINGLE_RELEASE ;
407+ switch_cluster_report_action (cluster );
408+ } else {
409+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
410+ switch_cluster_report_action (cluster );
380411 }
381412 } else {
382413 // This is end of long press, send zcl_level stop
383414 switch_cluster_level_stop (cluster );
415+
416+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
417+ switch_cluster_report_action (cluster );
384418 }
385419
386- cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
387- switch_cluster_report_action (cluster );
388420 return ;
389421 }
390422}
@@ -406,25 +438,43 @@ void switch_cluster_on_button_release(zigbee_switch_cluster *cluster)
406438 }
407439
408440 if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY ) {
409-
410441 if (cluster -> multistate_state != MULTISTATE_LONG_PRESS ) {
411- if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_SHORT ) {
412- switch_cluster_relay_action_on (cluster );
442+ if (!switch_cluster_scenes_is_enabled (cluster )) {
443+ if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_SHORT ) {
444+ switch_cluster_relay_action_on (cluster );
445+ }
446+ if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
447+ switch_cluster_binding_action_on (cluster );
448+ }
449+
450+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
451+ switch_cluster_report_action (cluster );
413452 }
414- if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
415- switch_cluster_binding_action_on (cluster );
453+ else if (cluster -> multistate_state == MULTISTATE_SINGLE_PRESS )
454+ {
455+ cluster -> multistate_state = MULTISTATE_SINGLE_RELEASE ;
456+ switch_cluster_report_action (cluster );
457+ } else {
458+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
459+ switch_cluster_report_action (cluster );
416460 }
417461 } else {
418462 // This is end of long press, send zcl_level stop
419463 switch_cluster_level_stop (cluster );
420- }
421464
422- cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
423- switch_cluster_report_action (cluster );
424- return ;
465+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
466+ switch_cluster_report_action (cluster );
467+ }
425468 }
426469
427470 if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY_NC ) {
471+ if (cluster -> multistate_state == MULTISTATE_SINGLE_RELEASE ) {
472+ switch_cluster_binding_recall_scene (cluster );
473+
474+ cluster -> multistate_state = MULTISTATE_DOUBLE_PRESS ;
475+ switch_cluster_report_action (cluster );
476+ return ;
477+ }
428478
429479 if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_RISE ) {
430480 switch_cluster_relay_action_on (cluster );
@@ -434,7 +484,7 @@ void switch_cluster_on_button_release(zigbee_switch_cluster *cluster)
434484 switch_cluster_binding_action_on (cluster );
435485 }
436486
437- cluster -> multistate_state = MULTISTATE_PRESS ;
487+ cluster -> multistate_state = MULTISTATE_SINGLE_PRESS ;
438488 switch_cluster_report_action (cluster );
439489 return ;
440490 }
@@ -518,6 +568,58 @@ void switch_cluster_on_button_multi_press(zigbee_switch_cluster *cluster, u8 pre
518568 }
519569}
520570
571+ void switch_cluster_on_button_timeout_pressed (zigbee_switch_cluster * cluster )
572+ {
573+ if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_TOGGLE )
574+ {
575+ // Shouldn't hook into this
576+ }
577+
578+ if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY )
579+ {
580+ // Hook into switch_cluster_on_button_released
581+ }
582+
583+ if (switch_cluster_scenes_is_enabled (cluster ) && cluster -> multistate_state == MULTISTATE_SINGLE_RELEASE )
584+ {
585+ if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_SHORT ) {
586+ switch_cluster_relay_action_on (cluster );
587+ }
588+ if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
589+ switch_cluster_binding_action_on (cluster );
590+ }
591+
592+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
593+ switch_cluster_report_action (cluster );
594+ }
595+ }
596+
597+ void switch_cluster_on_button_timeout_released (zigbee_switch_cluster * cluster )
598+ {
599+ if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_TOGGLE )
600+ {
601+ // Shouldn't hook into this
602+ }
603+
604+ if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY_NC )
605+ {
606+ // Hook into switch_cluster_on_button_released
607+ }
608+
609+ if (switch_cluster_scenes_is_enabled (cluster ) && cluster -> multistate_state == MULTISTATE_SINGLE_RELEASE )
610+ {
611+ if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_SHORT ) {
612+ switch_cluster_relay_action_on (cluster );
613+ }
614+ if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
615+ switch_cluster_binding_action_on (cluster );
616+ }
617+
618+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
619+ switch_cluster_report_action (cluster );
620+ }
621+ }
622+
521623void switch_cluster_on_write_attr (zigbee_switch_cluster * cluster )
522624{
523625 switch_cluster_store_attrs_to_nv (cluster );
0 commit comments