From 47330af2a1bd4d58a23b2b157022066216c21a22 Mon Sep 17 00:00:00 2001 From: DigiH <17110652+DigiH@users.noreply.github.com> Date: Sun, 10 Aug 2025 15:02:32 +0200 Subject: [PATCH] LYWSD03MMC BTHome decoder adjustment Pulling the decoding of the two frames together into one decoder to ensure initial auto-discovery of all properties. --- docs/devices/LYWSD03MMC.md | 8 +++-- docs/devices/MJWSD05MMC.md | 10 +++--- src/decoder.h | 3 +- src/devices.h | 3 +- src/devices/LYWSD03MMC_json.h | 59 ++++++++++++----------------------- tests/BLE/test_ble.cpp | 8 ++--- 6 files changed, 37 insertions(+), 54 deletions(-) diff --git a/docs/devices/LYWSD03MMC.md b/docs/devices/LYWSD03MMC.md index 425d23ade..910c3fbf3 100644 --- a/docs/devices/LYWSD03MMC.md +++ b/docs/devices/LYWSD03MMC.md @@ -1,7 +1,7 @@ -# Xiaomi LYWSD03MMC ATC or PVVX firmware +# Xiaomi LYWSD03MMC ATC, PVVX or BTHome v2(*) firmware -|Model Id|[LYWSD03MMC_ATC/PVVX](https://github.com/theengs/decoder/blob/development/src/devices/LYWSD03MMC_json.h)| +|Model Id|[LYWSD03MMC_ATC/PVVX/BTHOME](https://github.com/theengs/decoder/blob/development/src/devices/LYWSD03MMC_json.h)| |-|-| |Brand|Xiaomi| |Model|Compact Temperature sensor| @@ -9,6 +9,8 @@ |Communication|BLE broadcast| |Frequency|2.4Ghz| |Power Source|CR2032| -|Exchanged Data|temperature, humidity, battery, voltage (depending on which LYWSD03MMC firmware is installed)| +|Exchanged Data|temperature, humidity, battery, voltage, packet, power, open (depending on which LYWSD03MMC firmware is installed)| |Encrypted|Yes/No - Optional| |Image|![LYWSD03MMC](./../img/LYWSD03MMC.png)| + +(*) For the BTHome v2 format to be recognised when using the PVVX TelinkMiFlasher the device name must start with the default prefix of "ATC". diff --git a/docs/devices/MJWSD05MMC.md b/docs/devices/MJWSD05MMC.md index 2b1b04a5f..571ed12a7 100644 --- a/docs/devices/MJWSD05MMC.md +++ b/docs/devices/MJWSD05MMC.md @@ -1,6 +1,6 @@ -# Xiaomi MJWSD05MMC ATC or PVVX firmware +# Xiaomi MJWSD05MMC ATC, PVVX or BTHome v2(*) firmware -|Model Id|[MJWSD05MMC_ATC/PVVX](https://github.com/theengs/decoder/blob/development/src/devices/LYWSD03MMC_json.h)| +|Model Id|[MJWSD05MMC_ATC/PVVX/BTHOME](https://github.com/theengs/decoder/blob/development/src/devices/LYWSD03MMC_json.h)| |-|-| |Brand|Xiaomi| |Model|Compact Temperature sensor| @@ -8,5 +8,7 @@ |Communication|BLE broadcast| |Frequency|2.4Ghz| |Power Source|CR2450| -|Exchanged Data|temperature, humidity, battery, volt| -|Encrypted|No| +|Exchanged Data|temperature, humidity, battery, voltage, packet, power, open (depending on which MJWSD05MMC firmware is installed)| +|Encrypted|Yes/No - Optional| + +(*) For the BTHome v2 format to be recognised when using the PVVX TelinkMiFlasher the device name must start with the default prefix of "ATC". diff --git a/src/decoder.h b/src/decoder.h index 7fc7997fe..8daef114b 100644 --- a/src/decoder.h +++ b/src/decoder.h @@ -79,8 +79,7 @@ class TheengsDecoder { LYWSD03MMC_ATC, LYWSD03MMC_PVVX, LYWSD03MMC_PVVX_DECR, - LYWSD03MMC_PVVX_BTHOME_1, - LYWSD03MMC_PVVX_BTHOME_2, + LYWSD03MMC_PVVX_BTHOME, LYWSD03MMC_PVVX_ENCR, LYWSD03MMC_PVVX_BTHOME_1_ENCR, LYWSD03MMC_PVVX_BTHOME_2_ENCR, diff --git a/src/devices.h b/src/devices.h index 98ab29e94..31804320a 100644 --- a/src/devices.h +++ b/src/devices.h @@ -173,8 +173,7 @@ const char* _devices[][2] = { {_LYWSD03MMC_json_ATC, _LYWSD03MMC_json_props}, {_LYWSD03MMC_json_PVVX, _LYWSD03MMC_json_props}, {_LYWSD03MMC_json_PVVX_DECR, _LYWSD03MMC_json_props}, - {_LYWSD03MMC_json_PVVX_BTHOME_1, _LYWSD03MMC_BTHOME_1_json_props}, - {_LYWSD03MMC_json_PVVX_BTHOME_2, _LYWSD03MMC_BTHOME_2_json_props}, + {_LYWSD03MMC_json_PVVX_BTHOME, _LYWSD03MMC_BTHOME_json_props}, {_LYWSD03MMC_ENCR_json_PVVX, _LYWSD03MMC_ENCR_json_props}, {_LYWSD03MMC_ENCR_json_PVVX_BTHOME_1, _LYWSD03MMC_ENCR_json_props}, {_LYWSD03MMC_ENCR_json_PVVX_BTHOME_2, _LYWSD03MMC_ENCR_json_props}, diff --git a/src/devices/LYWSD03MMC_json.h b/src/devices/LYWSD03MMC_json.h index e4fce769f..9fdce7ac5 100644 --- a/src/devices/LYWSD03MMC_json.h +++ b/src/devices/LYWSD03MMC_json.h @@ -82,60 +82,48 @@ const char* _LYWSD03MMC_json_PVVX_DECR = "{\"brand\":\"Xiaomi\",\"model\":\"TH S } })"""";*/ -const char* _LYWSD03MMC_json_PVVX_BTHOME_1 = "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX_BTHOME\",\"tag\":\"0102\",\"condition\":[\"servicedata\",\"=\",22,\"index\",0,\"40\",\"&\",\"uuid\",\"index\",0,\"fcd2\",\"&\",\"name\",\"index\",0,\"ATC\"],\"properties\":{\"packet\":{\"condition\":[\"servicedata\",2,\"00\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false]},\"tempc\":{\"condition\":[\"servicedata\",10,\"02\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,4,true,true],\"post_proc\":[\"/\",100]},\"hum\":{\"condition\":[\"servicedata\",16,\"03\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,4,true,false],\"post_proc\":[\"/\",100]},\"batt\":{\"condition\":[\"servicedata\",6,\"01\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,2,false,false]}}}"; +const char* _LYWSD03MMC_json_PVVX_BTHOME = "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX_BTHOME\",\"tag\":\"0102\",\"condition\":[\"servicedata\",\"=\",22,\"index\",0,\"40\",\"|\",\"servicedata\",\"=\",20,\"index\",0,\"40\",\"&\",\"uuid\",\"index\",0,\"fcd2\",\"&\",\"name\",\"index\",0,\"ATC\"],\"properties\":{\"packet_1\":{\"condition\":[\"servicedata\",2,\"00\",\"&\",\"servicedata\",\"=\",22],\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false]},\"tempc\":{\"condition\":[\"servicedata\",10,\"02\",\"&\",\"servicedata\",\"=\",22],\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,4,true,true],\"post_proc\":[\"/\",100]},\"hum\":{\"condition\":[\"servicedata\",16,\"03\",\"&\",\"servicedata\",\"=\",22],\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,4,true,false],\"post_proc\":[\"/\",100]},\"batt\":{\"condition\":[\"servicedata\",6,\"01\",\"&\",\"servicedata\",\"=\",22],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,2,false,false]},\"packet_2\":{\"condition\":[\"servicedata\",2,\"00\",\"&\",\"servicedata\",\"=\",20],\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false]},\"volt\":{\"condition\":[\"servicedata\",6,\"0c\",\"&\",\"servicedata\",\"=\",20],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,4,true,false],\"post_proc\":[\"/\",1000]},\"power\":{\"condition\":[\"servicedata\",12,\"10\",\"&\",\"servicedata\",\"=\",20],\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,2,false,false]},\"open\":{\"condition\":[\"servicedata\",16,\"11\",\"&\",\"servicedata\",\"=\",20],\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,2,false,false]}}}"; /* R""""( { "brand":"Xiaomi", "model":"TH Sensor", "model_id":"LYWSD03MMC/MJWSD05MMC_PVVX_BTHOME", "tag":"0102", - "condition":["servicedata", "=", 22, "index", 0, "40", "&", "uuid", "index", 0, "fcd2", "&", "name", "index", 0, "ATC"], + "condition":["servicedata", "=", 22, "index", 0, "40", "|", "servicedata", "=", 20, "index", 0, "40", "&", "uuid", "index", 0, "fcd2", "&", "name", "index", 0, "ATC"], "properties":{ - "packet":{ - "condition":["servicedata", 2, "00"], + "packet_1":{ + "condition":["servicedata", 2, "00", "&", "servicedata", "=", 22], "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false] }, "tempc":{ - "condition":["servicedata", 10, "02"], + "condition":["servicedata", 10, "02", "&", "servicedata", "=", 22], "decoder":["value_from_hex_data", "servicedata", 12, 4, true, true], "post_proc":["/", 100] }, "hum":{ - "condition":["servicedata", 16, "03"], + "condition":["servicedata", 16, "03", "&", "servicedata", "=", 22], "decoder":["value_from_hex_data", "servicedata", 18, 4, true, false], "post_proc":["/", 100] }, "batt":{ - "condition":["servicedata", 6, "01"], + "condition":["servicedata", 6, "01", "&", "servicedata", "=", 22], "decoder":["value_from_hex_data", "servicedata", 8, 2, false, false] - } - } -})"""";*/ - -const char* _LYWSD03MMC_json_PVVX_BTHOME_2 = "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX_BTHOME\",\"tag\":\"0102\",\"condition\":[\"servicedata\",\"=\",20,\"index\",0,\"40\",\"&\",\"uuid\",\"index\",0,\"fcd2\",\"&\",\"name\",\"index\",0,\"ATC\"],\"properties\":{\"packet\":{\"condition\":[\"servicedata\",2,\"00\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false]},\"volt\":{\"condition\":[\"servicedata\",6,\"0c\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,4,true,false],\"post_proc\":[\"/\",1000]},\"power\":{\"condition\":[\"servicedata\",12,\"10\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,2,false,false]},\"opening\":{\"condition\":[\"servicedata\",16,\"11\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,2,false,false]}}}"; -/* R""""( -{ - "brand":"Xiaomi", - "model":"TH Sensor", - "model_id":"LYWSD03MMC/MJWSD05MMC_PVVX_BTHOME", - "tag":"0102", - "condition":["servicedata", "=", 20, "index", 0, "40", "&", "uuid", "index", 0, "fcd2", "&", "name", "index", 0, "ATC"], - "properties":{ - "packet":{ - "condition":["servicedata", 2, "00"], + }, + "packet_2":{ + "condition":["servicedata", 2, "00", "&", "servicedata", "=", 20], "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false] }, "volt":{ - "condition":["servicedata", 6, "0c"], + "condition":["servicedata", 6, "0c", "&", "servicedata", "=", 20], "decoder":["value_from_hex_data", "servicedata", 8, 4, true, false], "post_proc":["/", 1000] }, "power":{ - "condition":["servicedata", 12, "10"], + "condition":["servicedata", 12, "10", "&", "servicedata", "=", 20], "decoder":["value_from_hex_data", "servicedata", 14, 2, false, false] }, - "opening":{ - "condition":["servicedata", 16, "11"], + "open":{ + "condition":["servicedata", 16, "11", "&", "servicedata", "=", 20], "decoder":["value_from_hex_data", "servicedata", 18, 2, false, false] } } @@ -143,11 +131,11 @@ const char* _LYWSD03MMC_json_PVVX_BTHOME_2 = "{\"brand\":\"Xiaomi\",\"model\":\" const char* _LYWSD03MMC_json_props = _common_BVTH_props; -const char* _LYWSD03MMC_BTHOME_1_json_props = "{\"properties\":{\"packet\":{\"unit\":\"int\",\"name\":\"packet id\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +const char* _LYWSD03MMC_BTHOME_json_props = "{\"properties\":{\"packet_1\":{\"unit\":\"int\",\"name\":\"packet id\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"packet_2\":{\"unit\":\"int\",\"name\":\"packet id\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"power\":{\"unit\":\"int\",\"name\":\"power\"},\"open\":{\"unit\":\"int\",\"name\":\"open\"}}}"; /*R""""( { "properties":{ - "packet":{ + "packet_1":{ "unit":"int", "name":"packet id" }, @@ -162,15 +150,8 @@ const char* _LYWSD03MMC_BTHOME_1_json_props = "{\"properties\":{\"packet\":{\"un "batt":{ "unit":"%", "name":"battery" - } - } -})"""";*/ - -const char* _LYWSD03MMC_BTHOME_2_json_props = "{\"properties\":{\"packet\":{\"unit\":\"int\",\"name\":\"packet id\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"power\":{\"unit\":\"int\",\"name\":\"power\"},\"opening\":{\"unit\":\"int\",\"name\":\"opening\"}}}"; -/*R""""( -{ - "properties":{ - "packet":{ + }, + "packet_2":{ "unit":"int", "name":"packet id" }, @@ -182,9 +163,9 @@ const char* _LYWSD03MMC_BTHOME_2_json_props = "{\"properties\":{\"packet\":{\"un "unit": "int", "name": "power" }, - "opening": { + "open": { "unit": "int", - "name": "opening" + "name": "open" } } })"""";*/ diff --git a/tests/BLE/test_ble.cpp b/tests/BLE/test_ble.cpp index f5aae6653..919dd16ea 100644 --- a/tests/BLE/test_ble.cpp +++ b/tests/BLE/test_ble.cpp @@ -371,8 +371,8 @@ const char* expected_uuid_name_svcdata[] = { "{\"brand\":\"Sensor Easy\",\"model\":\"SE MAG\",\"model_id\":\"SE_MAG\",\"type\":\"CTMO\",\"open\":false,\"cont\":true}", "{\"brand\":\"SwitchBot\",\"model\":\"Outdoor Meter\",\"model_id\":\"W340001X\",\"type\":\"THB\",\"batt\":65}", "{\"brand\":\"Tuya\",\"model\":\"THB1 Thermo-Hygrometer\",\"model_id\":\"THB1\",\"type\":\"THB\",\"acts\":true,\"packet\":239,\"tempc\":17.94,\"tempf\":64.292,\"hum\":60.72,\"batt\":74,\"volt\":2.748}", - "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX_BTHOME\",\"type\":\"THB\",\"acts\":true,\"packet\":132,\"tempc\":20.79,\"tempf\":69.422,\"hum\":71.88,\"batt\":100}", - "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX_BTHOME\",\"type\":\"THB\",\"acts\":true,\"packet\":129,\"volt\":3.034,\"power\":1,\"opening\":1}", + "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX_BTHOME\",\"type\":\"THB\",\"acts\":true,\"packet_1\":132,\"tempc\":20.79,\"tempf\":69.422,\"hum\":71.88,\"batt\":100}", + "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX_BTHOME\",\"type\":\"THB\",\"acts\":true,\"packet_2\":129,\"volt\":3.034,\"power\":1,\"open\":1}", "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX_BTHOME_ENCR\",\"type\":\"THB\",\"acts\":true,\"encr\":2,\"cipher\":\"be07860de133b342\",\"ctr\":\"23020000\",\"mic\":\"50dea27d\"}", "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX_BTHOME_ENCR\",\"type\":\"THB\",\"acts\":true,\"encr\":2,\"cipher\":\"613c80e969f052\",\"ctr\":\"a9000000\",\"mic\":\"77b39384\"}", }; @@ -1301,8 +1301,8 @@ TheengsDecoder::BLE_ID_NUM test_uuid_name_svcdata_id_num[]{ TheengsDecoder::BLE_ID_NUM::SE_MAG, TheengsDecoder::BLE_ID_NUM::SBOT_S, TheengsDecoder::BLE_ID_NUM::THB1, - TheengsDecoder::BLE_ID_NUM::LYWSD03MMC_PVVX_BTHOME_1, - TheengsDecoder::BLE_ID_NUM::LYWSD03MMC_PVVX_BTHOME_2, + TheengsDecoder::BLE_ID_NUM::LYWSD03MMC_PVVX_BTHOME, + TheengsDecoder::BLE_ID_NUM::LYWSD03MMC_PVVX_BTHOME, TheengsDecoder::BLE_ID_NUM::LYWSD03MMC_PVVX_BTHOME_1_ENCR, TheengsDecoder::BLE_ID_NUM::LYWSD03MMC_PVVX_BTHOME_2_ENCR, };