mirror of https://github.com/arendst/Tasmota.git
TuyaUpdate
This commit is contained in:
parent
0cb31f72dd
commit
ae32549759
|
@ -381,6 +381,9 @@ enum TuyaSupportedFunctions { TUYA_MCU_FUNC_NONE,
|
||||||
TUYA_MCU_FUNC_REL6_INV, TUYA_MCU_FUNC_REL7_INV, TUYA_MCU_FUNC_REL8_INV,
|
TUYA_MCU_FUNC_REL6_INV, TUYA_MCU_FUNC_REL7_INV, TUYA_MCU_FUNC_REL8_INV,
|
||||||
TUYA_MCU_FUNC_LOWPOWER_MODE = 51,
|
TUYA_MCU_FUNC_LOWPOWER_MODE = 51,
|
||||||
TUYA_MCU_FUNC_ENUM1 = 61, TUYA_MCU_FUNC_ENUM2, TUYA_MCU_FUNC_ENUM3, TUYA_MCU_FUNC_ENUM4,
|
TUYA_MCU_FUNC_ENUM1 = 61, TUYA_MCU_FUNC_ENUM2, TUYA_MCU_FUNC_ENUM3, TUYA_MCU_FUNC_ENUM4,
|
||||||
|
TUYA_MCU_FUNC_TEMP = 71, TUYA_MCU_FUNC_TEMPSET, TUYA_MCU_FUNC_HUM, TUYA_MCU_FUNC_HUMSET,
|
||||||
|
TUYA_MCU_FUNC_LX = 75, TUYA_MCU_FUNC_TVOC, TUYA_MCU_FUNC_CO2, TUYA_MCU_FUNC_ECO2,
|
||||||
|
TUYA_MCU_FUNC_TIMER1 = 81, TUYA_MCU_FUNC_TIMER2, TUYA_MCU_FUNC_TIMER3, TUYA_MCU_FUNC_TIMER4,
|
||||||
TUYA_MCU_FUNC_MOTOR_DIR = 97,
|
TUYA_MCU_FUNC_MOTOR_DIR = 97,
|
||||||
TUYA_MCU_FUNC_ERROR = 98,
|
TUYA_MCU_FUNC_ERROR = 98,
|
||||||
TUYA_MCU_FUNC_DUMMY = 99,
|
TUYA_MCU_FUNC_DUMMY = 99,
|
||||||
|
|
|
@ -62,7 +62,8 @@ struct TUYA {
|
||||||
uint16_t CTMin = 153; // Minimum CT level allowed - When SetOption82 is enabled will default to 200
|
uint16_t CTMin = 153; // Minimum CT level allowed - When SetOption82 is enabled will default to 200
|
||||||
uint16_t CTMax = 500; // Maximum CT level allowed - When SetOption82 is enabled will default to 380
|
uint16_t CTMax = 500; // Maximum CT level allowed - When SetOption82 is enabled will default to 380
|
||||||
bool ModeSet = false; // Controls 0 - Single Tone light, 1 - RGB Light
|
bool ModeSet = false; // Controls 0 - Single Tone light, 1 - RGB Light
|
||||||
uint8_t FanState = 0; // Stores the current fan speed
|
uint16_t Sensors[14]; // Stores the values of Sensors connected to the Tuya Device
|
||||||
|
bool SensorsValid[14]; // Bool used for nullify the sensor value until a real value is received from the MCU
|
||||||
bool SuspendTopic = false; // Used to reduce the load at init time or when polling the configuraton on demand
|
bool SuspendTopic = false; // Used to reduce the load at init time or when polling the configuraton on demand
|
||||||
uint32_t ignore_topic_timeout = 0; // Suppress the /STAT topic (if enabled) to avoid data overflow until the configuration is over
|
uint32_t ignore_topic_timeout = 0; // Suppress the /STAT topic (if enabled) to avoid data overflow until the configuration is over
|
||||||
bool ignore_dim = false; // Flag to skip serial send to prevent looping when processing inbound states from the faceplate interaction
|
bool ignore_dim = false; // Flag to skip serial send to prevent looping when processing inbound states from the faceplate interaction
|
||||||
|
@ -90,6 +91,13 @@ struct TUYA {
|
||||||
#define D_CMND_TUYARGB "RGB"
|
#define D_CMND_TUYARGB "RGB"
|
||||||
#define D_CMND_TUYA_ENUM "Enum"
|
#define D_CMND_TUYA_ENUM "Enum"
|
||||||
#define D_CMND_TUYA_ENUM_LIST "EnumList"
|
#define D_CMND_TUYA_ENUM_LIST "EnumList"
|
||||||
|
#define D_CMND_TUYA_SET_TEMP "SetTemp"
|
||||||
|
#define D_CMND_TUYA_SET_HUM "SetHum"
|
||||||
|
#define D_CMND_TUYA_SET_TIMER "SetTimer"
|
||||||
|
|
||||||
|
const char kTuyaSensors[] PROGMEM = // Lit of available sensors (can be expanded in the future)
|
||||||
|
"" D_JSON_TEMPERATURE "|TempSet|" D_JSON_HUMIDITY "|HumSet|" D_JSON_ILLUMINANCE
|
||||||
|
"|" D_JSON_TVOC "|" D_JSON_ECO2 "|" D_JSON_CO2 "|||Timer1|Timer2|Timer3|TImer4";
|
||||||
|
|
||||||
const char kTuyaCommand[] PROGMEM = D_PRFX_TUYA "|" // Prefix
|
const char kTuyaCommand[] PROGMEM = D_PRFX_TUYA "|" // Prefix
|
||||||
D_CMND_TUYA_MCU "|" D_CMND_TUYA_MCU_SEND_STATE "|" D_CMND_TUYARGB "|" D_CMND_TUYA_ENUM "|" D_CMND_TUYA_ENUM_LIST;
|
D_CMND_TUYA_MCU "|" D_CMND_TUYA_MCU_SEND_STATE "|" D_CMND_TUYARGB "|" D_CMND_TUYA_ENUM "|" D_CMND_TUYA_ENUM_LIST;
|
||||||
|
@ -115,6 +123,9 @@ bool TuyaModeSet(void) // ModeSet Status
|
||||||
{
|
{
|
||||||
return Tuya.ModeSet;
|
return Tuya.ModeSet;
|
||||||
}
|
}
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Web Interface
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TuyaSend<x> dpId,data
|
TuyaSend<x> dpId,data
|
||||||
|
@ -124,7 +135,7 @@ TuyaSend1 11,1 -> Sends boolean (Type 1) data 0/1 to dpId 11 (Max data length 1
|
||||||
TuyaSend2 11,100 -> Sends integer (Type 2) data 100 to dpId 11 (Max data length 4 bytes)
|
TuyaSend2 11,100 -> Sends integer (Type 2) data 100 to dpId 11 (Max data length 4 bytes)
|
||||||
TuyaSend2 11,0xAABBCCDD -> Sends 4 bytes (Type 2) data to dpId 11 (Max data length 4 bytes)
|
TuyaSend2 11,0xAABBCCDD -> Sends 4 bytes (Type 2) data to dpId 11 (Max data length 4 bytes)
|
||||||
TuyaSend3 11,ThisIsTheData -> Sends the supplied string (Type 3) to dpId 11 ( Max data length not-known)
|
TuyaSend3 11,ThisIsTheData -> Sends the supplied string (Type 3) to dpId 11 ( Max data length not-known)
|
||||||
TuyaSend4 11,1 -> Sends enum (Type 4) data 0/1/2/3/4/5/6/7/8/9 to dpId 11 (Max data length 1 bytes)
|
TuyaSend4 11,1 -> Sends enum (Type 4) data 1 to dpId 11 (Max data length 1 bytes)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void CmndTuyaSend(void) {
|
void CmndTuyaSend(void) {
|
||||||
|
@ -195,12 +206,6 @@ void CmndTuyaMcu(void) {
|
||||||
} else { Settings.flag3.pwm_multi_channels = 0; }
|
} else { Settings.flag3.pwm_multi_channels = 0; }
|
||||||
TuyaAddMcuFunc(parm[0], parm[1]);
|
TuyaAddMcuFunc(parm[0], parm[1]);
|
||||||
TasmotaGlobal.restart_flag = 2;
|
TasmotaGlobal.restart_flag = 2;
|
||||||
if (TUYA_MCU_FUNC_RGB == parm[0] && parm[1] != 0) {
|
|
||||||
// if (Settings.tuya_fnid_map[235].dpid > 3) {
|
|
||||||
// Settings.tuya_fnid_map[235].fnid = 235;
|
|
||||||
// Settings.tuya_fnid_map[235].dpid = 0;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
AddLog_P(LOG_LEVEL_ERROR, PSTR("TYA: TuyaMcu Invalid function id=%d"), parm[0]);
|
AddLog_P(LOG_LEVEL_ERROR, PSTR("TYA: TuyaMcu Invalid function id=%d"), parm[0]);
|
||||||
}
|
}
|
||||||
|
@ -228,7 +233,7 @@ void CmndTuyaRgb(void) { // Command to control the RGB format
|
||||||
if (payload < 0 || payload > 3 || TuyaGetDpId(TUYA_MCU_FUNC_RGB) == 0) {
|
if (payload < 0 || payload > 3 || TuyaGetDpId(TUYA_MCU_FUNC_RGB) == 0) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (payload != Settings.tuya_fnid_map[230].dpid) { // fnid 230 reserved for RGB
|
if (payload != Settings.tuya_fnid_map[230].dpid) { // fnid 230 is reserved for RGB
|
||||||
Settings.tuya_fnid_map[230].fnid = 230;
|
Settings.tuya_fnid_map[230].fnid = 230;
|
||||||
Settings.tuya_fnid_map[230].dpid = payload;
|
Settings.tuya_fnid_map[230].dpid = payload;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +276,7 @@ void CmndTuyaEnum(void) { // Command to control up to four type 4 Enum
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndTuyaEnumList(void) { // Command to declare the number of items in list for up to four type 4 enum. Min = 0, Max = 9, Default = 1
|
void CmndTuyaEnumList(void) { // Command to declare the number of items in list for up to four type 4 enum. Min = 0, Max = 31, Default = 0
|
||||||
|
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
char *p;
|
char *p;
|
||||||
|
@ -281,7 +286,7 @@ void CmndTuyaEnumList(void) { // Command to declare the number of items in list
|
||||||
parm[i] = strtoul(str, nullptr, 0);
|
parm[i] = strtoul(str, nullptr, 0);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if ((parm[0] >= 1 && parm[0] <= 4) && (parm[1] >= 1 && parm[1] <= 9)) {
|
if ((parm[0] >= 1 && parm[0] <= 4) && (parm[1] >= 1 && parm[1] <= 31)) {
|
||||||
uint16_t idx = parm[0] + 230; // fnid 231, 232, 233 and 234 are reserved for enum
|
uint16_t idx = parm[0] + 230; // fnid 231, 232, 233 and 234 are reserved for enum
|
||||||
Settings.tuya_fnid_map[idx].fnid = idx;
|
Settings.tuya_fnid_map[idx].fnid = idx;
|
||||||
Settings.tuya_fnid_map[idx].dpid = parm[1];
|
Settings.tuya_fnid_map[idx].dpid = parm[1];
|
||||||
|
@ -295,7 +300,7 @@ void CmndTuyaEnumList(void) { // Command to declare the number of items in list
|
||||||
if (TuyaGetDpId(TUYA_MCU_FUNC_ENUM1 + i) != 0) {
|
if (TuyaGetDpId(TUYA_MCU_FUNC_ENUM1 + i) != 0) {
|
||||||
if (added) {
|
if (added) {
|
||||||
ResponseAppend_P(PSTR(","));
|
ResponseAppend_P(PSTR(","));
|
||||||
if ( Settings.tuya_fnid_map[i + 231].dpid > 9 ) { Settings.tuya_fnid_map[i + 231].dpid = 1; } // default to 1 it the value exceed the range
|
if ( Settings.tuya_fnid_map[i + 231].dpid > 31 ) { Settings.tuya_fnid_map[i + 231].dpid = 0; } // default to 0 it the value exceed the range
|
||||||
}
|
}
|
||||||
ResponseAppend_P(PSTR("\"Enum%d\":%d"), i + 1, Settings.tuya_fnid_map[i + 231].dpid); // fnid 231, 232, 233 and 234 are reserved for Enum
|
ResponseAppend_P(PSTR("\"Enum%d\":%d"), i + 1, Settings.tuya_fnid_map[i + 231].dpid); // fnid 231, 232, 233 and 234 are reserved for Enum
|
||||||
added = true;
|
added = true;
|
||||||
|
@ -305,7 +310,7 @@ void CmndTuyaEnumList(void) { // Command to declare the number of items in list
|
||||||
} else { return; }
|
} else { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
int StrCmpNoCase(char const *Str1, char const *Str2) // Compare RGB case sensistive strings
|
int StrCmpNoCase(char const *Str1, char const *Str2) // Compare case sensistive RGB strings
|
||||||
{
|
{
|
||||||
for (;; Str1++, Str2++) {
|
for (;; Str1++, Str2++) {
|
||||||
int StrCmp = tolower((unsigned char)*Str1) - tolower((unsigned char)*Str2);
|
int StrCmp = tolower((unsigned char)*Str1) - tolower((unsigned char)*Str2);
|
||||||
|
@ -367,7 +372,10 @@ inline bool TuyaFuncIdValid(uint8_t fnId) {
|
||||||
(fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) ||
|
(fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) ||
|
||||||
(fnId >= TUYA_MCU_FUNC_ENUM1 && fnId <= TUYA_MCU_FUNC_ENUM4) ||
|
(fnId >= TUYA_MCU_FUNC_ENUM1 && fnId <= TUYA_MCU_FUNC_ENUM4) ||
|
||||||
(fnId >= TUYA_MCU_FUNC_MOTOR_DIR && fnId <= TUYA_MCU_FUNC_DUMMY) ||
|
(fnId >= TUYA_MCU_FUNC_MOTOR_DIR && fnId <= TUYA_MCU_FUNC_DUMMY) ||
|
||||||
(fnId == TUYA_MCU_FUNC_LOWPOWER_MODE);
|
(fnId == TUYA_MCU_FUNC_LOWPOWER_MODE) ||
|
||||||
|
(fnId >= TUYA_MCU_FUNC_TEMP && fnId <= TUYA_MCU_FUNC_HUMSET) ||
|
||||||
|
(fnId >= TUYA_MCU_FUNC_LX && fnId <= TUYA_MCU_FUNC_ECO2) ||
|
||||||
|
(fnId >= TUYA_MCU_FUNC_TIMER1 && fnId <= TUYA_MCU_FUNC_TIMER4);
|
||||||
}
|
}
|
||||||
uint8_t TuyaGetFuncId(uint8_t dpid) {
|
uint8_t TuyaGetFuncId(uint8_t dpid) {
|
||||||
for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) {
|
for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) {
|
||||||
|
@ -527,7 +535,7 @@ bool TuyaSetChannels(void)
|
||||||
if (i == 0 && LightMode && Tuya.ModeSet ) { noupd = true;}
|
if (i == 0 && LightMode && Tuya.ModeSet ) { noupd = true;}
|
||||||
if (!noupd) {
|
if (!noupd) {
|
||||||
LightSerialDuty(Tuya.Snapshot[i], &hex_char[0], i+1);
|
LightSerialDuty(Tuya.Snapshot[i], &hex_char[0], i+1);
|
||||||
Tuya.Levels[i] = Tuya.Snapshot[i];
|
//Tuya.Levels[i] = Tuya.Snapshot[i];
|
||||||
}
|
}
|
||||||
noupd = false;
|
noupd = false;
|
||||||
}
|
}
|
||||||
|
@ -665,6 +673,7 @@ void TuyaProcessStatePacket(void) {
|
||||||
uint8_t dpidStart = 6;
|
uint8_t dpidStart = 6;
|
||||||
uint8_t fnId;
|
uint8_t fnId;
|
||||||
uint16_t dpDataLen;
|
uint16_t dpDataLen;
|
||||||
|
bool PowerOff = false;
|
||||||
|
|
||||||
while (dpidStart + 4 < Tuya.byte_counter) {
|
while (dpidStart + 4 < Tuya.byte_counter) {
|
||||||
dpDataLen = Tuya.buffer[dpidStart + 2] << 8 | Tuya.buffer[dpidStart + 3];
|
dpDataLen = Tuya.buffer[dpidStart + 2] << 8 | Tuya.buffer[dpidStart + 3];
|
||||||
|
@ -676,12 +685,14 @@ void TuyaProcessStatePacket(void) {
|
||||||
if (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) {
|
if (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) {
|
||||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[dpidStart + 4]?"On":"Off",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1)?"On":"Off");
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[dpidStart + 4]?"On":"Off",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1)?"On":"Off");
|
||||||
if ((TasmotaGlobal.power || Settings.light_dimmer > 0) && (Tuya.buffer[dpidStart + 4] != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1))) {
|
if ((TasmotaGlobal.power || Settings.light_dimmer > 0) && (Tuya.buffer[dpidStart + 4] != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1))) {
|
||||||
|
if (!Tuya.buffer[dpidStart + 4]) { PowerOff = true; }
|
||||||
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[dpidStart + 4], SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
|
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[dpidStart + 4], 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) {
|
} else if (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) {
|
||||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d-Inverted --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1_INV + 1, Tuya.buffer[dpidStart + 4]?"Off":"On",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1?"Off":"On");
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d-Inverted --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1_INV + 1, Tuya.buffer[dpidStart + 4]?"Off":"On",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1?"Off":"On");
|
||||||
if (Tuya.buffer[dpidStart + 4] != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1) {
|
if (Tuya.buffer[dpidStart + 4] != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1) {
|
||||||
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1_INV + 1, Tuya.buffer[dpidStart + 4] ^ 1, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
|
ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1_INV + 1, Tuya.buffer[dpidStart + 4] ^ 1, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
|
||||||
|
if (Tuya.buffer[dpidStart + 4]) { PowerOff = true; }
|
||||||
}
|
}
|
||||||
} else if (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) {
|
} else if (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) {
|
||||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: RX Switch-%d --> MCU State: %d Current State:%d"),fnId - TUYA_MCU_FUNC_SWT1 + 1,Tuya.buffer[dpidStart + 4], SwitchGetVirtual(fnId - TUYA_MCU_FUNC_SWT1));
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: RX Switch-%d --> MCU State: %d Current State:%d"),fnId - TUYA_MCU_FUNC_SWT1 + 1,Tuya.buffer[dpidStart + 4], SwitchGetVirtual(fnId - TUYA_MCU_FUNC_SWT1));
|
||||||
|
@ -691,18 +702,46 @@ void TuyaProcessStatePacket(void) {
|
||||||
SwitchHandler(1);
|
SwitchHandler(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (PowerOff) { Tuya.ignore_dimmer_cmd_timeout = millis() + 250; }
|
||||||
}
|
}
|
||||||
else if (Tuya.buffer[dpidStart + 1] == 2) { // Data Type 2
|
else if (Tuya.buffer[dpidStart + 1] == 2) { // Data Type 2
|
||||||
bool tuya_energy_enabled = (XNRG_32 == TasmotaGlobal.energy_driver);
|
bool tuya_energy_enabled = (XNRG_32 == TasmotaGlobal.energy_driver);
|
||||||
uint16_t packetValue = Tuya.buffer[dpidStart + 6] << 8 | Tuya.buffer[dpidStart + 7];
|
uint16_t packetValue = Tuya.buffer[dpidStart + 6] << 8 | Tuya.buffer[dpidStart + 7];
|
||||||
uint8_t dimIndex;
|
uint8_t dimIndex;
|
||||||
|
bool SnsUpdate = false;
|
||||||
|
|
||||||
|
if ((fnId >= TUYA_MCU_FUNC_TEMP) && (fnId <= TUYA_MCU_FUNC_TIMER4)) { // Sensors start from fnId 71
|
||||||
|
if (packetValue != Tuya.Sensors[fnId-71]) {
|
||||||
|
Tuya.SensorsValid[fnId-71] = true;
|
||||||
|
Tuya.Sensors[fnId-71] = packetValue;
|
||||||
|
SnsUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SnsUpdate) {
|
||||||
|
char sname[20];
|
||||||
|
char tempval[5];
|
||||||
|
uint8_t res;
|
||||||
|
|
||||||
|
if (TasmotaGlobal.uptime < 8) { // delay to avoid multiple topics at the same time at boot time
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (fnId > 74) {
|
||||||
|
res = 0;
|
||||||
|
} else { res = Settings.flag2.temperature_resolution; }
|
||||||
|
GetTextIndexed(sname, sizeof(sname), (fnId-71), kTuyaSensors);
|
||||||
|
ResponseClear(); // Clear retained message
|
||||||
|
Response_P(PSTR("{\"TuyaSNS\":{\"%s\":%s}}"), sname, dtostrfd(packetValue, res, tempval)); // sensor update is just on change
|
||||||
|
MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_CMND_SENSOR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fnId == TUYA_MCU_FUNC_DIMMER || fnId == TUYA_MCU_FUNC_REPORT1) { dimIndex = 0; }
|
if (fnId == TUYA_MCU_FUNC_DIMMER || fnId == TUYA_MCU_FUNC_REPORT1) { dimIndex = 0; }
|
||||||
|
|
||||||
if (fnId == TUYA_MCU_FUNC_DIMMER2 || fnId == TUYA_MCU_FUNC_REPORT2 || fnId == TUYA_MCU_FUNC_CT) { dimIndex = 1; }
|
if (fnId == TUYA_MCU_FUNC_DIMMER2 || fnId == TUYA_MCU_FUNC_REPORT2 || fnId == TUYA_MCU_FUNC_CT) { dimIndex = 1; }
|
||||||
|
|
||||||
if (dimIndex == 1 && !Settings.flag3.pwm_multi_channels) {
|
if (dimIndex == 1 && !Settings.flag3.pwm_multi_channels) {
|
||||||
Tuya.Levels[dimIndex] = changeUIntScale(packetValue, 0, Settings.dimmer_hw_max, Tuya.CTMax, Tuya.CTMin);
|
Tuya.Levels[1] = changeUIntScale(packetValue, 0, Settings.dimmer_hw_max, Tuya.CTMax, Tuya.CTMin);
|
||||||
} else {
|
} else {
|
||||||
Tuya.Levels[dimIndex] = changeUIntScale(packetValue, 0, Settings.dimmer_hw_max, 0, 100);
|
Tuya.Levels[dimIndex] = changeUIntScale(packetValue, 0, Settings.dimmer_hw_max, 0, 100);
|
||||||
}
|
}
|
||||||
|
@ -714,9 +753,7 @@ void TuyaProcessStatePacket(void) {
|
||||||
(fnId == TUYA_MCU_FUNC_CT) || (fnId == TUYA_MCU_FUNC_WHITE)) {
|
(fnId == TUYA_MCU_FUNC_CT) || (fnId == TUYA_MCU_FUNC_WHITE)) {
|
||||||
|
|
||||||
if (Tuya.ignore_dimmer_cmd_timeout < millis()) {
|
if (Tuya.ignore_dimmer_cmd_timeout < millis()) {
|
||||||
|
|
||||||
if ((TasmotaGlobal.power || Settings.flag3.tuya_apply_o20) && ((Tuya.Levels[dimIndex] > 0) && (Tuya.Levels[dimIndex] != Tuya.Snapshot[dimIndex]))) { // SetOption54 - Apply SetOption20 settings to Tuya device
|
if ((TasmotaGlobal.power || Settings.flag3.tuya_apply_o20) && ((Tuya.Levels[dimIndex] > 0) && (Tuya.Levels[dimIndex] != Tuya.Snapshot[dimIndex]))) { // SetOption54 - Apply SetOption20 settings to Tuya device
|
||||||
|
|
||||||
Tuya.ignore_dim = true;
|
Tuya.ignore_dim = true;
|
||||||
TasmotaGlobal.skip_light_fade = true;
|
TasmotaGlobal.skip_light_fade = true;
|
||||||
|
|
||||||
|
@ -743,6 +780,7 @@ void TuyaProcessStatePacket(void) {
|
||||||
ExecuteCommand(scmnd, SRC_SWITCH);
|
ExecuteCommand(scmnd, SRC_SWITCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Tuya.Snapshot[dimIndex] = Tuya.Levels[dimIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef USE_ENERGY_SENSOR
|
#ifdef USE_ENERGY_SENSOR
|
||||||
|
@ -794,7 +832,6 @@ void TuyaProcessStatePacket(void) {
|
||||||
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_COLOR " %s"), RGB);
|
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_COLOR " %s"), RGB);
|
||||||
memcpy_P(Tuya.RGBColor, RGB, strlen(RGB));
|
memcpy_P(Tuya.RGBColor, RGB, strlen(RGB));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (scmnd[0] != '\0') {
|
if (scmnd[0] != '\0') {
|
||||||
ExecuteCommand(scmnd, SRC_SWITCH);
|
ExecuteCommand(scmnd, SRC_SWITCH);
|
||||||
|
@ -809,8 +846,6 @@ void TuyaProcessStatePacket(void) {
|
||||||
Tuya.Levels[3] = dpData[0];
|
Tuya.Levels[3] = dpData[0];
|
||||||
}
|
}
|
||||||
if ((fnId >= TUYA_MCU_FUNC_ENUM1) && (fnId <= TUYA_MCU_FUNC_ENUM4)) {
|
if ((fnId >= TUYA_MCU_FUNC_ENUM1) && (fnId <= TUYA_MCU_FUNC_ENUM4)) {
|
||||||
// if ((fnId == TUYA_MCU_FUNC_ENUM1) || (fnId == TUYA_MCU_FUNC_ENUM2) ||
|
|
||||||
// (fnId == TUYA_MCU_FUNC_ENUM3) || (fnId == TUYA_MCU_FUNC_ENUM4)) {
|
|
||||||
for (uint8_t i = 0; i <= 3; i++) {
|
for (uint8_t i = 0; i <= 3; i++) {
|
||||||
bool noupdate = false;
|
bool noupdate = false;
|
||||||
if ((TUYA_MCU_FUNC_ENUM1 + i) == fnId) {
|
if ((TUYA_MCU_FUNC_ENUM1 + i) == fnId) {
|
||||||
|
@ -998,7 +1033,7 @@ void TuyaInit(void)
|
||||||
Tuya.SuspendTopic = true;
|
Tuya.SuspendTopic = true;
|
||||||
Tuya.ignore_topic_timeout = millis() + 1000; // suppress /STAT topic for 1000ms to avoid data overflow
|
Tuya.ignore_topic_timeout = millis() + 1000; // suppress /STAT topic for 1000ms to avoid data overflow
|
||||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Request MCU configuration at %d bps"), baudrate);
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Request MCU configuration at %d bps"), baudrate);
|
||||||
TuyaSendCmd(TUYA_CMD_QUERY_PRODUCT);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1217,6 +1252,82 @@ bool Xnrg32(uint8_t function)
|
||||||
}
|
}
|
||||||
#endif // USE_ENERGY_SENSOR
|
#endif // USE_ENERGY_SENSOR
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Sensors
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
void TuyaSensorsShow(bool json)
|
||||||
|
{
|
||||||
|
bool RootName = false;
|
||||||
|
bool added = false;
|
||||||
|
char sname[20];
|
||||||
|
char tempval[5];
|
||||||
|
uint8_t res;
|
||||||
|
|
||||||
|
for (uint8_t sensor = TUYA_MCU_FUNC_TEMP; sensor <= TUYA_MCU_FUNC_TIMER4; sensor++) { // Sensors start from fnId 71
|
||||||
|
if (json) {
|
||||||
|
if (TuyaGetDpId(sensor) != 0) {
|
||||||
|
|
||||||
|
if (!RootName) {
|
||||||
|
ResponseAppend_P(PSTR(",\"TuyaSNS\":{"));
|
||||||
|
RootName = true;
|
||||||
|
}
|
||||||
|
if (added) {
|
||||||
|
ResponseAppend_P(PSTR(","));
|
||||||
|
}
|
||||||
|
if (sensor > 74) {
|
||||||
|
res = 0;
|
||||||
|
} else { res = Settings.flag2.temperature_resolution; }
|
||||||
|
|
||||||
|
GetTextIndexed(sname, sizeof(sname), (sensor-71), kTuyaSensors);
|
||||||
|
ResponseAppend_P(PSTR("\"%s\":%s"), sname,
|
||||||
|
(Tuya.SensorsValid[sensor-71] ? dtostrfd(Tuya.Sensors[sensor-71], res, tempval) : "null"));
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
} else {
|
||||||
|
if (TuyaGetDpId(sensor) != 0) {
|
||||||
|
switch (sensor) {
|
||||||
|
case 71:
|
||||||
|
WSContentSend_PD(HTTP_SNS_TEMP, "", dtostrfd(Tuya.Sensors[0], Settings.flag2.temperature_resolution, tempval), TempUnit());
|
||||||
|
break;
|
||||||
|
case 72:
|
||||||
|
WSContentSend_PD(PSTR("{s}" D_TEMPERATURE " Set{m}%s " D_UNIT_DEGREE "%c{e}"),
|
||||||
|
dtostrfd(Tuya.Sensors[1], Settings.flag2.temperature_resolution, tempval), TempUnit());
|
||||||
|
break;
|
||||||
|
case 73:
|
||||||
|
WSContentSend_PD(HTTP_SNS_HUM, "", dtostrfd(Tuya.Sensors[2], Settings.flag2.temperature_resolution, tempval));
|
||||||
|
break;
|
||||||
|
case 74:
|
||||||
|
WSContentSend_PD(PSTR("{s}" D_HUMIDITY " Set{m}%s " D_UNIT_PERCENT "{e}"),
|
||||||
|
dtostrfd(Tuya.Sensors[3], Settings.flag2.temperature_resolution, tempval));
|
||||||
|
break;
|
||||||
|
case 75:
|
||||||
|
WSContentSend_PD(HTTP_SNS_ILLUMINANCE, "", Tuya.Sensors[4]);
|
||||||
|
break;
|
||||||
|
case 76:
|
||||||
|
WSContentSend_PD(PSTR("{s}" D_TVOC "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"), Tuya.Sensors[5]);
|
||||||
|
break;
|
||||||
|
case 77:
|
||||||
|
WSContentSend_PD(HTTP_SNS_CO2, "", Tuya.Sensors[6]);
|
||||||
|
break;
|
||||||
|
case 78:
|
||||||
|
WSContentSend_PD(HTTP_SNS_CO2EAVG, "", Tuya.Sensors[7]);
|
||||||
|
break;
|
||||||
|
case 81:
|
||||||
|
case 82:
|
||||||
|
case 83:
|
||||||
|
case 84:
|
||||||
|
WSContentSend_PD(PSTR("{s}Timer%d{m}%d{e}"), (sensor-80), Tuya.Sensors[sensor-71]); // No UoM for timers since they can be sec or min
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // USE_WEBSERVER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (RootName) { ResponseJsonEnd();}
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Interface
|
* Interface
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -1243,7 +1354,6 @@ bool Xdrv16(uint8_t function)
|
||||||
result = TuyaButtonPressed();
|
result = TuyaButtonPressed();
|
||||||
break;
|
break;
|
||||||
case FUNC_EVERY_SECOND:
|
case FUNC_EVERY_SECOND:
|
||||||
TuyaSetChannels();
|
|
||||||
if (TuyaSerial && Tuya.wifi_state != TuyaGetTuyaWifiState()) { TuyaSetWifiLed(); }
|
if (TuyaSerial && Tuya.wifi_state != TuyaGetTuyaWifiState()) { TuyaSetWifiLed(); }
|
||||||
if (!Tuya.low_power_mode) {
|
if (!Tuya.low_power_mode) {
|
||||||
Tuya.heartbeat_timer++;
|
Tuya.heartbeat_timer++;
|
||||||
|
@ -1261,12 +1371,23 @@ bool Xdrv16(uint8_t function)
|
||||||
}
|
}
|
||||||
if (Tuya.ignore_topic_timeout < millis()) { Tuya.SuspendTopic = false; }
|
if (Tuya.ignore_topic_timeout < millis()) { Tuya.SuspendTopic = false; }
|
||||||
break;
|
break;
|
||||||
// case FUNC_SET_CHANNELS:
|
case FUNC_SET_CHANNELS:
|
||||||
// result = TuyaSetChannels();
|
result = TuyaSetChannels();
|
||||||
// break;
|
break;
|
||||||
|
case FUNC_MQTT_INIT:
|
||||||
|
TuyaSendCmd(TUYA_CMD_QUERY_PRODUCT);
|
||||||
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
result = DecodeCommand(kTuyaCommand, TuyaCommand);
|
result = DecodeCommand(kTuyaCommand, TuyaCommand);
|
||||||
break;
|
break;
|
||||||
|
case FUNC_JSON_APPEND:
|
||||||
|
TuyaSensorsShow(1);
|
||||||
|
break;
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
case FUNC_WEB_SENSOR:
|
||||||
|
TuyaSensorsShow(0);
|
||||||
|
break;
|
||||||
|
#endif // USE_WEBSERVER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Reference in New Issue