@@ -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 [];
@@ -33,6 +35,8 @@ void switch_cluster_on_button_release(zigbee_switch_cluster *cluster);
3335void switch_cluster_on_button_long_press (zigbee_switch_cluster * cluster );
3436void switch_cluster_on_button_long_release (zigbee_switch_cluster * cluster );
3537void switch_cluster_on_button_multi_press (zigbee_switch_cluster * cluster , u8 press_count );
38+ void switch_cluster_on_button_timeout_pressed (zigbee_switch_cluster * cluster );
39+ void switch_cluster_on_button_timeout_released (zigbee_switch_cluster * cluster );
3640
3741zigbee_switch_cluster * switch_cluster_by_endpoint [10 ];
3842
@@ -47,6 +51,8 @@ static void switch_cluster_report_next_scene(zigbee_switch_cluster *cluster);
4751
4852bool switch_cluster_scenes_is_enabled (zigbee_switch_cluster * cluster );
4953
54+ static void switch_cluster_binding_recall_scene (zigbee_switch_cluster * cluster );
55+
5056status_t switch_cluster_callback_trampoline (zclIncomingAddrInfo_t * pAddrInfo , u8 cmdId , void * cmdPayload )
5157{
5258 return (ZCL_STA_SUCCESS );
@@ -63,6 +69,12 @@ void switch_cluster_callback_attr_write_trampoline(u8 endpoint, u16 clusterId, z
6369 {
6470 switch_cluster_fixup_scene_attrs (cluster );
6571 }
72+
73+ if (clusterId == 3 ) // relay mode
74+ {
75+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
76+ switch_cluster_report_action (cluster );
77+ }
6678}
6779
6880// (mandatory) Cluster revisions
@@ -91,8 +103,10 @@ void switch_cluster_add_to_endpoint(zigbee_switch_cluster *cluster, zigbee_endpo
91103 cluster -> button -> on_release = (ev_button_callback_t )switch_cluster_on_button_release ;
92104 cluster -> button -> on_long_press = (ev_button_callback_t )switch_cluster_on_button_long_press ;
93105 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 ;
106+ cluster -> button -> on_timeout_pressed = (ev_button_callback_t )switch_cluster_on_button_timeout_pressed ;
107+ cluster -> button -> on_timeout_released = (ev_button_callback_t )switch_cluster_on_button_timeout_released ;
95108 cluster -> button -> callback_param = cluster ;
109+ cluster -> button -> timeout_duration_ms = 250 ;
96110
97111 SETUP_ATTR (0 , ZCL_ATTRID_ONOFF_CONFIGURATION_SWITCH_TYPE , ZCL_DATA_TYPE_ENUM8 , ACCESS_CONTROL_READ , cluster -> mode );
98112 SETUP_ATTR (1 , ZCL_ATTRID_ONOFF_CONFIGURATION_SWITCH_ACTIONS , ZCL_DATA_TYPE_ENUM8 , ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE , cluster -> action );
@@ -355,6 +369,13 @@ void switch_cluster_on_button_press(zigbee_switch_cluster *cluster)
355369 }
356370
357371 if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY ) {
372+ if (cluster -> multistate_state == MULTISTATE_SINGLE_RELEASE ) {
373+ switch_cluster_binding_recall_scene (cluster );
374+
375+ cluster -> multistate_state = MULTISTATE_DOUBLE_PRESS ;
376+ switch_cluster_report_action (cluster );
377+ return ;
378+ }
358379
359380 if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_RISE ) {
360381 switch_cluster_relay_action_on (cluster );
@@ -364,27 +385,40 @@ void switch_cluster_on_button_press(zigbee_switch_cluster *cluster)
364385 switch_cluster_binding_action_on (cluster );
365386 }
366387
367- cluster -> multistate_state = MULTISTATE_PRESS ;
388+ cluster -> multistate_state = MULTISTATE_SINGLE_PRESS ;
368389 switch_cluster_report_action (cluster );
369390 return ;
370391 }
371392
372393 if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY_NC ) {
373-
374394 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 );
395+ if (!switch_cluster_scenes_is_enabled (cluster )) {
396+ if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_SHORT ) {
397+ switch_cluster_relay_action_on (cluster );
398+ }
399+ if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
400+ switch_cluster_binding_action_on (cluster );
401+ }
402+
403+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
404+ switch_cluster_report_action (cluster );
377405 }
378- if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
379- switch_cluster_binding_action_on (cluster );
406+ else if (cluster -> multistate_state == MULTISTATE_SINGLE_PRESS )
407+ {
408+ cluster -> multistate_state = MULTISTATE_SINGLE_RELEASE ;
409+ switch_cluster_report_action (cluster );
410+ } else {
411+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
412+ switch_cluster_report_action (cluster );
380413 }
381414 } else {
382415 // This is end of long press, send zcl_level stop
383416 switch_cluster_level_stop (cluster );
417+
418+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
419+ switch_cluster_report_action (cluster );
384420 }
385421
386- cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
387- switch_cluster_report_action (cluster );
388422 return ;
389423 }
390424}
@@ -406,25 +440,43 @@ void switch_cluster_on_button_release(zigbee_switch_cluster *cluster)
406440 }
407441
408442 if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY ) {
409-
410443 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 );
444+ if (!switch_cluster_scenes_is_enabled (cluster )) {
445+ if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_SHORT ) {
446+ switch_cluster_relay_action_on (cluster );
447+ }
448+ if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
449+ switch_cluster_binding_action_on (cluster );
450+ }
451+
452+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
453+ switch_cluster_report_action (cluster );
413454 }
414- if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
415- switch_cluster_binding_action_on (cluster );
455+ else if (cluster -> multistate_state == MULTISTATE_SINGLE_PRESS )
456+ {
457+ cluster -> multistate_state = MULTISTATE_SINGLE_RELEASE ;
458+ switch_cluster_report_action (cluster );
459+ } else {
460+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
461+ switch_cluster_report_action (cluster );
416462 }
417463 } else {
418464 // This is end of long press, send zcl_level stop
419465 switch_cluster_level_stop (cluster );
420- }
421466
422- cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
423- switch_cluster_report_action (cluster );
424- return ;
467+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
468+ switch_cluster_report_action (cluster );
469+ }
425470 }
426471
427472 if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY_NC ) {
473+ if (cluster -> multistate_state == MULTISTATE_SINGLE_RELEASE ) {
474+ switch_cluster_binding_recall_scene (cluster );
475+
476+ cluster -> multistate_state = MULTISTATE_DOUBLE_PRESS ;
477+ switch_cluster_report_action (cluster );
478+ return ;
479+ }
428480
429481 if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_RISE ) {
430482 switch_cluster_relay_action_on (cluster );
@@ -434,7 +486,7 @@ void switch_cluster_on_button_release(zigbee_switch_cluster *cluster)
434486 switch_cluster_binding_action_on (cluster );
435487 }
436488
437- cluster -> multistate_state = MULTISTATE_PRESS ;
489+ cluster -> multistate_state = MULTISTATE_SINGLE_PRESS ;
438490 switch_cluster_report_action (cluster );
439491 return ;
440492 }
@@ -518,6 +570,58 @@ void switch_cluster_on_button_multi_press(zigbee_switch_cluster *cluster, u8 pre
518570 }
519571}
520572
573+ void switch_cluster_on_button_timeout_pressed (zigbee_switch_cluster * cluster )
574+ {
575+ if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_TOGGLE )
576+ {
577+ // Shouldn't hook into this
578+ }
579+
580+ if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY )
581+ {
582+ // Hook into switch_cluster_on_button_released
583+ }
584+
585+ if (switch_cluster_scenes_is_enabled (cluster ) && cluster -> multistate_state == MULTISTATE_SINGLE_RELEASE )
586+ {
587+ if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_SHORT ) {
588+ switch_cluster_relay_action_on (cluster );
589+ }
590+ if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
591+ switch_cluster_binding_action_on (cluster );
592+ }
593+
594+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
595+ switch_cluster_report_action (cluster );
596+ }
597+ }
598+
599+ void switch_cluster_on_button_timeout_released (zigbee_switch_cluster * cluster )
600+ {
601+ if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_TOGGLE )
602+ {
603+ // Shouldn't hook into this
604+ }
605+
606+ if (cluster -> mode == ZCL_ONOFF_CONFIGURATION_SWITCH_TYPE_MOMENTARY_NC )
607+ {
608+ // Hook into switch_cluster_on_button_released
609+ }
610+
611+ if (switch_cluster_scenes_is_enabled (cluster ) && cluster -> multistate_state == MULTISTATE_SINGLE_RELEASE )
612+ {
613+ if (cluster -> relay_mode == ZCL_ONOFF_CONFIGURATION_RELAY_MODE_SHORT ) {
614+ switch_cluster_relay_action_on (cluster );
615+ }
616+ if (cluster -> binded_mode == ZCL_ONOFF_CONFIGURATION_BINDED_MODE_SHORT ) {
617+ switch_cluster_binding_action_on (cluster );
618+ }
619+
620+ cluster -> multistate_state = MULTISTATE_NOT_PRESSED ;
621+ switch_cluster_report_action (cluster );
622+ }
623+ }
624+
521625void switch_cluster_on_write_attr (zigbee_switch_cluster * cluster )
522626{
523627 switch_cluster_store_attrs_to_nv (cluster );
@@ -697,3 +801,8 @@ static void switch_cluster_binding_recall_scene(zigbee_switch_cluster *cluster)
697801out :
698802 switch_cluster_report_next_scene (cluster );
699803}
804+
805+ bool switch_cluster_scenes_is_enabled (zigbee_switch_cluster * cluster )
806+ {
807+ return cluster -> out_scene_count ;
808+ }
0 commit comments