Refactor Tuya driver to enable ESP32 support

Refactor Tuya driver to enable ESP32 support (#14086, #14106)
This commit is contained in:
Theo Arends 2021-12-19 16:41:10 +01:00
parent 12c3044148
commit 81aa579471
4 changed files with 69 additions and 56 deletions

View File

@ -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

View File

@ -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)

View File

@ -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 {

View File

@ -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;