From 204a859871b746416741c59042948752fcb41950 Mon Sep 17 00:00:00 2001 From: Eric Swanson Date: Wed, 29 Oct 2025 18:09:00 -0400 Subject: [PATCH 1/2] Add Eufy T9146 decoder Missing BMI data --- src/devices.h | 2 ++ src/devices/T9146_json.h | 40 ++++++++++++++++++++++++++++++++ tests/python_ble/decoder_test.py | 10 +++++++- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/devices/T9146_json.h diff --git a/src/devices.h b/src/devices.h index 7763e683e..282b8c0a5 100644 --- a/src/devices.h +++ b/src/devices.h @@ -139,6 +139,7 @@ #include "devices/SBHT_003C_json.h" #include "devices/SBHT_003C_ENCR_json.h" #include "devices/VCH6003_json.h" +#include "devices/T9146_json.h" const char* _devices[][2] = { @@ -289,4 +290,5 @@ const char* _devices[][2] = { {_SBHT_003C_json, _SBHT_003C_json_props}, {_SBHT_003C_ENCR_json, _SBHT_003C_ENCR_json_props}, {_VCH6003_json, _VCH6003_json_props}, + {_T9146_json, _T9146_json_props}, }; diff --git a/src/devices/T9146_json.h b/src/devices/T9146_json.h new file mode 100644 index 000000000..51af45308 --- /dev/null +++ b/src/devices/T9146_json.h @@ -0,0 +1,40 @@ +const char* _T9146_json = "{\"brand\":\"eufy\",\"model\":\"Smart Scale C1\",\"model_id\":\"T9146\",\"tag\":\"05\",\"condition\":[\"manufacturerdata\",\"index\",0,\"cfe50c\",\"&\",\"name\",\"contain\",\"eufy T9146\"],\"properties\":{\"weighing_mode\":{\"decoder\":[\"static_value\",\"person\"]},\"unit\":{\"decoder\":[\"static_value\",\"kg\"]},\"weight\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",18,4,true,false],\"post_proc\":[\"/\",100]}}}"; +/*R""""( +{ + "brand":"eufy", + "model":"Smart Scale C1", + "model_id":"T9146", + "tag":"05", + "condition":["manufacturerdata", "index", 0, "cfe50c", "&", "name", "contain", "eufy T9146"], + "properties":{ + "weighing_mode":{ + "decoder":["static_value", "person"] + }, + "unit":{ + "decoder":["static_value", "kg"] + }, + "weight":{ + "decoder":["value_from_hex_data", "manufacturerdata", 18, 4, true, false], + "post_proc":["/", 100] + } + } +})"""";*/ + +const char* _T9146_json_props = "{\"properties\":{\"weighing_mode\":{\"unit\":\"string\",\"name\":\"weighing_mode\"},\"unit\":{\"unit\":\"string\",\"name\":\"unit\"},\"weight\":{\"unit\":\"kg\",\"name\":\"weight\"}}}"; +/*R""""( +{ + "properties":{ + "weighing_mode":{ + "unit":"string", + "name":"weighing_mode" + }, + "unit":{ + "unit":"string", + "name":"unit" + }, + "weight":{ + "unit":"kg", + "name":"weight" + } + } +})"""";*/ diff --git a/tests/python_ble/decoder_test.py b/tests/python_ble/decoder_test.py index 4e21f5b7d..32ddb640d 100644 --- a/tests/python_ble/decoder_test.py +++ b/tests/python_ble/decoder_test.py @@ -4,6 +4,14 @@ import json x = {"servicedata":"712098004a63b6658d7cc40d071003f32600"} +x = { + "id": "CF:E5:0C:03:01:EC", + "mac_type": 0, + "adv_type": 0, + "name": "eufy T9146", + "manufacturerdata": "cfe50c0301eccf0000460500000001008d5d9146", + "rssi": -61 +} z = dble(json.dumps(x)) print(z, "\n") @@ -16,4 +24,4 @@ y = {} z = dble(json.dumps(y)) print("decoder result (None expected): ", z) -print("Done") \ No newline at end of file +print("Done") From fafd9736f99752cb1c331d66af4147aae76fb351 Mon Sep 17 00:00:00 2001 From: Eric Swanson Date: Wed, 29 Oct 2025 18:19:58 -0400 Subject: [PATCH 2/2] Just kidding, it works now --- src/devices/T9146_json.h | 7 ++++++- tests/python_ble/decoder_test.py | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/devices/T9146_json.h b/src/devices/T9146_json.h index 51af45308..7c5c5bb04 100644 --- a/src/devices/T9146_json.h +++ b/src/devices/T9146_json.h @@ -5,7 +5,7 @@ const char* _T9146_json = "{\"brand\":\"eufy\",\"model\":\"Smart Scale C1\",\"mo "model":"Smart Scale C1", "model_id":"T9146", "tag":"05", - "condition":["manufacturerdata", "index", 0, "cfe50c", "&", "name", "contain", "eufy T9146"], + "condition":["manufacturerdata", "index", 0, "cf", "manufacturerdata", "index", 12, "cf", "&", "name", "contain", "eufy T9146"], "properties":{ "weighing_mode":{ "decoder":["static_value", "person"] @@ -19,6 +19,11 @@ const char* _T9146_json = "{\"brand\":\"eufy\",\"model\":\"Smart Scale C1\",\"mo } } })"""";*/ +// manufacturerdata starts with the mac address (6 bytes / 12 hex chars) +// then constant "cf" plus 13 more bytes / 26 more chars +// total length is 40 chars / 20 bytes +// weight is encoded in hex char position 18 to 22, little endian, as 100ths of kg +// for example, cfe50c0301eccfa2128c232624540100874a9146 => 8c23 => 0x238c => 91.00 kg const char* _T9146_json_props = "{\"properties\":{\"weighing_mode\":{\"unit\":\"string\",\"name\":\"weighing_mode\"},\"unit\":{\"unit\":\"string\",\"name\":\"unit\"},\"weight\":{\"unit\":\"kg\",\"name\":\"weight\"}}}"; /*R""""( diff --git a/tests/python_ble/decoder_test.py b/tests/python_ble/decoder_test.py index 32ddb640d..5b9ba67d8 100644 --- a/tests/python_ble/decoder_test.py +++ b/tests/python_ble/decoder_test.py @@ -9,7 +9,7 @@ "mac_type": 0, "adv_type": 0, "name": "eufy T9146", - "manufacturerdata": "cfe50c0301eccf0000460500000001008d5d9146", + "manufacturerdata": "cfe50c0301eccfa2128c232624540100874a9146", "rssi": -61 } z = dble(json.dumps(x))