diff --git a/src/driver/drv_tuyaMCU.c b/src/driver/drv_tuyaMCU.c index ab994d8fb..a027b59c0 100644 --- a/src/driver/drv_tuyaMCU.c +++ b/src/driver/drv_tuyaMCU.c @@ -159,6 +159,10 @@ typedef struct tuyaMCUMapping_s { byte bDPCache; // store last channel value to avoid sending it again int prevValue; + // allow storing raw data for later usage + byte *rawData; + int rawBufferSize; + int rawDataLen; // TODO //int mode; // list @@ -326,6 +330,9 @@ void TuyaMCU_MapIDToChannel(int fnId, int dpType, int channel, int bDPCache) { cur->bDPCache = bDPCache; cur->prevValue = 0; cur->next = g_tuyaMappings; + cur->rawData = 0; + cur->rawDataLen = 0; + cur->rawBufferSize = 0; g_tuyaMappings = cur; } @@ -1273,6 +1280,64 @@ void TuyaMCU_ParseWeatherData(const byte* data, int len) { ofs += stringLen; } } + + + +int http_obk_json_dps(int id, void* request, jsonCb_t printer) { + int i; + int iCnt = 0; + char tmp[8]; + tuyaMCUMapping_t* cur; + + printer(request, "["); + + + cur = g_tuyaMappings; + while (cur) { + if (id == -1 || id == cur->fnId) { + if (iCnt) { + printer(request, ","); + } + iCnt++; + printer(request, "{\"id\":%i,\"type\":%i,\"data\":", cur->fnId, cur->dpType); + if (cur->rawData == 0) { + printer(request, "0\"}", cur->rawData); + } + else { + if (cur->dpType == DP_TYPE_BOOL || cur->dpType == DP_TYPE_ENUM + || cur->dpType == DP_TYPE_VALUE) { + if (cur->rawDataLen == 1) { + i = cur->rawData[0]; + } + else if (cur->rawDataLen == 4) { + i = cur->rawData[0] << 24 | cur->rawData[1] << 16 | cur->rawData[2] << 8 | cur->rawData[3]; + } + else { + i = 0; + } + printer(request, "%i}", i); + } + else if (cur->dpType == DP_TYPE_STRING) { + printer(request, "\"%s\"}", cur->rawData); + } + else { + printer(request, "\""); + for (i = 0; i < cur->rawDataLen; i++) { + sprintf(tmp, "%02X", cur->rawData[i]); + printer(request, "%s", tmp); + } + printer(request, "\"}"); + } + } + } + cur = cur->next; + } + + + printer(request, "]"); + return 0; +} + // Protocol version - 0x00 (not 0x03) // Used for battery powered devices, eg. door sensor. // Packet ID: 0x08 @@ -1448,6 +1513,17 @@ void TuyaMCU_ParseStateMessage(const byte* data, int len) { TuyaMCU_PublishDPToMQTT(data, ofs); } + if (CFG_HasFlag(OBK_FLAG_TUYAMCU_STORE_RAW_DATA)) { + if (mapping) { + if (mapping->rawBufferSize < sectorLen) { + mapping->rawData = realloc(mapping->rawData, sectorLen); + mapping->rawBufferSize = sectorLen; + } + mapping->rawDataLen = sectorLen; + memcpy(mapping->rawData, data + ofs + 4, sectorLen); + } + } + if (sectorLen == 1) { iVal = (int)data[ofs + 4]; addLogAdv(LOG_INFO, LOG_FEATURE_TUYAMCU, "TuyaMCU_ParseStateMessage: raw data 1 byte: %i\n", iVal); diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c index d2f2b5600..712388997 100644 --- a/src/httpserver/http_fns.c +++ b/src/httpserver/http_fns.c @@ -2573,8 +2573,11 @@ const char* g_obk_flagNames[] = { "[TuyaMCU] Use queue", "[HTTP] Disable authentication in safe mode (not recommended)", "[MQTT Discovery] Don't merge toggles and dimmers into lights", + "[TuyaMCU] Store raw data", "error", -}; + "error", +}; + int http_fn_cfg_generic(http_request_t* request) { int i; char tmpA[64]; @@ -2611,7 +2614,10 @@ int http_fn_cfg_generic(http_request_t* request) { CFG_Save_IfThereArePendingChanges(); + // 32 bit type hprintf255(request, "