From efd1870d5ec5f7704ddbd3809c7e7487f510b0b7 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 3 Sep 2019 11:23:44 +0100 Subject: [PATCH 1/6] Tuya: Make Tuya Mcu implementation more configurable. More and more Tuya MCU based devices are coming in the market and people requesting to support them. This patch makes Tuya module more configurable and easier to add new functionalities. Its not just a dimmer or a switch anymore. After this Patch Tuya MCU module has a list of supported functions and the user would need to map the functionId to dpId of their device. Once mapped correctly the Tuya module will take care for handling proper function for dpId. Currently functions supported are 1. Relays1 to 8 : FunctionID 11 to 18 2. Dimmer : FunctionID 21 3. Power ( Deca Watt ) : Function ID 31 4. Current ( milli Amps ) : Function ID 32 5. Voltage ( deca Volts ) : Function ID 33 The changes are - Use a TuyaMCU command to map DPs to Functions instead of many different SetOptions. SetOption41, 44, 45, 46, 65 won't be needed after this patch. - TuyaMCU command takes argument like `11,1` which means Map Function id 11 (Relay1) to DPID 1 - Migrates old settings flags and options to new TuyaMap command --- sonoff/i18n.h | 4 + sonoff/settings.h | 11 +- sonoff/settings.ino | 35 +++++ sonoff/sonoff_version.h | 2 +- sonoff/xdrv_16_tuyadimmer.ino | 257 ++++++++++++++++++++++++++-------- 5 files changed, 249 insertions(+), 60 deletions(-) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 463ec13cf..287476dd7 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -444,6 +444,10 @@ #define D_CMND_LATITUDE "Latitude" #define D_CMND_LONGITUDE "Longitude" +// Commands xdrv_16_tuyadimmer.ino + +#define D_CMND_TUYA_MCU "TuyaMCU" + // Commands xdrv_23_zigbee.ino #define D_CMND_ZIGBEEZNPSEND "ZigbeeZNPSend" #define D_JSON_ZIGBEEZNPRECEIVED "ZigbeeZNPReceived" diff --git a/sonoff/settings.h b/sonoff/settings.h index f326dc529..bc8564cca 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -185,6 +185,14 @@ typedef struct { uint32_t last_return_kWhtotal; } EnergyUsage; + +typedef struct { + uint8_t fnid = 0; + uint8_t dpid = 0; +} TuyaFnidDpidMap; + +const uint8_t MAX_TUYA_FUNCTIONS = 16; + /* struct SYSCFG { unsigned long cfg_holder; // 000 Pre v6 header @@ -366,8 +374,9 @@ struct SYSCFG { char rules[MAX_RULE_SETS][MAX_RULE_SIZE]; // 800 uses 512 bytes in v5.12.0m, 3 x 512 bytes in v5.14.0b uint8_t data8[32]; // E00 uint16_t data16[16]; // E20 + TuyaFnidDpidMap tuya_fnid_map[MAX_TUYA_FUNCTIONS]; // E40 32 bytes - uint8_t free_e20[448]; // E40 + uint8_t free_e20[416]; // E60 // FFF last location } Settings; diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 4bdae99ff..7c44bf053 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -1096,6 +1096,41 @@ void SettingsDelta(void) Settings.sbaudrate = Settings.ex_sbaudrate * 4; } + if (Settings.version < 0x0606000A) { + uint8_t tuyaindex = 0; + if (Settings.param[P_TUYA_DIMMER_ID] > 0) { + Settings.tuya_fnid_map[tuyaindex].fnid = 21; //TUYA_MCU_FUNC_DIMMER; // Move Tuya Dimmer Id to Map + Settings.tuya_fnid_map[tuyaindex].dpid = Settings.param[P_TUYA_DIMMER_ID]; + tuyaindex++; + } else if (Settings.flag3.tuya_disable_dimmer == 1) { + Settings.tuya_fnid_map[tuyaindex].fnid = 11; //TUYA_MCU_FUNC_REL1; // Create FnID for Switches + Settings.tuya_fnid_map[tuyaindex].dpid = 1; + tuyaindex++; + } + if (Settings.param[P_TUYA_RELAYS] > 0) { + for (uint8_t i = 0 ; i < Settings.param[P_TUYA_RELAYS]; i++) { + Settings.tuya_fnid_map[tuyaindex].fnid = 12 + i; //TUYA_MCU_FUNC_REL2+; // Create FnID for Switches + Settings.tuya_fnid_map[tuyaindex].dpid = i + 2; + tuyaindex++; + } + } + if (Settings.param[P_TUYA_POWER_ID] > 0) { + Settings.tuya_fnid_map[tuyaindex].fnid = 31; //TUYA_MCU_FUNC_POWER; // Move Tuya Power Id to Map + Settings.tuya_fnid_map[tuyaindex].dpid = Settings.param[P_TUYA_POWER_ID]; + tuyaindex++; + } + if (Settings.param[P_TUYA_VOLTAGE_ID] > 0) { + Settings.tuya_fnid_map[tuyaindex].fnid = 33; //TUYA_MCU_FUNC_VOLTAGE; // Move Tuya Voltage Id to Map + Settings.tuya_fnid_map[tuyaindex].dpid = Settings.param[P_TUYA_VOLTAGE_ID]; + tuyaindex++; + } + if (Settings.param[P_TUYA_CURRENT_ID] > 0) { + Settings.tuya_fnid_map[tuyaindex].fnid = 32; //TUYA_MCU_FUNC_CURRENT; // Move Tuya Current Id to Map + Settings.tuya_fnid_map[tuyaindex].dpid = Settings.param[P_TUYA_CURRENT_ID]; + tuyaindex++; + } + + } Settings.version = VERSION; SettingsSave(1); } diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index e614fbf36..962434a63 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,6 +20,6 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -const uint32_t VERSION = 0x06060009; +const uint32_t VERSION = 0x0606000A; #endif // _SONOFF_VERSION_H_ diff --git a/sonoff/xdrv_16_tuyadimmer.ino b/sonoff/xdrv_16_tuyadimmer.ino index 608236f4b..452a65346 100644 --- a/sonoff/xdrv_16_tuyadimmer.ino +++ b/sonoff/xdrv_16_tuyadimmer.ino @@ -61,10 +61,130 @@ struct TUYA { int byte_counter = 0; // Index in serial receive buffer } Tuya; + +enum TuyaSupportedFunctions { + TUYA_MCU_FUNC_NONE, + // TUYA_MCU_FUNC_KEY1 = 1, // Buttons + // TUYA_MCU_FUNC_KEY2, + // TUYA_MCU_FUNC_KEY3, + // TUYA_MCU_FUNC_KEY4, + TUYA_MCU_FUNC_REL1 = 11, // Relays + TUYA_MCU_FUNC_REL2, + TUYA_MCU_FUNC_REL3, + TUYA_MCU_FUNC_REL4, + TUYA_MCU_FUNC_REL5, + TUYA_MCU_FUNC_REL6, + TUYA_MCU_FUNC_REL7, + TUYA_MCU_FUNC_REL8, + TUYA_MCU_FUNC_DIMMER = 21, + TUYA_MCU_FUNC_POWER = 31, + TUYA_MCU_FUNC_CURRENT, + TUYA_MCU_FUNC_VOLTAGE, + TUYA_MCU_FUNC_LAST = 255 +}; + +const char kTuyaCommand[] PROGMEM = "|" // No prefix + D_CMND_TUYA_MCU; + +void (* const TuyaCommand[])(void) PROGMEM = { + &CmndTuyaMcu +}; + + +/* + +TuyaMap fnid,dpid + +*/ + +void CmndTuyaMcu(void) { + if (XdrvMailbox.data_len > 0) { + char *p; + uint8_t i = 0; + uint8_t parm[3] = { 0 }; + for (char *str = strtok_r(XdrvMailbox.data, ", ", &p); str && i < 2; str = strtok_r(nullptr, ", ", &p)) { + parm[i] = strtoul(str, nullptr, 0); + i++; + } + + if (TuyaFuncIdValid(parm[0])) { + TuyaAddMcuFunc(parm[0], parm[1]); + restart_flag = 2; + } else { + AddLog_P2(LOG_LEVEL_ERROR, PSTR("TYA: TuyaMcu Invalid function id=%d"), parm[0]); + } + + } + + Response_P(PSTR("[")); + bool added = false; + for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) { + if (Settings.tuya_fnid_map[i].fnid != 0) { + if (added) { + ResponseAppend_P(PSTR(",")); + } + ResponseAppend_P(PSTR("{\"fnId\":%d, \"dpId\":%d}" ), Settings.tuya_fnid_map[i].fnid, Settings.tuya_fnid_map[i].dpid); + added = true; + } + } + ResponseAppend_P(PSTR("]")); +} + /*********************************************************************************************\ * Internal Functions \*********************************************************************************************/ +void TuyaAddMcuFunc(uint8_t fnId, uint8_t dpId) { + bool added = false; + + if (fnId == 0 || dpId == 0) { // Delete entry + for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) { + if ((dpId > 0 && Settings.tuya_fnid_map[i].dpid == dpId) || (fnId > TUYA_MCU_FUNC_NONE && Settings.tuya_fnid_map[i].fnid == fnId)) { + Settings.tuya_fnid_map[i].fnid = TUYA_MCU_FUNC_NONE; + Settings.tuya_fnid_map[i].dpid = 0; + break; + } + } + } else { // Add or update + for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) { + if (Settings.tuya_fnid_map[i].dpid == dpId || Settings.tuya_fnid_map[i].dpid == 0 || Settings.tuya_fnid_map[i].fnid == fnId || Settings.tuya_fnid_map[i].fnid == 0) { + if (!added) { // Update entry if exisiting entry or add + Settings.tuya_fnid_map[i].fnid = fnId; + Settings.tuya_fnid_map[i].dpid = dpId; + added = true; + } else if (Settings.tuya_fnid_map[i].dpid == dpId || Settings.tuya_fnid_map[i].fnid == fnId) { // Remove existing entry if added to empty place + Settings.tuya_fnid_map[i].fnid = TUYA_MCU_FUNC_NONE; + Settings.tuya_fnid_map[i].dpid = 0; + } + } + } + } +} + +inline bool TuyaFuncIdValid(uint8_t fnId) { + return (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) || + fnId == TUYA_MCU_FUNC_DIMMER || + (fnId >= TUYA_MCU_FUNC_POWER && fnId <= TUYA_MCU_FUNC_VOLTAGE); +} + +uint8_t TuyaGetFuncId(uint8_t dpid) { + for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) { + if (Settings.tuya_fnid_map[i].dpid == dpid) { + return Settings.tuya_fnid_map[i].fnid; + } + } + return TUYA_MCU_FUNC_NONE; +} + +uint8_t TuyaGetDpId(uint8_t fnId) { + for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) { + if (Settings.tuya_fnid_map[i].fnid == fnId) { + return Settings.tuya_fnid_map[i].dpid; + } + } + return 0; +} + void TuyaSendCmd(uint8_t cmd, uint8_t payload[] = nullptr, uint16_t payload_len = 0) { uint8_t checksum = (0xFF + cmd + (payload_len >> 8) + (payload_len & 0xFF)); @@ -146,24 +266,26 @@ bool TuyaSetChannels(void) void LightSerialDuty(uint8_t duty) { - if (duty > 0 && !Tuya.ignore_dim && TuyaSerial) { + uint8_t dpid = TuyaGetDpId(TUYA_MCU_FUNC_DIMMER); + if (duty > 0 && !Tuya.ignore_dim && TuyaSerial && dpid > 0) { if (Settings.flag3.tuya_dimmer_min_limit) { // Enable dimming limit SetOption69: Enabled by default if (duty < 25) { duty = 25; } // dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself } - if (Settings.flag3.tuya_disable_dimmer == 0) { duty = changeUIntScale(duty, 0, 255, 0, Settings.param[P_TUYA_DIMMER_MAX]); if (Tuya.new_dim != duty) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Send dim value=%d (id=%d)"), duty, Settings.param[P_TUYA_DIMMER_ID]); - TuyaSendValue(Settings.param[P_TUYA_DIMMER_ID], duty); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Send dim value=%d (id=%d)"), duty, dpid); + TuyaSendValue(dpid, duty); } } - } else { + } else if (dpid > 0) { Tuya.ignore_dim = false; // reset flag if (Settings.flag3.tuya_disable_dimmer == 0) { duty = changeUIntScale(duty, 0, 255, 0, Settings.param[P_TUYA_DIMMER_MAX]); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Send dim skipped value=%d"), duty); // due to 0 or already set } + } else { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Cannot set dimmer. Dimmer Id unknown")); // } } @@ -189,6 +311,7 @@ void TuyaResetWifi(void) void TuyaPacketProcess(void) { char scmnd[20]; + uint8_t fnId = TUYA_MCU_FUNC_NONE; switch (Tuya.buffer[3]) { @@ -201,57 +324,60 @@ void TuyaPacketProcess(void) break; case TUYA_CMD_STATE: - if (Tuya.buffer[5] == 5) { // on/off packet + fnId = TuyaGetFuncId(Tuya.buffer[6]); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: FnId=%d is set for dpId=%d"), fnId, Tuya.buffer[6]); + // if (TuyaFuncIdValid(fnId)) { + if (Tuya.buffer[5] == 5) { // on/off packet - /*if ((power || Settings.light_dimmer > 0) && (power != Tuya.buffer[10])) { - ExecuteCommandPower(1, Tuya.buffer[10], SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction - }*/ - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Device-%d --> MCU State: %s Current State:%s"),Tuya.buffer[6],Tuya.buffer[10]?"On":"Off",bitRead(power, Tuya.buffer[6]-1)?"On":"Off"); - if ((power || Settings.light_dimmer > 0) && (Tuya.buffer[10] != bitRead(power, Tuya.buffer[6]-1))) { - ExecuteCommandPower(Tuya.buffer[6], Tuya.buffer[10], SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction - } - } - else if (Tuya.buffer[5] == 8) { // Long value packet - - if (Settings.flag3.tuya_disable_dimmer == 0) { - if (!Settings.param[P_TUYA_DIMMER_ID]) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Autoconfiguring Dimmer ID %d"), Tuya.buffer[6]); - Settings.param[P_TUYA_DIMMER_ID] = Tuya.buffer[6]; - } - if (Settings.param[P_TUYA_DIMMER_ID] == Tuya.buffer[6]) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Dim State=%d"), Tuya.buffer[13]); - Tuya.new_dim = changeUIntScale((uint8_t) Tuya.buffer[13], 0, Settings.param[P_TUYA_DIMMER_MAX], 0, 100); - if ((power || Settings.flag3.tuya_apply_o20) && (Tuya.new_dim > 0) && (abs(Tuya.new_dim - Settings.light_dimmer) > 1)) { - Tuya.ignore_dim = true; - - snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), Tuya.new_dim ); - ExecuteCommand(scmnd, SRC_SWITCH); + if (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Device-%d --> MCU State: %s Current State:%s"),Tuya.buffer[6],Tuya.buffer[10]?"On":"Off",bitRead(power, fnId - TUYA_MCU_FUNC_REL1)?"On":"Off"); + if ((power || Settings.light_dimmer > 0) && (Tuya.buffer[10] != bitRead(power, fnId - TUYA_MCU_FUNC_REL1))) { + ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[10], SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction } } + } + else if (Tuya.buffer[5] == 8) { // Long value packet + if (fnId == TUYA_MCU_FUNC_DIMMER) { + // if (!Settings.param[P_TUYA_DIMMER_ID]) { + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Autoconfiguring Dimmer ID %d"), Tuya.buffer[6]); + // Settings.param[P_TUYA_DIMMER_ID] = Tuya.buffer[6]; + // } + // if (Settings.param[P_TUYA_DIMMER_ID] == Tuya.buffer[6]) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Dim State=%d"), Tuya.buffer[13]); + Tuya.new_dim = changeUIntScale((uint8_t) Tuya.buffer[13], 0, Settings.param[P_TUYA_DIMMER_MAX], 0, 100); + if ((power || Settings.flag3.tuya_apply_o20) && (Tuya.new_dim > 0) && (abs(Tuya.new_dim - Settings.light_dimmer) > 1)) { + Tuya.ignore_dim = true; -#ifdef USE_ENERGY_SENSOR - if (Settings.param[P_TUYA_VOLTAGE_ID] == Tuya.buffer[6]) { - Energy.voltage = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 10; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Voltage=%d"), Settings.param[P_TUYA_VOLTAGE_ID], (Tuya.buffer[12] << 8 | Tuya.buffer[13])); - } else if (Settings.param[P_TUYA_CURRENT_ID] == Tuya.buffer[6]) { - Energy.current = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 1000; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Current=%d"), Settings.param[P_TUYA_CURRENT_ID], (Tuya.buffer[12] << 8 | Tuya.buffer[13])); - } else if (Settings.param[P_TUYA_POWER_ID] == Tuya.buffer[6]) { - Energy.active_power = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 10; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Active_Power=%d"), Settings.param[P_TUYA_POWER_ID], (Tuya.buffer[12] << 8 | Tuya.buffer[13])); - - if (Tuya.lastPowerCheckTime != 0 && Energy.active_power > 0) { - Energy.kWhtoday += (float)Energy.active_power * (Rtc.utc_time - Tuya.lastPowerCheckTime) / 36; - EnergyUpdateToday(); + snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), Tuya.new_dim ); + ExecuteCommand(scmnd, SRC_SWITCH); + } + // } } - Tuya.lastPowerCheckTime = Rtc.utc_time; - } else if (Settings.param[P_TUYA_DIMMER_ID] != Tuya.buffer[6]){ - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Unknown ID=%d"), Tuya.buffer[6]); - } -#endif // USE_ENERGY_SENSOR - } + #ifdef USE_ENERGY_SENSOR + else if (fnId == TUYA_MCU_FUNC_VOLTAGE) { + Energy.voltage = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 10; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Voltage=%d"), Tuya.buffer[6], (Tuya.buffer[12] << 8 | Tuya.buffer[13])); + } else if (fnId == TUYA_MCU_FUNC_CURRENT) { + Energy.current = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 1000; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Current=%d"), Tuya.buffer[6], (Tuya.buffer[12] << 8 | Tuya.buffer[13])); + } else if (fnId == TUYA_MCU_FUNC_POWER) { + Energy.active_power = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 10; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Active_Power=%d"), Tuya.buffer[6], (Tuya.buffer[12] << 8 | Tuya.buffer[13])); + + if (Tuya.lastPowerCheckTime != 0 && Energy.active_power > 0) { + Energy.kWhtoday += (float)Energy.active_power * (Rtc.utc_time - Tuya.lastPowerCheckTime) / 36; + EnergyUpdateToday(); + } + Tuya.lastPowerCheckTime = Rtc.utc_time; + } + #endif // USE_ENERGY_SENSOR + + } + // } else { + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Unknown FnId=%s for dpId=%s"), fnId, Tuya.buffer[6]); + // } break; case TUYA_CMD_WIFI_RESET: @@ -266,9 +392,9 @@ void TuyaPacketProcess(void) break; case TUYA_CMD_MCU_CONF: - AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: RX MCU configuration")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX MCU configuration Mode=%d"), Tuya.buffer[5]); - if (Tuya.buffer[5] == 2) { + if (Tuya.buffer[5] == 2) { // Processing by ESP module mode uint8_t led1_gpio = Tuya.buffer[6]; uint8_t key1_gpio = Tuya.buffer[7]; bool key1_set = false; @@ -307,7 +433,17 @@ bool TuyaModuleSelected(void) Settings.my_gp.io[3] = GPIO_TUYA_RX; restart_flag = 2; } - if (Settings.flag3.tuya_disable_dimmer == 0) { + + if (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER) == 0 && TUYA_DIMMER_ID > 0) { + TuyaAddMcuFunc(TUYA_MCU_FUNC_DIMMER, TUYA_DIMMER_ID); + } + + if (TuyaGetDpId(TUYA_MCU_FUNC_REL1) == 0) { + TuyaAddMcuFunc(TUYA_MCU_FUNC_REL1, 1); + SettingsSaveAll(); + } + + if (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER) != 0) { light_type = LT_SERIAL1; } else { light_type = LT_BASIC; @@ -318,10 +454,12 @@ bool TuyaModuleSelected(void) void TuyaInit(void) { - devices_present += Settings.param[P_TUYA_RELAYS]; // SetOption41 - Add virtual relays if present - if (!Settings.param[P_TUYA_DIMMER_ID]) { - Settings.param[P_TUYA_DIMMER_ID] = TUYA_DIMMER_ID; + for(uint8_t i = TUYA_MCU_FUNC_REL2; i <= TUYA_MCU_FUNC_REL8; i++) { + if (TuyaGetDpId(i) != 0) { + devices_present++; + } } + Tuya.buffer = (char*)(malloc(TUYA_BUFFER_SIZE)); if (Tuya.buffer != nullptr) { TuyaSerial = new TasmotaSerial(pin[GPIO_TUYA_RX], pin[GPIO_TUYA_TX], 2); @@ -434,11 +572,11 @@ int Xnrg08(uint8_t function) if (TUYA_DIMMER == my_module_type) { if (FUNC_PRE_INIT == function) { if (!energy_flg) { - if (Settings.param[P_TUYA_POWER_ID] != 0) { - if (Settings.param[P_TUYA_CURRENT_ID] == 0) { + if (TuyaGetDpId(TUYA_MCU_FUNC_POWER) != 0) { + if (TuyaGetDpId(TUYA_MCU_FUNC_CURRENT) == 0) { Energy.current_available = false; } - if (Settings.param[P_TUYA_VOLTAGE_ID] == 0) { + if (TuyaGetDpId(TUYA_MCU_FUNC_VOLTAGE) == 0) { Energy.voltage_available = false; } energy_flg = XNRG_08; @@ -486,6 +624,9 @@ bool Xdrv16(uint8_t function) case FUNC_SET_CHANNELS: result = TuyaSetChannels(); break; + case FUNC_COMMAND: + result = DecodeCommand(kTuyaCommand, TuyaCommand); + break; } } return result; From 1d7a058155a68a4e53d4ea71f9d0accfa8cd9ccd Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 3 Sep 2019 11:57:13 +0100 Subject: [PATCH 2/6] Tuya MCU: Add support for Switches1 to 4 FunctionIDs 1 to 4 --- sonoff/xdrv_16_tuyadimmer.ino | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sonoff/xdrv_16_tuyadimmer.ino b/sonoff/xdrv_16_tuyadimmer.ino index 452a65346..66f649603 100644 --- a/sonoff/xdrv_16_tuyadimmer.ino +++ b/sonoff/xdrv_16_tuyadimmer.ino @@ -64,10 +64,10 @@ struct TUYA { enum TuyaSupportedFunctions { TUYA_MCU_FUNC_NONE, - // TUYA_MCU_FUNC_KEY1 = 1, // Buttons - // TUYA_MCU_FUNC_KEY2, - // TUYA_MCU_FUNC_KEY3, - // TUYA_MCU_FUNC_KEY4, + TUYA_MCU_FUNC_SWT1 = 1, // Buttons + TUYA_MCU_FUNC_SWT2, + TUYA_MCU_FUNC_SWT3, + TUYA_MCU_FUNC_SWT4, TUYA_MCU_FUNC_REL1 = 11, // Relays TUYA_MCU_FUNC_REL2, TUYA_MCU_FUNC_REL3, @@ -162,7 +162,8 @@ void TuyaAddMcuFunc(uint8_t fnId, uint8_t dpId) { } inline bool TuyaFuncIdValid(uint8_t fnId) { - return (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) || + return (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) || + (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) || fnId == TUYA_MCU_FUNC_DIMMER || (fnId >= TUYA_MCU_FUNC_POWER && fnId <= TUYA_MCU_FUNC_VOLTAGE); } @@ -330,10 +331,17 @@ void TuyaPacketProcess(void) if (Tuya.buffer[5] == 5) { // on/off packet if (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Device-%d --> MCU State: %s Current State:%s"),Tuya.buffer[6],Tuya.buffer[10]?"On":"Off",bitRead(power, fnId - TUYA_MCU_FUNC_REL1)?"On":"Off"); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[10]?"On":"Off",bitRead(power, fnId - TUYA_MCU_FUNC_REL1)?"On":"Off"); if ((power || Settings.light_dimmer > 0) && (Tuya.buffer[10] != bitRead(power, fnId - TUYA_MCU_FUNC_REL1))) { ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[10], SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction } + } else if (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Switch-%d --> MCU State: %d Current State:%d"),fnId - TUYA_MCU_FUNC_SWT1 + 1,Tuya.buffer[10], SwitchGetVirtual(fnId - TUYA_MCU_FUNC_SWT1 + 1)); + + if (SwitchGetVirtual(fnId - TUYA_MCU_FUNC_SWT1 + 1) != Tuya.buffer[10]) { + SwitchSetVirtual(fnId - TUYA_MCU_FUNC_SWT1 + 1, Tuya.buffer[10]); + SwitchHandler(1); + } } } From 982f0b9573a13d535bb0498e166e2c9ae5cf8619 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 3 Sep 2019 12:23:05 +0100 Subject: [PATCH 3/6] TuyaMCU: Rename Tuya Dimmer to Tuya MCU to make it more clear. --- sonoff/my_user_config.h | 2 +- sonoff/sonoff_post.h | 10 +++++----- sonoff/sonoff_template.h | 6 +++--- sonoff/support_command.ino | 2 +- sonoff/support_features.ino | 2 +- sonoff/{xdrv_16_tuyadimmer.ino => xdrv_16_tuyamcu.ino} | 6 +++--- 6 files changed, 14 insertions(+), 14 deletions(-) rename sonoff/{xdrv_16_tuyadimmer.ino => xdrv_16_tuyamcu.ino} (99%) diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index f55fc774f..a18adc7b7 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -307,7 +307,7 @@ // -- Optional modules ---------------------------- #define USE_BUZZER // Add support for a buzzer (+0k6 code) #define USE_SONOFF_IFAN // Add support for Sonoff iFan02 and iFan03 (+2k code) -#define USE_TUYA_DIMMER // Add support for Tuya Serial Dimmer +#define USE_TUYA_MCU // Add support for Tuya Serial MCU #define TUYA_DIMMER_ID 0 // Default dimmer Id #define USE_ARMTRONIX_DIMMERS // Add support for Armtronix Dimmers (+1k4 code) #define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer and Sonoff L1 (+2k code) diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index cc2b8b237..271325da1 100644 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -85,7 +85,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c // -- Optional modules ------------------------- #define USE_SONOFF_IFAN // Add support for Sonoff iFan02 and iFan03 (+2k code) -#define USE_TUYA_DIMMER // Add support for Tuya Serial Dimmer +#define USE_TUYA_MCU // Add support for Tuya Serial MCU #ifndef TUYA_DIMMER_ID #define TUYA_DIMMER_ID 0 // Default dimmer Id #endif @@ -217,7 +217,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c //#ifndef USE_SONOFF_IFAN #define USE_SONOFF_IFAN // Add support for Sonoff iFan02 and iFan03 (+2k code) //#endif -#undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer +#undef USE_TUYA_MCU // Disable support for Tuya Serial MCU #undef USE_ARMTRONIX_DIMMERS // Disable support for Armtronix Dimmers (+1k4 code) #undef USE_PS_16_DZ // Disable support for PS-16-DZ Dimmer and Sonoff L1 (+2k code) #undef ROTARY_V1 // Disable support for MI Desk Lamp @@ -345,7 +345,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c // -- Optional modules ------------------------- #undef USE_BUZZER // Disable support for a buzzer (+0k6 code) #undef USE_SONOFF_IFAN // Disable support for Sonoff iFan02 and iFan03 (+2k code) -#undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer +#undef USE_TUYA_MCU // Disable support for Tuya Serial MCU #undef USE_ARMTRONIX_DIMMERS // Disable support for Armtronix Dimmers (+1k4 code) #undef USE_PS_16_DZ // Disable support for PS-16-DZ Dimmer and Sonoff L1 (+2k code) #undef USE_DS18x20 // Disable Optional for more than one DS18x20 sensors with id sort, single scan and read retry (+1k3 code) @@ -436,7 +436,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c // -- Optional modules ------------------------- #define USE_SONOFF_IFAN // Add support for Sonoff iFan02 and iFan03 (+2k code) -//#undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer +//#undef USE_TUYA_MCU // Disable support for Tuya Serial MCU #undef USE_ARMTRONIX_DIMMERS // Disable support for Armtronix Dimmers (+1k4 code) #undef USE_PS_16_DZ // Disable support for PS-16-DZ Dimmer and Sonoff L1 (+2k code) #undef ROTARY_V1 // Disable support for MI Desk Lamp @@ -517,7 +517,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c // -- Optional modules ------------------------- #undef USE_SONOFF_IFAN // Disable support for Sonoff iFan02 and iFan03 (+2k code) -#undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer +#undef USE_TUYA_MCU // Disable support for Tuya Serial MCU #undef USE_ARMTRONIX_DIMMERS // Disable support for Armtronix Dimmers (+1k4 code) #undef USE_PS_16_DZ // Disable support for PS-16-DZ Dimmer and Sonoff L1 (+2k code) #undef ROTARY_V1 // Disable support for MI Desk Lamp diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 85f1a8c8d..cdfe75e23 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -541,7 +541,7 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_SM16716_DAT, // SM16716 DATA GPIO_SM16716_SEL, // SM16716 SELECT #endif // USE_SM16716 -#ifdef USE_TUYA_DIMMER +#ifdef USE_TUYA_MCU GPIO_TUYA_TX, // Tuya Serial interface GPIO_TUYA_RX, // Tuya Serial interface #endif @@ -749,7 +749,7 @@ const uint8_t kModuleNiceList[] PROGMEM = { OBI2, MANZOKU_EU_4, ESP_SWITCH, // Switch Devices -#ifdef USE_TUYA_DIMMER +#ifdef USE_TUYA_MCU TUYA_DIMMER, // Dimmer Devices #endif #ifdef USE_ARMTRONIX_DIMMERS @@ -1728,7 +1728,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_REL1, // GPIO14 Relay SRU 5VDC SDA (0 = Off, 1 = On ) 0, 0, 0 }, - { "Tuya Dimmer", // Tuya Dimmer (ESP8266 w/ separate MCU dimmer) + { "Tuya MCU", // Tuya MCU device (ESP8266 w/ separate MCU) // https://www.amazon.com/gp/product/B07CTNSZZ8/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1 GPIO_USER, // Virtual Button (controlled by MCU) GPIO_USER, // GPIO01 MCU serial control diff --git a/sonoff/support_command.ino b/sonoff/support_command.ino index 1b91dc11b..a11c6b8c1 100644 --- a/sonoff/support_command.ino +++ b/sonoff/support_command.ino @@ -661,7 +661,7 @@ void CmndSetoption(void) IrReceiveUpdateThreshold(); break; #endif -#ifdef USE_TUYA_DIMMER +#ifdef USE_TUYA_MCU case P_TUYA_RELAYS: case P_TUYA_POWER_ID: case P_TUYA_CURRENT_ID: diff --git a/sonoff/support_features.ino b/sonoff/support_features.ino index 42144d191..8265e4cb9 100644 --- a/sonoff/support_features.ino +++ b/sonoff/support_features.ino @@ -171,7 +171,7 @@ void GetFeatures(void) #ifdef USE_PCA9685 feature_drv2 |= 0x00004000; // xdrv_15_pca9685.ino #endif -#if defined(USE_LIGHT) && defined(USE_TUYA_DIMMER) +#if defined(USE_LIGHT) && defined(USE_TUYA_MCU) feature_drv2 |= 0x00008000; // xdrv_16_tuyadimmer.ino #endif #ifdef USE_RC_SWITCH diff --git a/sonoff/xdrv_16_tuyadimmer.ino b/sonoff/xdrv_16_tuyamcu.ino similarity index 99% rename from sonoff/xdrv_16_tuyadimmer.ino rename to sonoff/xdrv_16_tuyamcu.ino index 66f649603..edf60fbe3 100644 --- a/sonoff/xdrv_16_tuyadimmer.ino +++ b/sonoff/xdrv_16_tuyamcu.ino @@ -1,5 +1,5 @@ /* - xdrv_16_tuyadimmer.ino - Tuya dimmer support for Sonoff-Tasmota + xdrv_16_tuyamcu.ino - Tuya MCU support for Sonoff-Tasmota Copyright (C) 2019 digiblur, Joel Stein and Theo Arends @@ -18,7 +18,7 @@ */ #ifdef USE_LIGHT -#ifdef USE_TUYA_DIMMER +#ifdef USE_TUYA_MCU #define XDRV_16 16 #define XNRG_08 8 @@ -640,5 +640,5 @@ bool Xdrv16(uint8_t function) return result; } -#endif // USE_TUYA_DIMMER +#endif // USE_TUYA_MCU #endif // USE_LIGHT From c4c8fab42f2359ba61089c770dbe207f65f01825 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 3 Sep 2019 14:00:51 +0100 Subject: [PATCH 4/6] Tuya MCU: Fix Switch ids are 1 incremented in MQTT --- sonoff/xdrv_16_tuyamcu.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sonoff/xdrv_16_tuyamcu.ino b/sonoff/xdrv_16_tuyamcu.ino index edf60fbe3..745990962 100644 --- a/sonoff/xdrv_16_tuyamcu.ino +++ b/sonoff/xdrv_16_tuyamcu.ino @@ -336,10 +336,10 @@ void TuyaPacketProcess(void) ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[10], SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction } } else if (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Switch-%d --> MCU State: %d Current State:%d"),fnId - TUYA_MCU_FUNC_SWT1 + 1,Tuya.buffer[10], SwitchGetVirtual(fnId - TUYA_MCU_FUNC_SWT1 + 1)); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Switch-%d --> MCU State: %d Current State:%d"),fnId - TUYA_MCU_FUNC_SWT1 + 1,Tuya.buffer[10], SwitchGetVirtual(fnId - TUYA_MCU_FUNC_SWT1)); - if (SwitchGetVirtual(fnId - TUYA_MCU_FUNC_SWT1 + 1) != Tuya.buffer[10]) { - SwitchSetVirtual(fnId - TUYA_MCU_FUNC_SWT1 + 1, Tuya.buffer[10]); + if (SwitchGetVirtual(fnId - TUYA_MCU_FUNC_SWT1) != Tuya.buffer[10]) { + SwitchSetVirtual(fnId - TUYA_MCU_FUNC_SWT1, Tuya.buffer[10]); SwitchHandler(1); } } From dad5b0ffc22ef9b2715ff433a0e44ad2b0d68b9a Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 3 Sep 2019 14:04:07 +0100 Subject: [PATCH 5/6] Tuya MCU: Implement support for Inverted Relays --- sonoff/xdrv_16_tuyamcu.ino | 58 +++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/sonoff/xdrv_16_tuyamcu.ino b/sonoff/xdrv_16_tuyamcu.ino index 745990962..61cc584bd 100644 --- a/sonoff/xdrv_16_tuyamcu.ino +++ b/sonoff/xdrv_16_tuyamcu.ino @@ -80,6 +80,14 @@ enum TuyaSupportedFunctions { TUYA_MCU_FUNC_POWER = 31, TUYA_MCU_FUNC_CURRENT, TUYA_MCU_FUNC_VOLTAGE, + TUYA_MCU_FUNC_REL1_INV = 41, // Inverted Relays + TUYA_MCU_FUNC_REL2_INV, + TUYA_MCU_FUNC_REL3_INV, + TUYA_MCU_FUNC_REL4_INV, + TUYA_MCU_FUNC_REL5_INV, + TUYA_MCU_FUNC_REL6_INV, + TUYA_MCU_FUNC_REL7_INV, + TUYA_MCU_FUNC_REL8_INV, TUYA_MCU_FUNC_LAST = 255 }; @@ -93,7 +101,7 @@ void (* const TuyaCommand[])(void) PROGMEM = { /* -TuyaMap fnid,dpid +TuyaMcu fnid,dpid */ @@ -159,13 +167,30 @@ void TuyaAddMcuFunc(uint8_t fnId, uint8_t dpId) { } } } + UpdateDevices(); +} + +void UpdateDevices() { + for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) { + uint8_t fnId = Settings.tuya_fnid_map[i].fnid; + if (fnId > TUYA_MCU_FUNC_NONE && Settings.tuya_fnid_map[i].dpid > 0) { + + if (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) { //Relay + bitClear(rel_inverted, fnId - TUYA_MCU_FUNC_REL1); + } else if (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) { // Inverted Relay + bitSet(rel_inverted, fnId - TUYA_MCU_FUNC_REL1_INV); + } + + } + } } inline bool TuyaFuncIdValid(uint8_t fnId) { return (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) || (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) || fnId == TUYA_MCU_FUNC_DIMMER || - (fnId >= TUYA_MCU_FUNC_POWER && fnId <= TUYA_MCU_FUNC_VOLTAGE); + (fnId >= TUYA_MCU_FUNC_POWER && fnId <= TUYA_MCU_FUNC_VOLTAGE) || + (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV); } uint8_t TuyaGetFuncId(uint8_t dpid) { @@ -252,7 +277,7 @@ bool TuyaSetPower(void) int16_t source = XdrvMailbox.payload; if (source != SRC_SWITCH && TuyaSerial) { // ignore to prevent loop from pushing state from faceplate interaction - TuyaSendBool(active_device, bitRead(rpower, active_device-1)); + TuyaSendBool(active_device, bitRead(rpower, active_device-1) ^ bitRead(rel_inverted, active_device-1)); status = true; } return status; @@ -335,6 +360,11 @@ void TuyaPacketProcess(void) if ((power || Settings.light_dimmer > 0) && (Tuya.buffer[10] != bitRead(power, fnId - TUYA_MCU_FUNC_REL1))) { ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[10], SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction } + } else if (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d-Inverted --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1_INV + 1, Tuya.buffer[10]?"Off":"On",bitRead(power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1?"Off":"On"); + if (Tuya.buffer[10] != bitRead(power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1) { + ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1_INV + 1, Tuya.buffer[10] ^ 1, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction + } } else if (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Switch-%d --> MCU State: %d Current State:%d"),fnId - TUYA_MCU_FUNC_SWT1 + 1,Tuya.buffer[10], SwitchGetVirtual(fnId - TUYA_MCU_FUNC_SWT1)); @@ -446,8 +476,21 @@ bool TuyaModuleSelected(void) TuyaAddMcuFunc(TUYA_MCU_FUNC_DIMMER, TUYA_DIMMER_ID); } - if (TuyaGetDpId(TUYA_MCU_FUNC_REL1) == 0) { + bool relaySet = false; + + devices_present--; + + for (uint8_t i = 0 ; i < MAX_TUYA_FUNCTIONS; i++) { + if ((Settings.tuya_fnid_map[i].fnid >= TUYA_MCU_FUNC_REL1 && Settings.tuya_fnid_map[i].fnid <= TUYA_MCU_FUNC_REL8 ) || + (Settings.tuya_fnid_map[i].fnid >= TUYA_MCU_FUNC_REL1_INV && Settings.tuya_fnid_map[i].fnid <= TUYA_MCU_FUNC_REL8_INV )) { + relaySet = true; + devices_present++; + } + } + + if (!relaySet) { TuyaAddMcuFunc(TUYA_MCU_FUNC_REL1, 1); + devices_present++; SettingsSaveAll(); } @@ -457,17 +500,12 @@ bool TuyaModuleSelected(void) light_type = LT_BASIC; } + UpdateDevices(); return true; } void TuyaInit(void) { - for(uint8_t i = TUYA_MCU_FUNC_REL2; i <= TUYA_MCU_FUNC_REL8; i++) { - if (TuyaGetDpId(i) != 0) { - devices_present++; - } - } - Tuya.buffer = (char*)(malloc(TUYA_BUFFER_SIZE)); if (Tuya.buffer != nullptr) { TuyaSerial = new TasmotaSerial(pin[GPIO_TUYA_RX], pin[GPIO_TUYA_TX], 2); From 0145c86fe0b5f43219c6b6642907818fca12c777 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 5 Sep 2019 10:02:42 +0200 Subject: [PATCH 6/6] Update settings.h --- sonoff/settings.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sonoff/settings.h b/sonoff/settings.h index bc8564cca..40be8b25f 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -372,11 +372,9 @@ struct SYSCFG { uint16_t web_refresh; // 7CC char mems[MAX_RULE_MEMS][10]; // 7CE char rules[MAX_RULE_SETS][MAX_RULE_SIZE]; // 800 uses 512 bytes in v5.12.0m, 3 x 512 bytes in v5.14.0b - uint8_t data8[32]; // E00 - uint16_t data16[16]; // E20 - TuyaFnidDpidMap tuya_fnid_map[MAX_TUYA_FUNCTIONS]; // E40 32 bytes + TuyaFnidDpidMap tuya_fnid_map[MAX_TUYA_FUNCTIONS]; // E00 32 bytes - uint8_t free_e20[416]; // E60 + uint8_t free_e20[480]; // E20 // FFF last location } Settings;