From 81aa57947100f641a350427f0204c1a0bef94a57 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 19 Dec 2021 16:41:10 +0100 Subject: [PATCH] Refactor Tuya driver to enable ESP32 support Refactor Tuya driver to enable ESP32 support (#14086, #14106) --- tasmota/tasmota_globals.h | 3 - tasmota/xdrv_12_discovery.ino | 6 +- tasmota/xdrv_12_home_assistant.ino | 24 ++++---- tasmota/xdrv_16_tuyamcu.ino | 92 +++++++++++++++++------------- 4 files changed, 69 insertions(+), 56 deletions(-) diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index aa9f97063..b69f1f166 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -133,7 +133,6 @@ String EthernetMacAddress(void); #undef FIRMWARE_MINIMAL // Minimal is not supported as not needed // Hardware has no ESP32 -#undef USE_TUYA_DIMMER #undef USE_PWM_DIMMER #undef USE_EXS_DIMMER #undef USE_ARMTRONIX_DIMMERS @@ -146,9 +145,7 @@ String EthernetMacAddress(void); #undef USE_RF_FLASH // Not ported (yet) - #undef USE_MY92X1 -#undef USE_TUYA_MCU #undef USE_PS_16_DZ #undef USE_HM10 // Disable support for HM-10 as a BLE-bridge as an alternative is using the internal ESP32 BLE diff --git a/tasmota/xdrv_12_discovery.ino b/tasmota/xdrv_12_discovery.ino index da92495d5..112df2387 100644 --- a/tasmota/xdrv_12_discovery.ino +++ b/tasmota/xdrv_12_discovery.ino @@ -48,10 +48,12 @@ void TasDiscoverMessage(void) { } bool TuyaMod = false; +#ifdef USE_TUYA_MCU + TuyaMod = IsModuleTuya(); +#endif bool iFanMod = false; #ifdef ESP8266 - if ((TUYA_DIMMER == TasmotaGlobal.module_type) || (SK03_TUYA == TasmotaGlobal.module_type)) { TuyaMod = true; }; - if ((SONOFF_IFAN02 == TasmotaGlobal.module_type) || (SONOFF_IFAN03 == TasmotaGlobal.module_type)) { iFanMod = true; }; + iFanMod = ((SONOFF_IFAN02 == TasmotaGlobal.module_type) || (SONOFF_IFAN03 == TasmotaGlobal.module_type)); #endif // ESP8266 ResponseAppend_P(PSTR("]," // Friendly Names (end) diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index a686531f6..e1cdc5179 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -215,10 +215,12 @@ void HassDiscoverMessage(void) { } bool TuyaMod = false; +#ifdef USE_TUYA_MCU + TuyaMod = IsModuleTuya(); +#endif bool iFanMod = false; #ifdef ESP8266 - if ((TUYA_DIMMER == TasmotaGlobal.module_type) || (SK03_TUYA == TasmotaGlobal.module_type)) { TuyaMod = true; }; - if ((SONOFF_IFAN02 == TasmotaGlobal.module_type) || (SONOFF_IFAN03 == TasmotaGlobal.module_type)) { iFanMod = true; }; + iFanMod = ((SONOFF_IFAN02 == TasmotaGlobal.module_type) || (SONOFF_IFAN03 == TasmotaGlobal.module_type)); #endif // ESP8266 ResponseAppend_P(PSTR("]," // Friendly Names (end) @@ -456,12 +458,14 @@ void HAssAnnounceRelayLight(void) uint8_t TuyaDim = 0; power_t shutter_mask = 0; - #ifdef ESP8266 - if (PWM_DIMMER == TasmotaGlobal.module_type ) { PwmMod = true; } // - if (SONOFF_IFAN02 == TasmotaGlobal.module_type || SONOFF_IFAN03 == TasmotaGlobal.module_type) { FanMod = true; } - if (SONOFF_DUAL == TasmotaGlobal.module_type) { valid_relay = 2; } - if (TUYA_DIMMER == TasmotaGlobal.module_type || SK03_TUYA == TasmotaGlobal.module_type) { TuyaMod = true; } - #endif //ESP8266 +#ifdef ESP8266 + PwmMod = (PWM_DIMMER == TasmotaGlobal.module_type); + FanMod = (SONOFF_IFAN02 == TasmotaGlobal.module_type || SONOFF_IFAN03 == TasmotaGlobal.module_type); + if (SONOFF_DUAL == TasmotaGlobal.module_type) { valid_relay = 2; } +#endif //ESP8266 +#ifdef USE_TUYA_MCU + TuyaMod = IsModuleTuya(); +#endif #ifdef USE_LIGHT // If there is a special Light to be enabled and managed with SetOption68 or SetOption37 >= 128, Discovery calculates the maximum number of entities to be generated in advance @@ -1038,10 +1042,10 @@ void HAssAnnounceShutters(void) GetTopic_P(stemp1, STAT, TasmotaGlobal.mqtt_topic, PSTR("SHUTTER")); GetTopic_P(stemp2, CMND, TasmotaGlobal.mqtt_topic, PSTR("ShutterPosition")); TryResponseAppend_P(HASS_DISCOVER_SHUTTER_POS, stemp1, i + 1, stemp2, i + 1); - + GetTopic_P(stemp1, CMND, TasmotaGlobal.mqtt_topic, PSTR("ShutterTilt")); TryResponseAppend_P(HASS_DISCOVER_SHUTTER_TILT, stemp1, i + 1, Settings->shutter_tilt_config[3][i], Settings->shutter_tilt_config[4][i]); - + TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); TryResponseAppend_P(PSTR("}")); } else { diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index 5750839c5..3c550424f 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -81,6 +81,7 @@ struct TUYA { bool send_success_next_second = false; // Second command success in low power mode uint32_t ignore_dimmer_cmd_timeout = 0; // Time until which received dimmer commands should be ignored bool ignore_tuyareceived = false; // When a modeset changes ignore stat + bool active; } Tuya; #define D_JSON_TUYA_MCU_RECEIVED "TuyaReceived" @@ -109,9 +110,16 @@ void (* const TuyaCommand[])(void) PROGMEM = { /*********************************************************************************************\ * Web Interface \*********************************************************************************************/ -bool IsModuleTuya(void) -{ - return ((TUYA_DIMMER == TasmotaGlobal.module_type) || (SK03_TUYA == TasmotaGlobal.module_type)); + +bool IsModuleTuya(void) { + bool is_tuya = Tuya.active; +//#ifdef ESP8266 + // This is not a Tuya driven device. It uses a Tuya provided ESP8266. Why it was here is a mystery to me. +// if (SK03_TUYA == TasmotaGlobal.module_type) { +// is_tuya = true; +// } +//#endif + return is_tuya; } bool AsModuleTuyaMS(void) // ModeSet Layout @@ -123,6 +131,7 @@ bool TuyaModeSet(void) // ModeSet Status { return Tuya.ModeSet; } + /*********************************************************************************************\ * Web Interface \*********************************************************************************************/ @@ -1055,8 +1064,10 @@ void TuyaNormalPowerModePacketProcess(void) * API Functions \*********************************************************************************************/ -bool TuyaModuleSelected(void) -{ +bool TuyaModuleSelected(void) { +#ifdef ESP8266 + if (TUYA_DIMMER != TasmotaGlobal.module_type) { return false; } + if (!PinUsed(GPIO_TUYA_RX) || !PinUsed(GPIO_TUYA_TX)) { // fallback to hardware-serial if not explicitly selected SetPin(1, AGPIO(GPIO_TUYA_TX)); SetPin(3, AGPIO(GPIO_TUYA_RX)); @@ -1064,6 +1075,8 @@ bool TuyaModuleSelected(void) Settings->my_gp.io[3] = AGPIO(GPIO_TUYA_RX); TasmotaGlobal.restart_flag = 2; } +#endif + if (!PinUsed(GPIO_TUYA_RX) || !PinUsed(GPIO_TUYA_TX)) { return false; } if (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER) == 0 && TUYA_DIMMER_ID > 0) { TuyaAddMcuFunc(TUYA_MCU_FUNC_DIMMER, TUYA_DIMMER_ID); @@ -1119,8 +1132,7 @@ bool TuyaModuleSelected(void) return true; } -void TuyaInit(void) -{ +void TuyaInit(void) { int baudrate = 9600; if (Settings->flag4.tuyamcu_baudrate) { baudrate = 115200; } // SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200) @@ -1134,10 +1146,12 @@ void TuyaInit(void) Tuya.ignore_topic_timeout = millis() + 1000; // suppress /STAT topic for 1000ms to avoid data overflow AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Request MCU configuration at %d bps"), baudrate); - + Tuya.heartbeat_timer = 0; // init heartbeat timer when dimmer init is done + return; } + free(Tuya.buffer); } - Tuya.heartbeat_timer = 0; // init heartbeat timer when dimmer init is done + Tuya.active = false; } void TuyaSerialInput(void) @@ -1332,33 +1346,6 @@ void TuyaSetTime(void) { } #endif //USE_TUYA_TIME -#ifdef USE_ENERGY_SENSOR - -/*********************************************************************************************\ - * Energy Interface -\*********************************************************************************************/ - -bool Xnrg32(uint8_t function) -{ - bool result = false; - - if (TUYA_DIMMER == TasmotaGlobal.module_type) { - if (FUNC_PRE_INIT == function) { - if (TuyaGetDpId(TUYA_MCU_FUNC_POWER) != 0 || TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) != 0) { - if (TuyaGetDpId(TUYA_MCU_FUNC_CURRENT) == 0 && TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) == 0) { - Energy.current_available = false; - } - if (TuyaGetDpId(TUYA_MCU_FUNC_VOLTAGE) == 0 && TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) == 0) { - Energy.voltage_available = false; - } - TasmotaGlobal.energy_driver = XNRG_32; - } - } - } - return result; -} -#endif // USE_ENERGY_SENSOR - /*********************************************************************************************\ * Sensors \*********************************************************************************************/ @@ -1471,18 +1458,41 @@ void TuyaAddButton(void) { * Interface \*********************************************************************************************/ -bool Xdrv16(uint8_t function) +#ifdef USE_ENERGY_SENSOR + +bool Xnrg32(uint8_t function) { bool result = false; - if (TUYA_DIMMER == TasmotaGlobal.module_type) { + if (Tuya.active) { + if (FUNC_PRE_INIT == function) { + if (TuyaGetDpId(TUYA_MCU_FUNC_POWER) != 0 || TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) != 0) { + if (TuyaGetDpId(TUYA_MCU_FUNC_CURRENT) == 0 && TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) == 0) { + Energy.current_available = false; + } + if (TuyaGetDpId(TUYA_MCU_FUNC_VOLTAGE) == 0 && TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) == 0) { + Energy.voltage_available = false; + } + TasmotaGlobal.energy_driver = XNRG_32; + } + } + } + return result; +} +#endif // USE_ENERGY_SENSOR + +bool Xdrv16(uint8_t function) { + bool result = false; + + if (FUNC_MODULE_INIT == function) { + result = TuyaModuleSelected(); + Tuya.active = result; + } + else if (Tuya.active) { switch (function) { case FUNC_LOOP: if (TuyaSerial) { TuyaSerialInput(); } break; - case FUNC_MODULE_INIT: - result = TuyaModuleSelected(); - break; case FUNC_PRE_INIT: TuyaInit(); break;