mirror of https://github.com/arendst/Tasmota.git
[tuyamcu_v2] Fix suppressed dimmer updates from MQTT (#20950)
The driver tried to avoid loops when state updates from the MCU (eg from physical button press) could be reflected back by Tasmota and trigger another MCU command, followed by a state update. It did this by tracking the source of the command in the last_source and last_command_source variables, suppressing the command if either of those was SRC_SWITCH. However this logic is faulty: Since there are two last_source variables to check, a command might reset one of them, but the other would still suppress the update. As it turns out, MQTT commands would only set last_source but not last_command_source. As a result, any dimmer changes via MQTT would be dropped by the driver and not applied to the MCU. Switch functionality (on/off) was still working because those do not rely on last_command_source, only last_source. This change removes the loop detection logic altogether for dimmer updates. This should be safe, because the driver already has the latest dimmer value in its shadow state, and will not try to re-apply a current value, thus breaking the loop. This patch has been tested with several CE-WF500D dimmers which had this problem.
This commit is contained in:
parent
cc8614da9c
commit
1a462c986c
|
@ -401,7 +401,6 @@ struct TasmotaGlobal_t {
|
|||
uint8_t module_type; // Current copy of Settings->module or user template type
|
||||
uint8_t emulated_module_type; // Emulated module type as requested by ESP32
|
||||
uint8_t last_source; // Last command source
|
||||
uint8_t last_command_source; // Last command source
|
||||
uint8_t shutters_present; // Number of actual define shutters
|
||||
uint8_t discovery_counter; // Delayed discovery counter
|
||||
uint8_t power_on_delay; // Delay relay power on to reduce power surge (SetOption47)
|
||||
|
|
|
@ -338,7 +338,6 @@ void ExecuteCommand(const char *cmnd, uint32_t source)
|
|||
// cmnd: "var1=1" = stopic "var1" and svalue "=1"
|
||||
SHOW_FREE_MEM(PSTR("ExecuteCommand"));
|
||||
ShowSource(source);
|
||||
TasmotaGlobal.last_command_source = source;
|
||||
|
||||
const char *pos = cmnd;
|
||||
while (*pos && isspace(*pos)) {
|
||||
|
|
|
@ -1245,11 +1245,12 @@ bool TuyaSetPower(void)
|
|||
uint8_t dev = TasmotaGlobal.active_device-1;
|
||||
uint8_t value = bitRead(rpower, dev) ^ bitRead(TasmotaGlobal.rel_inverted, dev);
|
||||
|
||||
if (source != SRC_SWITCH && TuyaSerial && dpid) { // ignore to prevent loop from pushing state from faceplate interaction
|
||||
// Ignore the command if the source is SRC_SWITCH, to prevent loop from pushing state
|
||||
// from faceplate interaction. (This is probably unnecessary, as we store the latest state
|
||||
// and will not update it with the same value.)
|
||||
if (source != SRC_SWITCH && TuyaSerial && dpid) {
|
||||
TuyaSendBool(dpid, value);
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: post rpower%d v%d dp%d s%d d%d"), rpower, value, dpid, source, dev);
|
||||
// no longer needed as commands wait for ack.
|
||||
//delay(20); // Hack when power is off and dimmer is set then both commands go too soon to Serial out.
|
||||
status = true;
|
||||
} else {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: rpower%d v%d dp%d ignored s%d d%d"), rpower, value, dpid, source, dev);
|
||||
|
@ -1265,11 +1266,6 @@ bool TuyaSetChannels(void)
|
|||
char hex_char[15];
|
||||
bool noupd = false;
|
||||
|
||||
if ((SRC_SWITCH == TasmotaGlobal.last_source) || (SRC_SWITCH == TasmotaGlobal.last_command_source)) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: setchan disbl SRC_SWITCH"));
|
||||
// but pretend we did set them
|
||||
return true;
|
||||
}
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: setchan"));
|
||||
|
||||
bool LightMode = TuyaGetDpId(TUYA_MCU_FUNC_MODESET) != 0;
|
||||
|
@ -1619,12 +1615,12 @@ void TuyaProcessRxedDP(uint8_t dpid, uint8_t type, uint8_t *data, int dpDataLen)
|
|||
AddLog(LOG_LEVEL_DEBUG, PSTR("T:fn%d Relay%d-->M%s T%s"), fnId, fnId - TUYA_MCU_FUNC_REL1 + 1, value?"On":"Off",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1)?"On":"Off");
|
||||
if (value != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1)) {
|
||||
if (!value) { PowerOff = true; }
|
||||
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1 + 1, value, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
|
||||
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1 + 1, value, SRC_SWITCH);
|
||||
}
|
||||
} else if (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("T:fn%d Relay%d-Inv-->M%s T%s"), fnId, fnId - TUYA_MCU_FUNC_REL1_INV + 1, value?"Off":"On",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1?"Off":"On");
|
||||
if (value != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1) {
|
||||
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1_INV + 1, value ^ 1, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
|
||||
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1_INV + 1, value ^ 1, SRC_SWITCH);
|
||||
if (value) { PowerOff = true; }
|
||||
}
|
||||
} else if (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) {
|
||||
|
|
Loading…
Reference in New Issue