diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index e9e8f390c..801c57acc 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -225,7 +225,7 @@ #define KEY_DEBOUNCE_TIME 50 // [ButtonDebounce] Number of mSeconds button press debounce time #define KEY_HOLD_TIME 40 // [SetOption32] Number of 0.1 seconds to hold Button or external Pushbutton before sending HOLD message #define SWITCH_DEBOUNCE_TIME 50 // [SwitchDebounce] Number of mSeconds switch press debounce time -#define SWITCH_MODE TOGGLE // [SwitchMode] TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE (the wall switch state) +#define SWITCH_MODE TOGGLE // [SwitchMode] TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, TOGGLEHOLD, FOLLOWHOLD, FOLLOWHOLD_INV (the wall switch state) #define WS2812_LEDS 30 // [Pixels] Number of WS2812 LEDs to start with (max is 512) #define TEMP_CONVERSION 0 // [SetOption8] Return temperature in (0 = Celsius or 1 = Fahrenheit) diff --git a/tasmota/support_switch.ino b/tasmota/support_switch.ino index b8ce8c646..9cc3c336f 100644 --- a/tasmota/support_switch.ino +++ b/tasmota/support_switch.ino @@ -137,22 +137,36 @@ void SwitchHandler(uint8_t mode) for (uint32_t i = 0; i < MAX_SWITCHES; i++) { if ((pin[GPIO_SWT1 +i] < 99) || (mode)) { + uint8_t button = Switch.virtual_state[i]; + uint8_t switchflag = POWER_TOGGLE +1; if (Switch.hold_timer[i]) { Switch.hold_timer[i]--; if (0 == Switch.hold_timer[i]) { - SendKey(KEY_SWITCH, i +1, POWER_HOLD); // Execute command via MQTT + + switch (Settings.switchmode[i]) { + case TOGGLEMULTI: + switchflag = POWER_TOGGLE; // Toggle after hold + break; + case FOLLOWMULTI: + switchflag = button &1; // Follow wall switch state after hold + break; + case FOLLOWMULTI_INV: + switchflag = ~button &1; // Follow inverted wall switch state after hold + break; + default: + SendKey(KEY_SWITCH, i +1, POWER_HOLD); // Execute command via MQTT + break; + } } } - uint8_t button = Switch.virtual_state[i]; - -// enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, MAX_SWITCH_OPTION}; +// enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, TOGGLEMULTI, FOLLOWMULTI, FOLLOWMULTI_INV, MAX_SWITCH_OPTION}; if (button != Switch.last_state[i]) { - uint8_t switchflag = POWER_TOGGLE +1; switch (Settings.switchmode[i]) { case TOGGLE: + case PUSHBUTTON_TOGGLE: switchflag = POWER_TOGGLE; // Toggle break; case FOLLOW: @@ -171,11 +185,6 @@ void SwitchHandler(uint8_t mode) switchflag = POWER_TOGGLE; // Toggle with releasing pushbutton from Gnd } break; - case PUSHBUTTON_TOGGLE: - if (button != Switch.last_state[i]) { - switchflag = POWER_TOGGLE; // Toggle with any pushbutton change - } - break; case PUSHBUTTONHOLD: if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; @@ -194,16 +203,25 @@ void SwitchHandler(uint8_t mode) switchflag = POWER_TOGGLE; // Toggle with pushbutton to Gnd } break; - } - - if (switchflag <= POWER_TOGGLE) { - if (!SendKey(KEY_SWITCH, i +1, switchflag)) { // Execute command via MQTT - ExecuteCommandPower(i +1, switchflag, SRC_SWITCH); // Execute command internally (if i < devices_present) + case TOGGLEMULTI: + case FOLLOWMULTI: + case FOLLOWMULTI_INV: + if (Switch.hold_timer[i]) { + Switch.hold_timer[i] = 0; + SendKey(KEY_SWITCH, i +1, POWER_HOLD); // Execute command via MQTT + } else { + Switch.hold_timer[i] = loops_per_second / 2; // 0.5 second multi press window } + break; } Switch.last_state[i] = button; } + if (switchflag <= POWER_TOGGLE) { + if (!SendKey(KEY_SWITCH, i +1, switchflag)) { // Execute command via MQTT + ExecuteCommandPower(i +1, switchflag, SRC_SWITCH); // Execute command internally (if i < devices_present) + } + } } } } diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index f0e747c27..b4b944d80 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -231,7 +231,7 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D enum WifiConfigOptions {WIFI_RESTART, EX_WIFI_SMARTCONFIG, WIFI_MANAGER, EX_WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL, WIFI_MANAGER_RESET_ONLY, MAX_WIFI_OPTION}; -enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, MAX_SWITCH_OPTION}; +enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, TOGGLEMULTI, FOLLOWMULTI, FOLLOWMULTI_INV, MAX_SWITCH_OPTION}; enum LedStateOptions {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION}; diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index dd557a0fd..13287d009 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -563,7 +563,7 @@ void RulesEvery50ms(void) #else if (pin[GPIO_SWT1 +i] < 99) { #endif // USE_TM1638 - bool swm = ((FOLLOW_INV == Settings.switchmode[i]) || (PUSHBUTTON_INV == Settings.switchmode[i]) || (PUSHBUTTONHOLD_INV == Settings.switchmode[i])); + bool swm = ((FOLLOW_INV == Settings.switchmode[i]) || (PUSHBUTTON_INV == Settings.switchmode[i]) || (PUSHBUTTONHOLD_INV == Settings.switchmode[i]) || (FOLLOWMULTI_INV == Settings.switchmode[i])); snprintf_P(json_event, sizeof(json_event), PSTR("{\"" D_JSON_SWITCH "%d\":{\"Boot\":%d}}"), i +1, (swm ^ SwitchLastState(i))); RulesProcessEvent(json_event); }