diff --git a/tasmota/support_switch.ino b/tasmota/support_switch.ino index 9fc3b57c3..bd127d6c5 100644 --- a/tasmota/support_switch.ino +++ b/tasmota/support_switch.ino @@ -231,9 +231,9 @@ void SwitchHandler(uint8_t mode) uint8_t button = Switch.virtual_state[i]; uint8_t switchflag = POWER_TOGGLE +1; - if (Switch.hold_timer[i]) { + if (Switch.hold_timer[i] & (((Settings.switchmode[i] == PUSHHOLDMULTI) | (Settings.switchmode[i] == PUSHHOLDMULTI_INV)) ? SM_TIMER_MASK: SM_NO_TIMER_MASK)) { Switch.hold_timer[i]--; - if (Switch.hold_timer[i] == loops_per_second * Settings.param[P_HOLD_TIME] / 25) { + if ((Switch.hold_timer[i] & SM_TIMER_MASK) == loops_per_second * Settings.param[P_HOLD_TIME] / 25) { if ((Settings.switchmode[i] == PUSHHOLDMULTI) & (NOT_PRESSED == Switch.last_state[i])) { SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT } @@ -241,7 +241,7 @@ void SwitchHandler(uint8_t mode) SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT } } - if (0 == Switch.hold_timer[i]) { + if (0 == (Switch.hold_timer[i] & (((Settings.switchmode[i] == PUSHHOLDMULTI) | (Settings.switchmode[i] == PUSHHOLDMULTI_INV)) ? SM_TIMER_MASK: SM_NO_TIMER_MASK))) { switch (Settings.switchmode[i]) { case TOGGLEMULTI: switchflag = POWER_TOGGLE; // Toggle after hold @@ -257,6 +257,7 @@ void SwitchHandler(uint8_t mode) Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 25; SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT } else { + Switch.hold_timer[i]= 0; SendKey(KEY_SWITCH, i +1, POWER_CLEAR); // Execute command via MQTT } break; @@ -265,6 +266,7 @@ void SwitchHandler(uint8_t mode) Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 25; SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT } else { + Switch.hold_timer[i]= 0; SendKey(KEY_SWITCH, i +1, POWER_CLEAR); // Execute command via MQTT } break; @@ -327,31 +329,49 @@ void SwitchHandler(uint8_t mode) break; case PUSHHOLDMULTI: if (NOT_PRESSED == button) { - if (Switch.hold_timer[i] != 0) { + if ((Switch.hold_timer[i] & SM_TIMER_MASK) != 0) { + Switch.hold_timer[i] = ((Switch.hold_timer[i] & ~SM_TIMER_MASK) == SM_FIRST_PRESS) ? SM_SECOND_PRESS : 0; SendKey(KEY_SWITCH, i +1, POWER_INV); // Execute command via MQTT } } else { - if (Switch.hold_timer[i] > loops_per_second * Settings.param[P_HOLD_TIME] / 25) { - switchflag = POWER_TOGGLE; // Toggle with pushbutton + if ((Switch.hold_timer[i] & SM_TIMER_MASK) > loops_per_second * Settings.param[P_HOLD_TIME] / 25) { + if((Switch.hold_timer[i] & ~SM_TIMER_MASK) != SM_SECOND_PRESS) { + Switch.hold_timer[i]= SM_FIRST_PRESS; + switchflag = POWER_TOGGLE; // Toggle with pushbutton + } + else{ + SendKey(KEY_SWITCH, i +1, POWER_100); // Execute command via MQTT + Switch.hold_timer[i]= 0; + } } else { + Switch.hold_timer[i]= 0; SendKey(KEY_SWITCH, i +1, POWER_RELEASE); // Execute command via MQTT } } - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; + Switch.hold_timer[i] = (Switch.hold_timer[i] & ~SM_TIMER_MASK) | loops_per_second * Settings.param[P_HOLD_TIME] / 10; break; case PUSHHOLDMULTI_INV: if (PRESSED == button) { - if (Switch.hold_timer[i] != 0) { + if ((Switch.hold_timer[i] & SM_TIMER_MASK) != 0) { + Switch.hold_timer[i] = ((Switch.hold_timer[i] & ~SM_TIMER_MASK) == SM_FIRST_PRESS) ? SM_SECOND_PRESS : 0; SendKey(KEY_SWITCH, i +1, POWER_INV); // Execute command via MQTT } } else { - if (Switch.hold_timer[i] > loops_per_second * Settings.param[P_HOLD_TIME] / 25) { - switchflag = POWER_TOGGLE; // Toggle with pushbutton + if ((Switch.hold_timer[i] & SM_TIMER_MASK)> loops_per_second * Settings.param[P_HOLD_TIME] / 25) { + if((Switch.hold_timer[i] & ~SM_TIMER_MASK) != SM_SECOND_PRESS) { + Switch.hold_timer[i]= SM_FIRST_PRESS; + switchflag = POWER_TOGGLE; // Toggle with pushbutton + } + else{ + SendKey(KEY_SWITCH, i +1, POWER_100); // Execute command via MQTT + Switch.hold_timer[i]= 0; + } } else { + Switch.hold_timer[i]= 0; SendKey(KEY_SWITCH, i +1, POWER_RELEASE); // Execute command via MQTT } } - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; + Switch.hold_timer[i] = (Switch.hold_timer[i] & ~SM_TIMER_MASK) | loops_per_second * Settings.param[P_HOLD_TIME] / 10; break; case PUSHON: if (PRESSED == button) { diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 642389741..ba8c9e302 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -209,6 +209,12 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to #define KNX_MAX_device_param 31 #define MAX_KNXTX_CMNDS 5 +// Switch Mode definietions +#define SM_TIMER_MASK 0x3F +#define SM_NO_TIMER_MASK 0xFF +#define SM_FIRST_PRESS 0x40 +#define SM_SECOND_PRESS 0x80 + /*********************************************************************************************\ * Enumeration \*********************************************************************************************/ @@ -235,7 +241,7 @@ enum TopicOptions { CMND, STAT, TELE, nu1, RESULT_OR_CMND, RESULT_OR_STAT, RESUL enum ExecuteCommandPowerOptions { POWER_OFF, POWER_ON, POWER_TOGGLE, POWER_BLINK, POWER_BLINK_STOP, POWER_OFF_NO_STATE = 8, POWER_ON_NO_STATE, POWER_TOGGLE_NO_STATE, POWER_SHOW_STATE = 16 }; -enum SendKeyPowerOptions { POWER_HOLD = 3, POWER_INCREMENT = 4, POWER_INV = 5, POWER_CLEAR = 6, POWER_RELEASE = 7, CLEAR_RETAIN = 9 }; +enum SendKeyPowerOptions { POWER_HOLD = 3, POWER_INCREMENT = 4, POWER_INV = 5, POWER_CLEAR = 6, POWER_RELEASE = 7, POWER_100 = 8, CLEAR_RETAIN = 9 }; enum SendKeyOptions { KEY_BUTTON, KEY_SWITCH }; enum SendKeyMultiClick { SINGLE = 10, DOUBLE = 11, TRIPLE = 12, QUAD = 13, PENTA = 14};