Skip to content

Commit c622328

Browse files
committed
[tuyamcu_v2] Fix suppressed dimmer updates from MQTT
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 one of them. 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.
1 parent 3e0ebc7 commit c622328

File tree

3 files changed

+6
-12
lines changed

3 files changed

+6
-12
lines changed

tasmota/tasmota.ino

-1
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,6 @@ struct TasmotaGlobal_t {
401401
uint8_t module_type; // Current copy of Settings->module or user template type
402402
uint8_t emulated_module_type; // Emulated module type as requested by ESP32
403403
uint8_t last_source; // Last command source
404-
uint8_t last_command_source; // Last command source
405404
uint8_t shutters_present; // Number of actual define shutters
406405
uint8_t discovery_counter; // Delayed discovery counter
407406
uint8_t power_on_delay; // Delay relay power on to reduce power surge (SetOption47)

tasmota/tasmota_support/support_command.ino

-1
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,6 @@ void ExecuteCommand(const char *cmnd, uint32_t source)
338338
// cmnd: "var1=1" = stopic "var1" and svalue "=1"
339339
SHOW_FREE_MEM(PSTR("ExecuteCommand"));
340340
ShowSource(source);
341-
TasmotaGlobal.last_command_source = source;
342341

343342
const char *pos = cmnd;
344343
while (*pos && isspace(*pos)) {

tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino

+6-10
Original file line numberDiff line numberDiff line change
@@ -1245,11 +1245,12 @@ bool TuyaSetPower(void)
12451245
uint8_t dev = TasmotaGlobal.active_device-1;
12461246
uint8_t value = bitRead(rpower, dev) ^ bitRead(TasmotaGlobal.rel_inverted, dev);
12471247

1248-
if (source != SRC_SWITCH && TuyaSerial && dpid) { // ignore to prevent loop from pushing state from faceplate interaction
1248+
// Ignore the command if the source is SRC_SWITCH, to prevent loop from pushing state
1249+
// from faceplate interaction. (This is probably unnecessary, as we store the latest state
1250+
// and will not update it with the same value.)
1251+
if (source != SRC_SWITCH && TuyaSerial && dpid) {
12491252
TuyaSendBool(dpid, value);
12501253
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: post rpower%d v%d dp%d s%d d%d"), rpower, value, dpid, source, dev);
1251-
// no longer needed as commands wait for ack.
1252-
//delay(20); // Hack when power is off and dimmer is set then both commands go too soon to Serial out.
12531254
status = true;
12541255
} else {
12551256
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)
12651266
char hex_char[15];
12661267
bool noupd = false;
12671268

1268-
if ((SRC_SWITCH == TasmotaGlobal.last_source) || (SRC_SWITCH == TasmotaGlobal.last_command_source)) {
1269-
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: setchan disbl SRC_SWITCH"));
1270-
// but pretend we did set them
1271-
return true;
1272-
}
12731269
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: setchan"));
12741270

12751271
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)
16191615
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");
16201616
if (value != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1)) {
16211617
if (!value) { PowerOff = true; }
1622-
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
1618+
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1 + 1, value, SRC_SWITCH);
16231619
}
16241620
} else if (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) {
16251621
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");
16261622
if (value != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1) {
1627-
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
1623+
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1_INV + 1, value ^ 1, SRC_SWITCH);
16281624
if (value) { PowerOff = true; }
16291625
}
16301626
} else if (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) {

0 commit comments

Comments
 (0)