From 7d9bc1039fb034fe36379bf00e64656b76afc35a Mon Sep 17 00:00:00 2001 From: Joel Stein Date: Fri, 2 Nov 2018 16:04:35 +0100 Subject: [PATCH 1/6] tuya: don't set tuya_wifi_state in TuyaResetWifi() (will be set automatically) --- sonoff/xdrv_16_tuyadimmer.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/sonoff/xdrv_16_tuyadimmer.ino b/sonoff/xdrv_16_tuyadimmer.ino index 813879b97..c9de62edd 100644 --- a/sonoff/xdrv_16_tuyadimmer.ino +++ b/sonoff/xdrv_16_tuyadimmer.ino @@ -335,7 +335,6 @@ void TuyaResetWifi() { if (!Settings.flag.button_restrict) { char scmnd[20]; - tuya_wifi_state = -1; snprintf_P(scmnd, sizeof(scmnd), D_CMND_WIFICONFIG " %d", 2); ExecuteCommand(scmnd, SRC_BUTTON); } From 91ead8c60ed2401c2b4befef00242c1d54b49132 Mon Sep 17 00:00:00 2001 From: Joel Stein Date: Sat, 3 Nov 2018 22:34:29 +0100 Subject: [PATCH 2/6] tuya: refactor/simplify code --- sonoff/xdrv_16_tuyadimmer.ino | 291 ++++++++++++++++++---------------- 1 file changed, 155 insertions(+), 136 deletions(-) diff --git a/sonoff/xdrv_16_tuyadimmer.ino b/sonoff/xdrv_16_tuyadimmer.ino index c9de62edd..b721ac7f6 100644 --- a/sonoff/xdrv_16_tuyadimmer.ino +++ b/sonoff/xdrv_16_tuyadimmer.ino @@ -20,9 +20,25 @@ #ifdef USE_TUYA_DIMMER #ifndef TUYA_DIMMER_ID -#define TUYA_DIMMER_ID 0 +#define TUYA_DIMMER_ID 0 #endif -#define TUYA_BUFFER_SIZE 256 + +#define TUYA_POWER_ID 1 + +#define TUYA_CMD_HEARTBEAT 0x00 +#define TUYA_CMD_QUERY_PRODUCT 0x01 +#define TUYA_CMD_MCU_CONF 0x02 +#define TUYA_CMD_WIFI_STATE 0x03 +#define TUYA_CMD_WIFI_RESET 0x04 +#define TUYA_CMD_WIFI_SELECT 0x05 +#define TUYA_CMD_SET_DP 0x06 +#define TUYA_CMD_STATE 0x07 +#define TUYA_CMD_QUERY_STATE 0x08 + +#define TUYA_TYPE_BOOL 0x01 +#define TUYA_TYPE_VALUE 0x02 + +#define TUYA_BUFFER_SIZE 256 #include @@ -38,6 +54,61 @@ int8_t tuya_wifi_state = -2; // Keep MCU wifi-status in sync with char tuya_buffer[TUYA_BUFFER_SIZE]; // Serial receive buffer int tuya_byte_counter = 0; // Index in serial receive buffer +void TuyaSendCmd(uint8_t cmd, uint8_t payload[], uint16_t payload_len){ + uint8_t checksum = 0xFF + cmd + (payload_len & 0xFF) + (payload_len >> 8); + TuyaSerial->write((uint8_t)0x55); // Tuya header 55AA + TuyaSerial->write((uint8_t)0xAA); + TuyaSerial->write((uint8_t)0x00); // version 00 + TuyaSerial->write(cmd); // Tuya command + TuyaSerial->write(payload_len >> 8); // following data length (Hi) + TuyaSerial->write(payload_len & 0xFF); // following data length (Lo) + snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Send Packet: \"%02x%02x%02x%02x%02x%02x"), 0x55, 0xAA, 0x00, cmd, payload_len >> 8, payload_len & 0xFF); + for(int i = 0; i < payload_len; ++i){ + TuyaSerial->write(payload[i]); + checksum += payload[i]; + snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x"), log_data, payload[i]); + } + TuyaSerial->write(checksum); + TuyaSerial->flush(); + + snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x\""), log_data, checksum); + AddLog(LOG_LEVEL_DEBUG); +} + +void TuyaSendState(uint8_t type, uint8_t id, uint8_t* value){ + uint16_t payload_len = 4; + uint8_t payload_buffer[8]; + payload_buffer[0] = id; + payload_buffer[1] = type; + switch(type){ + case TUYA_TYPE_BOOL: + payload_len += 1; + payload_buffer[2] = 0x00; + payload_buffer[3] = 0x01; + payload_buffer[4] = value[0]; + break; + case TUYA_TYPE_VALUE: + payload_len += 4; + payload_buffer[2] = 0x00; + payload_buffer[3] = 0x04; + payload_buffer[4] = value[3]; + payload_buffer[5] = value[2]; + payload_buffer[6] = value[1]; + payload_buffer[7] = value[0]; + break; + } + + TuyaSendCmd(TUYA_CMD_SET_DP, payload_buffer, payload_len); +} + +void TuyaSendBool(uint8_t id, boolean value){ + TuyaSendState(TUYA_TYPE_BOOL, TUYA_POWER_ID, &value); +} + +void TuyaSendValue(uint8_t id, uint32_t value){ + TuyaSendState(TUYA_TYPE_VALUE, Settings.param[P_TUYA_DIMMER_ID], (uint8_t*)(&value)); +} + boolean TuyaSetPower() { boolean status = false; @@ -50,19 +121,7 @@ boolean TuyaSetPower() snprintf_P(log_data, sizeof(log_data), PSTR("TYA: SetDevicePower.rpower=%d"), rpower); AddLog(LOG_LEVEL_DEBUG); - TuyaSerial->write((uint8_t)0x55); // Tuya header 55AA - TuyaSerial->write((uint8_t)0xAA); - TuyaSerial->write((uint8_t)0x00); // version 00 - TuyaSerial->write((uint8_t)0x06); // Tuya command 06 - TuyaSerial->write((uint8_t)0x00); - TuyaSerial->write((uint8_t)0x05); // following data length 0x05 - TuyaSerial->write((uint8_t)0x01); // relay number 1,2,3 - TuyaSerial->write((uint8_t)0x01); - TuyaSerial->write((uint8_t)0x00); - TuyaSerial->write((uint8_t)0x01); - TuyaSerial->write((uint8_t)rpower); // status - TuyaSerial->write((uint8_t)0x0D + rpower); // checksum sum of all bytes in packet mod 256 - TuyaSerial->flush(); + TuyaSendBool(TUYA_POWER_ID, rpower); status = true; } @@ -75,22 +134,8 @@ void LightSerialDuty(uint8_t duty) if (duty < 25) { duty = 25; // dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself } - TuyaSerial->write((uint8_t)0x55); // Tuya header 55AA - TuyaSerial->write((uint8_t)0xAA); - TuyaSerial->write((uint8_t)0x00); // version 00 - TuyaSerial->write((uint8_t)0x06); // Tuya command 06 - send order - TuyaSerial->write((uint8_t)0x00); - TuyaSerial->write((uint8_t)0x08); // following data length 0x08 - TuyaSerial->write((uint8_t)Settings.param[P_TUYA_DIMMER_ID]); // dimmer id - TuyaSerial->write((uint8_t)0x02); // type=value - TuyaSerial->write((uint8_t)0x00); // length hi - TuyaSerial->write((uint8_t)0x04); // length low - TuyaSerial->write((uint8_t)0x00); // - TuyaSerial->write((uint8_t)0x00); // - TuyaSerial->write((uint8_t)0x00); // - TuyaSerial->write((uint8_t) duty ); // dim value (0-255) - TuyaSerial->write((uint8_t) byte(Settings.param[P_TUYA_DIMMER_ID] + 19 + duty) ); // checksum:sum of all bytes in packet mod 256 - TuyaSerial->flush(); + + TuyaSendValue(Settings.param[P_TUYA_DIMMER_ID], duty); snprintf_P(log_data, sizeof(log_data), PSTR( "TYA: Send Serial Packet Dim Value=%d (id=%d)"), duty, Settings.param[P_TUYA_DIMMER_ID]); AddLog(LOG_LEVEL_DEBUG); @@ -108,84 +153,85 @@ void TuyaPacketProcess() { char scmnd[20]; - snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Packet Size=%d"), tuya_byte_counter); - AddLog(LOG_LEVEL_DEBUG); + switch(tuya_buffer[3]) { - if (tuya_byte_counter == 7 && tuya_buffer[3] == 14 ) { // heartbeat packet - AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Heartbeat")); - if(tuya_buffer[6] == 0){ - AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Detected MCU restart")); - tuya_wifi_state = -2; - } - } - else if (tuya_byte_counter == 12 && tuya_buffer[3] == 7 && tuya_buffer[5] == 5) { // on/off packet - - snprintf_P(log_data, sizeof(log_data),PSTR("TYA: Rcvd - %s State"),tuya_buffer[10]?"On":"Off"); - AddLog(LOG_LEVEL_DEBUG); - - 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 - } - } - else if (tuya_byte_counter == 15 && tuya_buffer[3] == 7 && tuya_buffer[5] == 8) { // dim packet - - snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Rcvd Dim State=%d"), tuya_buffer[13]); - AddLog(LOG_LEVEL_DEBUG); - - if (!Settings.param[P_TUYA_DIMMER_ID]) { - snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Autoconfiguring Dimmer ID %d"), tuya_buffer[6]); - AddLog(LOG_LEVEL_DEBUG); - Settings.param[P_TUYA_DIMMER_ID] = tuya_buffer[6]; - } - - tuya_new_dim = round(tuya_buffer[13] * (100. / 255.)); - if((power) && (tuya_new_dim > 0) && (abs(tuya_new_dim - Settings.light_dimmer) > 2)) { - - snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Send CMND_DIMMER=%d"), tuya_new_dim ); - AddLog(LOG_LEVEL_DEBUG); - - snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), tuya_new_dim ); - - snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Send CMND_DIMMER_STR=%s"), scmnd ); - AddLog(LOG_LEVEL_DEBUG); - - tuya_ignore_dim = true; - ExecuteCommand(scmnd, SRC_SWITCH); - } - } - else if (tuya_byte_counter == 8 && tuya_buffer[3] == 5 && tuya_buffer[5] == 1) { // reset WiFi settings packet - - AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: WiFi Reset Rcvd")); - TuyaResetWifi(); - } - else if (tuya_byte_counter == 7 && tuya_buffer[3] == 3 && tuya_buffer[6] == 2) { // WiFi LED has been sucessfully set. - - AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: WiFi LED set ACK Rcvd")); - tuya_wifi_state = WifiState(); - } - else if (tuya_buffer[3] == 2) { // MCU configuration packet - - AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: MCU configuration Rcvd")); - - if (tuya_buffer[5] == 2) { - uint8_t led1_gpio = tuya_buffer[6]; - uint8_t key1_gpio = tuya_buffer[7]; - boolean key1_set = false; - boolean led1_set = false; - for (byte i = 0; i < MAX_GPIO_PIN; i++) { - if (Settings.my_gp.io[i] == GPIO_LED1) led1_set = true; - else if (Settings.my_gp.io[i] == GPIO_KEY1) key1_set = true; + case TUYA_CMD_HEARTBEAT: + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Heartbeat")); + if(tuya_buffer[6] == 0){ + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Detected MCU restart")); + tuya_wifi_state = -2; } - if(!Settings.my_gp.io[led1_gpio] && !led1_set){ - Settings.my_gp.io[led1_gpio] = GPIO_LED1; - restart_flag = 2; + break; + + case TUYA_CMD_STATE: + if (tuya_buffer[5] == 5) { // on/off packet + + snprintf_P(log_data, sizeof(log_data),PSTR("TYA: Rcvd - %s State"),tuya_buffer[10]?"On":"Off"); + AddLog(LOG_LEVEL_DEBUG); + + 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 + } } - if(!Settings.my_gp.io[key1_gpio] && !key1_set){ - Settings.my_gp.io[key1_gpio] = GPIO_KEY1; - restart_flag = 2; + else if (tuya_buffer[5] == 8) { // dim packet + + snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Rcvd Dim State=%d"), tuya_buffer[13]); + AddLog(LOG_LEVEL_DEBUG); + + if (!Settings.param[P_TUYA_DIMMER_ID]) { + snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Autoconfiguring Dimmer ID %d"), tuya_buffer[6]); + AddLog(LOG_LEVEL_DEBUG); + Settings.param[P_TUYA_DIMMER_ID] = tuya_buffer[6]; + } + + tuya_new_dim = round(tuya_buffer[13] * (100. / 255.)); + if((power) && (tuya_new_dim > 0) && (abs(tuya_new_dim - Settings.light_dimmer) > 2)) { + + snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), tuya_new_dim ); + + snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Send CMND_DIMMER_STR=%s"), scmnd ); + AddLog(LOG_LEVEL_DEBUG); + + tuya_ignore_dim = true; + ExecuteCommand(scmnd, SRC_SWITCH); + } } - } - TuyaRequestState(); + break; + + case TUYA_CMD_WIFI_RESET: + case TUYA_CMD_WIFI_SELECT: + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Rcvd WiFi Reset")); + TuyaResetWifi(); + break; + + case TUYA_CMD_WIFI_STATE: + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Rcvd WiFi LED set ACK")); + tuya_wifi_state = WifiState(); + break; + + case TUYA_CMD_MCU_CONF: + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Rcvd MCU configuration")); + + if (tuya_buffer[5] == 2) { + uint8_t led1_gpio = tuya_buffer[6]; + uint8_t key1_gpio = tuya_buffer[7]; + boolean key1_set = false; + boolean led1_set = false; + for (byte i = 0; i < MAX_GPIO_PIN; i++) { + if (Settings.my_gp.io[i] == GPIO_LED1) led1_set = true; + else if (Settings.my_gp.io[i] == GPIO_KEY1) key1_set = true; + } + if(!Settings.my_gp.io[led1_gpio] && !led1_set){ + Settings.my_gp.io[led1_gpio] = GPIO_LED1; + restart_flag = 2; + } + if(!Settings.my_gp.io[key1_gpio] && !key1_set){ + Settings.my_gp.io[key1_gpio] = GPIO_KEY1; + restart_flag = 2; + } + } + TuyaRequestState(); + break; } } @@ -195,9 +241,6 @@ void TuyaSerialInput() yield(); byte serial_in_byte = TuyaSerial->read(); - //snprintf_P(log_data, sizeof(log_data), PSTR("TYA: serial_in_byte %d, tuya_cmd_status %d, tuya_cmd_checksum %d, tuya_data_len %d, tuya_byte_counter %d"), serial_in_byte, tuya_cmd_status, tuya_cmd_checksum, tuya_data_len, tuya_byte_counter); - //AddLog(LOG_LEVEL_DEBUG); - if (serial_in_byte == 0x55) { // Start TUYA Packet tuya_cmd_status = 1; tuya_buffer[tuya_byte_counter++] = serial_in_byte; @@ -206,8 +249,6 @@ void TuyaSerialInput() else if (tuya_cmd_status == 1 && serial_in_byte == 0xAA){ // Only packtes with header 0x55AA are valid tuya_cmd_status = 2; - AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: 0x55AA Packet Start")); - tuya_byte_counter = 0; tuya_buffer[tuya_byte_counter++] = 0x55; tuya_buffer[tuya_byte_counter++] = 0xAA; @@ -224,7 +265,7 @@ void TuyaSerialInput() else if ((tuya_cmd_status == 3) && (tuya_byte_counter == (6 + tuya_data_len)) && (tuya_cmd_checksum == serial_in_byte)){ // Compare checksum and process packet tuya_buffer[tuya_byte_counter++] = serial_in_byte; - snprintf_P(log_data, sizeof(log_data), PSTR("TYA: 0x55 Packet End: \"")); + snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Received Packet: \"")); for (int i = 0; i < tuya_byte_counter; i++) { snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x"), log_data, tuya_buffer[i]); } @@ -280,15 +321,7 @@ void TuyaSetWifiLed(){ snprintf_P(log_data, sizeof(log_data), "TYA: Set WiFi LED to state %d (%d)", wifi_state, WifiState()); AddLog(LOG_LEVEL_DEBUG); - TuyaSerial->write((uint8_t)0x55); // header 55AA - TuyaSerial->write((uint8_t)0xAA); - TuyaSerial->write((uint8_t)0x00); // version 00 - TuyaSerial->write((uint8_t)0x03); // command 03 - set wifi state - TuyaSerial->write((uint8_t)0x00); - TuyaSerial->write((uint8_t)0x01); // following data length 0x01 - TuyaSerial->write((uint8_t)wifi_state); // wifi state (0x00 == smartconfig, 0x01 == AP, 0x02 == not connected, 0x03 == connected) - TuyaSerial->write((uint8_t)(0x03 + wifi_state)); // checksum:sum of all bytes in packet mod 256 - TuyaSerial->flush(); + TuyaSendCmd(TUYA_CMD_WIFI_STATE, &wifi_state, 1); } void TuyaRequestState(){ @@ -297,14 +330,7 @@ void TuyaRequestState(){ snprintf_P(log_data, sizeof(log_data), "TYA: Request MCU state"); AddLog(LOG_LEVEL_DEBUG); - TuyaSerial->write((uint8_t)0x55); // header 55AA - TuyaSerial->write((uint8_t)0xAA); - TuyaSerial->write((uint8_t)0x00); // version 00 - TuyaSerial->write((uint8_t)0x08); // command 08 - get status - TuyaSerial->write((uint8_t)0x00); - TuyaSerial->write((uint8_t)0x00); // following data length 0x00 - TuyaSerial->write((uint8_t)0x07); // checksum:sum of all bytes in packet mod 256 - TuyaSerial->flush(); + TuyaSendCmd(TUYA_CMD_QUERY_STATE, nullptr, 0); } } @@ -320,14 +346,7 @@ void TuyaInit() snprintf_P(log_data, sizeof(log_data), "TYA: Request MCU configuration"); AddLog(LOG_LEVEL_DEBUG); - TuyaSerial->write((uint8_t)0x55); // header 55AA - TuyaSerial->write((uint8_t)0xAA); - TuyaSerial->write((uint8_t)0x00); // version 00 - TuyaSerial->write((uint8_t)0x02); // command 02 - get configuration - TuyaSerial->write((uint8_t)0x00); - TuyaSerial->write((uint8_t)0x00); // following data length 0x00 - TuyaSerial->write((uint8_t)0x01); // checksum:sum of all bytes in packet mod 256 - TuyaSerial->flush(); + TuyaSendCmd(TUYA_CMD_MCU_CONF, nullptr, 0); } } From 2a9a5bb94b56c875894fc3107ebfb9cb6198ea79 Mon Sep 17 00:00:00 2001 From: Joel Stein Date: Sat, 3 Nov 2018 23:24:43 +0100 Subject: [PATCH 3/6] tuya: send power when setting dim-level --- sonoff/xdrv_16_tuyadimmer.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sonoff/xdrv_16_tuyadimmer.ino b/sonoff/xdrv_16_tuyadimmer.ino index b721ac7f6..8ef35f19b 100644 --- a/sonoff/xdrv_16_tuyadimmer.ino +++ b/sonoff/xdrv_16_tuyadimmer.ino @@ -102,11 +102,11 @@ void TuyaSendState(uint8_t type, uint8_t id, uint8_t* value){ } void TuyaSendBool(uint8_t id, boolean value){ - TuyaSendState(TUYA_TYPE_BOOL, TUYA_POWER_ID, &value); + TuyaSendState(TUYA_TYPE_BOOL, id, &value); } void TuyaSendValue(uint8_t id, uint32_t value){ - TuyaSendState(TUYA_TYPE_VALUE, Settings.param[P_TUYA_DIMMER_ID], (uint8_t*)(&value)); + TuyaSendState(TUYA_TYPE_VALUE, id, (uint8_t*)(&value)); } boolean TuyaSetPower() @@ -136,6 +136,7 @@ void LightSerialDuty(uint8_t duty) } TuyaSendValue(Settings.param[P_TUYA_DIMMER_ID], duty); + TuyaSendBool(TUYA_POWER_ID, power); snprintf_P(log_data, sizeof(log_data), PSTR( "TYA: Send Serial Packet Dim Value=%d (id=%d)"), duty, Settings.param[P_TUYA_DIMMER_ID]); AddLog(LOG_LEVEL_DEBUG); From b958c7b716da0adf5f80d37dd2b5908eb689ce65 Mon Sep 17 00:00:00 2001 From: Joel Stein Date: Sun, 4 Nov 2018 03:40:14 +0100 Subject: [PATCH 4/6] tuya: cleanup --- sonoff/xdrv_16_tuyadimmer.ino | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/sonoff/xdrv_16_tuyadimmer.ino b/sonoff/xdrv_16_tuyadimmer.ino index 8ef35f19b..c296548cc 100644 --- a/sonoff/xdrv_16_tuyadimmer.ino +++ b/sonoff/xdrv_16_tuyadimmer.ino @@ -54,23 +54,22 @@ int8_t tuya_wifi_state = -2; // Keep MCU wifi-status in sync with char tuya_buffer[TUYA_BUFFER_SIZE]; // Serial receive buffer int tuya_byte_counter = 0; // Index in serial receive buffer -void TuyaSendCmd(uint8_t cmd, uint8_t payload[], uint16_t payload_len){ - uint8_t checksum = 0xFF + cmd + (payload_len & 0xFF) + (payload_len >> 8); +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)); TuyaSerial->write((uint8_t)0x55); // Tuya header 55AA TuyaSerial->write((uint8_t)0xAA); TuyaSerial->write((uint8_t)0x00); // version 00 TuyaSerial->write(cmd); // Tuya command TuyaSerial->write(payload_len >> 8); // following data length (Hi) TuyaSerial->write(payload_len & 0xFF); // following data length (Lo) - snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Send Packet: \"%02x%02x%02x%02x%02x%02x"), 0x55, 0xAA, 0x00, cmd, payload_len >> 8, payload_len & 0xFF); - for(int i = 0; i < payload_len; ++i){ + snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Sent Packet: \"55aa00%02x%02x%02x"), cmd, payload_len >> 8, payload_len & 0xFF); + for(int i = 0; i < payload_len; ++i) { TuyaSerial->write(payload[i]); checksum += payload[i]; snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x"), log_data, payload[i]); } TuyaSerial->write(checksum); TuyaSerial->flush(); - snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x\""), log_data, checksum); AddLog(LOG_LEVEL_DEBUG); } @@ -136,7 +135,6 @@ void LightSerialDuty(uint8_t duty) } TuyaSendValue(Settings.param[P_TUYA_DIMMER_ID], duty); - TuyaSendBool(TUYA_POWER_ID, power); snprintf_P(log_data, sizeof(log_data), PSTR( "TYA: Send Serial Packet Dim Value=%d (id=%d)"), duty, Settings.param[P_TUYA_DIMMER_ID]); AddLog(LOG_LEVEL_DEBUG); @@ -233,6 +231,9 @@ void TuyaPacketProcess() } TuyaRequestState(); break; + + default: + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Rcvd unknown command")); } } @@ -331,7 +332,7 @@ void TuyaRequestState(){ snprintf_P(log_data, sizeof(log_data), "TYA: Request MCU state"); AddLog(LOG_LEVEL_DEBUG); - TuyaSendCmd(TUYA_CMD_QUERY_STATE, nullptr, 0); + TuyaSendCmd(TUYA_CMD_QUERY_STATE); } } @@ -347,7 +348,7 @@ void TuyaInit() snprintf_P(log_data, sizeof(log_data), "TYA: Request MCU configuration"); AddLog(LOG_LEVEL_DEBUG); - TuyaSendCmd(TUYA_CMD_MCU_CONF, nullptr, 0); + TuyaSendCmd(TUYA_CMD_MCU_CONF); } } From 256b5cba8e8d0367f399ab5e439977ddfa4d846f Mon Sep 17 00:00:00 2001 From: Joel Stein Date: Sun, 4 Nov 2018 06:40:55 +0100 Subject: [PATCH 5/6] tuya: only handle reset GPIO --- sonoff/xdrv_16_tuyadimmer.ino | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/sonoff/xdrv_16_tuyadimmer.ino b/sonoff/xdrv_16_tuyadimmer.ino index c296548cc..f3b087c7d 100644 --- a/sonoff/xdrv_16_tuyadimmer.ino +++ b/sonoff/xdrv_16_tuyadimmer.ino @@ -56,12 +56,12 @@ int tuya_byte_counter = 0; // Index in serial receive buffer 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)); - TuyaSerial->write((uint8_t)0x55); // Tuya header 55AA - TuyaSerial->write((uint8_t)0xAA); - TuyaSerial->write((uint8_t)0x00); // version 00 - TuyaSerial->write(cmd); // Tuya command - TuyaSerial->write(payload_len >> 8); // following data length (Hi) - TuyaSerial->write(payload_len & 0xFF); // following data length (Lo) + TuyaSerial->write(0x55); // Tuya header 55AA + TuyaSerial->write(0xAA); + TuyaSerial->write(0x00); // version 00 + TuyaSerial->write(cmd); // Tuya command + TuyaSerial->write(payload_len >> 8); // following data length (Hi) + TuyaSerial->write(payload_len & 0xFF); // following data length (Lo) snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Sent Packet: \"55aa00%02x%02x%02x"), cmd, payload_len >> 8, payload_len & 0xFF); for(int i = 0; i < payload_len; ++i) { TuyaSerial->write(payload[i]); @@ -74,7 +74,7 @@ void TuyaSendCmd(uint8_t cmd, uint8_t payload[] = nullptr, uint16_t payload_len AddLog(LOG_LEVEL_DEBUG); } -void TuyaSendState(uint8_t type, uint8_t id, uint8_t* value){ +void TuyaSendState(uint8_t id, uint8_t type, uint8_t* value){ uint16_t payload_len = 4; uint8_t payload_buffer[8]; payload_buffer[0] = id; @@ -101,11 +101,11 @@ void TuyaSendState(uint8_t type, uint8_t id, uint8_t* value){ } void TuyaSendBool(uint8_t id, boolean value){ - TuyaSendState(TUYA_TYPE_BOOL, id, &value); + TuyaSendState(id, TUYA_TYPE_BOOL, &value); } void TuyaSendValue(uint8_t id, uint32_t value){ - TuyaSendState(TUYA_TYPE_VALUE, id, (uint8_t*)(&value)); + TuyaSendState(id, TUYA_TYPE_VALUE, (uint8_t*)(&value)); } boolean TuyaSetPower() @@ -363,14 +363,13 @@ void TuyaResetWifi() boolean TuyaButtonPressed() { - if ((PRESSED == XdrvMailbox.payload) && (NOT_PRESSED == lastbutton[XdrvMailbox.index])) { - - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_LEVEL_10), XdrvMailbox.index +1); + if (!XdrvMailbox.index && ((PRESSED == XdrvMailbox.payload) && (NOT_PRESSED == lastbutton[XdrvMailbox.index]))) { + snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Reset GPIO triggered")); AddLog(LOG_LEVEL_DEBUG); TuyaResetWifi(); - + return true; // Reset GPIO served here } - return true; // Serviced here + return false; // Don't serve other buttons } /*********************************************************************************************\ From 0c3123a7aa4db1c25e4eb7466e66d94d6015e729 Mon Sep 17 00:00:00 2001 From: Joel Stein Date: Sun, 4 Nov 2018 06:56:36 +0100 Subject: [PATCH 6/6] tuya: reorder functions --- sonoff/xdrv_16_tuyadimmer.ino | 120 ++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 55 deletions(-) diff --git a/sonoff/xdrv_16_tuyadimmer.ino b/sonoff/xdrv_16_tuyadimmer.ino index f3b087c7d..bf8213da2 100644 --- a/sonoff/xdrv_16_tuyadimmer.ino +++ b/sonoff/xdrv_16_tuyadimmer.ino @@ -54,11 +54,15 @@ int8_t tuya_wifi_state = -2; // Keep MCU wifi-status in sync with char tuya_buffer[TUYA_BUFFER_SIZE]; // Serial receive buffer int tuya_byte_counter = 0; // Index in serial receive buffer +/*********************************************************************************************\ + * Internal Functions +\*********************************************************************************************/ + 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)); TuyaSerial->write(0x55); // Tuya header 55AA TuyaSerial->write(0xAA); - TuyaSerial->write(0x00); // version 00 + TuyaSerial->write((uint8_t)0x00); // version 00 TuyaSerial->write(cmd); // Tuya command TuyaSerial->write(payload_len >> 8); // following data length (Hi) TuyaSerial->write(payload_len & 0xFF); // following data length (Lo) @@ -148,6 +152,25 @@ void LightSerialDuty(uint8_t duty) } } +void TuyaRequestState(){ + if(TuyaSerial) { + // Get current status of MCU + snprintf_P(log_data, sizeof(log_data), "TYA: Request MCU state"); + AddLog(LOG_LEVEL_DEBUG); + + TuyaSendCmd(TUYA_CMD_QUERY_STATE); + } +} + +void TuyaResetWifi() +{ + if (!Settings.flag.button_restrict) { + char scmnd[20]; + snprintf_P(scmnd, sizeof(scmnd), D_CMND_WIFICONFIG " %d", 2); + ExecuteCommand(scmnd, SRC_BUTTON); + } +} + void TuyaPacketProcess() { char scmnd[20]; @@ -237,6 +260,39 @@ void TuyaPacketProcess() } } +/*********************************************************************************************\ + * API Functions +\*********************************************************************************************/ + +boolean TuyaModuleSelected() +{ + if (!(pin[GPIO_TUYA_RX] < 99) || !(pin[GPIO_TUYA_TX] < 99)) { // fallback to hardware-serial if not explicitly selected + pin[GPIO_TUYA_TX] = 1; + pin[GPIO_TUYA_RX] = 3; + Settings.my_gp.io[1] = GPIO_TUYA_TX; + Settings.my_gp.io[3] = GPIO_TUYA_RX; + restart_flag = 2; + } + light_type = LT_SERIAL; + return true; +} + +void TuyaInit() +{ + if (!Settings.param[P_TUYA_DIMMER_ID]) { + Settings.param[P_TUYA_DIMMER_ID] = TUYA_DIMMER_ID; + } + TuyaSerial = new TasmotaSerial(pin[GPIO_TUYA_RX], pin[GPIO_TUYA_TX], 1); + if (TuyaSerial->begin(9600)) { + if (TuyaSerial->hardwareSerial()) { ClaimSerial(); } + // Get MCU Configuration + snprintf_P(log_data, sizeof(log_data), "TYA: Request MCU configuration"); + AddLog(LOG_LEVEL_DEBUG); + + TuyaSendCmd(TUYA_CMD_MCU_CONF); + } +} + void TuyaSerialInput() { while (TuyaSerial->available()) { @@ -292,17 +348,16 @@ void TuyaSerialInput() } } -boolean TuyaModuleSelected() + +boolean TuyaButtonPressed() { - if (!(pin[GPIO_TUYA_RX] < 99) || !(pin[GPIO_TUYA_TX] < 99)) { // fallback to hardware-serial if not explicitly selected - pin[GPIO_TUYA_TX] = 1; - pin[GPIO_TUYA_RX] = 3; - Settings.my_gp.io[1] = GPIO_TUYA_TX; - Settings.my_gp.io[3] = GPIO_TUYA_RX; - restart_flag = 2; + if (!XdrvMailbox.index && ((PRESSED == XdrvMailbox.payload) && (NOT_PRESSED == lastbutton[XdrvMailbox.index]))) { + snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Reset GPIO triggered")); + AddLog(LOG_LEVEL_DEBUG); + TuyaResetWifi(); + return true; // Reset GPIO served here } - light_type = LT_SERIAL; - return true; + return false; // Don't serve other buttons } void TuyaSetWifiLed(){ @@ -326,51 +381,6 @@ void TuyaSetWifiLed(){ TuyaSendCmd(TUYA_CMD_WIFI_STATE, &wifi_state, 1); } -void TuyaRequestState(){ - if(TuyaSerial) { - // Get current status of MCU - snprintf_P(log_data, sizeof(log_data), "TYA: Request MCU state"); - AddLog(LOG_LEVEL_DEBUG); - - TuyaSendCmd(TUYA_CMD_QUERY_STATE); - } -} - -void TuyaInit() -{ - if (!Settings.param[P_TUYA_DIMMER_ID]) { - Settings.param[P_TUYA_DIMMER_ID] = TUYA_DIMMER_ID; - } - TuyaSerial = new TasmotaSerial(pin[GPIO_TUYA_RX], pin[GPIO_TUYA_TX], 1); - if (TuyaSerial->begin(9600)) { - if (TuyaSerial->hardwareSerial()) { ClaimSerial(); } - // Get MCU Configuration - snprintf_P(log_data, sizeof(log_data), "TYA: Request MCU configuration"); - AddLog(LOG_LEVEL_DEBUG); - - TuyaSendCmd(TUYA_CMD_MCU_CONF); - } -} - -void TuyaResetWifi() -{ - if (!Settings.flag.button_restrict) { - char scmnd[20]; - snprintf_P(scmnd, sizeof(scmnd), D_CMND_WIFICONFIG " %d", 2); - ExecuteCommand(scmnd, SRC_BUTTON); - } -} - -boolean TuyaButtonPressed() -{ - if (!XdrvMailbox.index && ((PRESSED == XdrvMailbox.payload) && (NOT_PRESSED == lastbutton[XdrvMailbox.index]))) { - snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Reset GPIO triggered")); - AddLog(LOG_LEVEL_DEBUG); - TuyaResetWifi(); - return true; // Reset GPIO served here - } - return false; // Don't serve other buttons -} /*********************************************************************************************\ * Interface