Merge pull request #9721 from effelle/development

Switches: MQTT decoupling and regression fix
This commit is contained in:
Theo Arends 2020-11-03 09:23:28 +01:00 committed by GitHub
commit d9954a2df7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 5 deletions

View File

@ -139,7 +139,8 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
typedef union { // Restricted by MISRA-C Rule 18.4 but so useful...
uint32_t data; // Allow bit manipulation using SetOption
struct { // SetOption114 .. SetOption145
uint32_t spare00 : 1; // bit 0
uint32_t mqtt_switches : 1; // bit 0 (V9.0.0.3) - SetOption114 - Detach Swiches from relays and enable MQTT action state for all the SwitchModes
//uint32_t spare00 : 1; // bit 0
uint32_t spare01 : 1; // bit 1
uint32_t spare02 : 1; // bit 2
uint32_t spare03 : 1; // bit 3

View File

@ -34,6 +34,10 @@ const uint8_t AC_PERIOD = (20 + SWITCH_FAST_PROBE_INTERVAL - 1) / SWITCH_FAST_PR
#define SM_NO_TIMER_MASK 0xFF
#define SM_FIRST_PRESS 0x40
#define SM_SECOND_PRESS 0x80
#define POWER_NONE 99
const char kSwitchPressStates[] PROGMEM =
"||||POWER_INCREMENT|POWER_INV|POWER_CLEAR|POWER_RELEASE|POWER_100|";
#include <Ticker.h>
@ -240,6 +244,7 @@ void SwitchHandler(uint8_t mode)
if (PinUsed(GPIO_SWT1, i) || (mode)) {
uint8_t button = Switch.virtual_state[i];
uint8_t switchflag = POWER_TOGGLE +1;
uint8_t MqttAction = POWER_NONE;
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]--;
@ -266,22 +271,28 @@ void SwitchHandler(uint8_t mode)
if (NOT_PRESSED == button) {
Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 25;
SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT
MqttAction = POWER_INCREMENT;
} else {
Switch.hold_timer[i]= 0;
SendKey(KEY_SWITCH, i +1, POWER_CLEAR); // Execute command via MQTT
MqttAction = POWER_CLEAR;
}
break;
case PUSHHOLDMULTI_INV:
if (PRESSED == button) {
Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 25;
SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT
MqttAction = POWER_INCREMENT;
} else {
Switch.hold_timer[i]= 0;
SendKey(KEY_SWITCH, i +1, POWER_CLEAR); // Execute command via MQTT
MqttAction = POWER_CLEAR;
}
break;
default:
SendKey(KEY_SWITCH, i +1, POWER_HOLD); // Execute command via MQTT
MqttAction = POWER_HOLD;
break;
}
}
@ -333,6 +344,7 @@ void SwitchHandler(uint8_t mode)
if (Switch.hold_timer[i]) {
Switch.hold_timer[i] = 0;
SendKey(KEY_SWITCH, i +1, POWER_HOLD); // Execute command via MQTT
MqttAction = POWER_HOLD;
} else {
Switch.hold_timer[i] = loops_per_second / 2; // 0.5 second multi press window
}
@ -342,6 +354,7 @@ void SwitchHandler(uint8_t mode)
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
MqttAction = POWER_INV;
}
} else {
if ((Switch.hold_timer[i] & SM_TIMER_MASK) > loops_per_second * Settings.param[P_HOLD_TIME] / 25) {
@ -351,11 +364,13 @@ void SwitchHandler(uint8_t mode)
}
else{
SendKey(KEY_SWITCH, i +1, POWER_100); // Execute command via MQTT
MqttAction = POWER_100;
Switch.hold_timer[i]= 0;
}
} else {
Switch.hold_timer[i]= 0;
SendKey(KEY_SWITCH, i +1, POWER_RELEASE); // Execute command via MQTT
MqttAction = POWER_RELEASE;
}
}
Switch.hold_timer[i] = (Switch.hold_timer[i] & ~SM_TIMER_MASK) | loops_per_second * Settings.param[P_HOLD_TIME] / 10;
@ -365,6 +380,7 @@ void SwitchHandler(uint8_t mode)
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
MqttAction = POWER_INV;
}
} else {
if ((Switch.hold_timer[i] & SM_TIMER_MASK)> loops_per_second * Settings.param[P_HOLD_TIME] / 25) {
@ -374,11 +390,13 @@ void SwitchHandler(uint8_t mode)
}
else{
SendKey(KEY_SWITCH, i +1, POWER_100); // Execute command via MQTT
MqttAction = POWER_100;
Switch.hold_timer[i]= 0;
}
} else {
Switch.hold_timer[i]= 0;
SendKey(KEY_SWITCH, i +1, POWER_RELEASE); // Execute command via MQTT
MqttAction = POWER_RELEASE;
}
}
Switch.hold_timer[i] = (Switch.hold_timer[i] & ~SM_TIMER_MASK) | loops_per_second * Settings.param[P_HOLD_TIME] / 10;
@ -400,14 +418,40 @@ void SwitchHandler(uint8_t mode)
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 < TasmotaGlobal.devices_present)
}
if (!Settings.flag5.mqtt_switches) { // SetOption114 (0) - Detach Swiches from relays and enable MQTT action state for all the SwitchModes
if (!SendKey(KEY_SWITCH, i +1, switchflag)) { // Execute command via MQTT
ExecuteCommandPower(i +1, switchflag, SRC_SWITCH); // Execute command internally (if i < TasmotaGlobal.devices_present)
}
} else { MqttAction = switchflag; }
}
if (MqttAction != POWER_NONE && Settings.flag5.mqtt_switches) {
MqttSwitchTopic(i +1, MqttAction); // SetOption114 (0) - Detach Swiches from relays and enable MQTT action state for all the SwitchModes
MqttAction = POWER_NONE;
}
}
}
}
void MqttSwitchTopic(uint8_t switch_id, uint8_t MqttAction)
{
char scommand[CMDSZ];
char stopic[TOPSZ];
char mqttstate[16];
if (!Settings.flag.hass_discovery) {
if (MqttAction <= 3) {
if (MqttAction != 3) { SendKey(KEY_SWITCH, switch_id, MqttAction); }
snprintf_P(mqttstate, sizeof(mqttstate), PSTR("%s"), SettingsText(SET_STATE_TXT1 + MqttAction));
} else {
GetTextIndexed(mqttstate, sizeof(mqttstate), MqttAction, kSwitchPressStates);
}
snprintf_P(scommand, sizeof(scommand), PSTR("SWITCH%d"), switch_id);
GetTopic_P(stopic, STAT, TasmotaGlobal.mqtt_topic, scommand);
Response_P(S_JSON_COMMAND_SVALUE, "ACTION", mqttstate);
MqttPublish(stopic);
}
}
void SwitchLoop(void)
{
if (Switch.present) {

View File

@ -497,7 +497,7 @@ bool SendKey(uint32_t key, uint32_t device, uint32_t state)
XdrvCall(FUNC_ANY_KEY);
XdrvMailbox.payload = payload_save;
#ifdef USE_PWM_DIMMER
result = true;
if (PWM_DIMMER == TasmotaGlobal.module_type) result = true;
}
#endif // USE_PWM_DIMMER
return result;