1technophile / OpenMQTTGateway

MQTT gateway for ESP8266 or ESP32 with bidirectional 433mhz/315mhz/868mhz, Infrared communications, BLE, Bluetooth, beacons detection, mi flora, mi jia, LYWSD02, LYWSD03MMC, Mi Scale, TPMS, BBQ thermometer compatibility & LoRa.
https://docs.openmqttgateway.com
GNU General Public License v3.0
3.5k stars 775 forks source link

Support Eufy T9146 smart scale #1706

Open lachesis opened 1 year ago

lachesis commented 1 year ago

Is your feature request related to a problem? Please describe. I have an Eufy Smart Scale C1 (amazon link). This scale reports weight to a phone app using BLE advertisements. My BTtoMQTT instance of this project cannot parse those advertisements, only returning JSON like {"id": "X:X:X", "name":"eufy T9146","rssi":-89}.

Describe the solution you'd like I'd like to see this device supported in OpenMQTTGateway.

Describe alternatives you've considered I considered setting up a Home Assistant instance or using a Raspberry Pi to read these advertisements using either eufylife-ble-client or the EufyLife_ble HA integration

Additional context I'm happy to help with this by providing raw captures of the messages or by writing the code myself if you can suggest a good client to pattern it after.

DigiH commented 1 year ago

Hi @lachesis

Could you turn on advanced/advertising data so that the JSON does include the undecoded raw data for us to look at on how to decode them?

Thanks

lachesis commented 11 months ago

Certainly, here is the message. Sorry it took me so long to reply.

{
  "id": "CF:E5:0C:03:01:EC",
  "mac_type": 0,
  "adv_type": 0,
  "name": "eufy T9146",
  "manufacturerdata": "cfe50c0301eccf2413122560655a0100914a9146",
  "rssi": -83
}

This scale returned a weight measurement around 209 lbs for that. I need less time in the lab and more on the track. ;)

DigiH commented 11 months ago

Thanks for the sample message with the manufacturerdata. With looking at some of your posted links above

cfe50c0301eccf2413 1225 60655a0100914a9146

1225 little endian 2512 hex = decimal 9490 / 100 = 94.9 kg = 209.2187 lb

So the weight is easily decodable, especially also with the final/exceeded weight options

is_final = data[9] == 0x00 (as reported in your sample) weight_limit_exceeded = data[9] == 0x02

So it seems the weight is always reported as kg, so we would also have to look into which bit or byte contains the metric/imperial setting information.

Also the impedance, required for a correct BMI and other body composition value calculations does seem to be commented out or missing from the given examples, but would be good to also catch for a complete decoder.

If you are interested in creating and submitting your own decoder you could take the existing Xiaomi Mi Scales decoders as a starting point, together with the submitting decoders documentation, or we can work on it together with more samples with different settings for the scale.

You can have a look and test with my initial Eufy C1/P1 decoder branch

https://github.com/DigiH/decoder/tree/eufy

lachesis commented 11 months ago

I was impatient and stepped off the scale before it measured BMI. Here is another capture which should contain impedance data. The weight reported by the scale was 209.8 lbs this time, but I don't know what was reported for impedance.

{"id":"CF:E5:0C:03:01:EC","mac_type":0,"adv_type":0,"name":"eufy T9146","manufacturerdata":"cfe50c0301eccf0a143a257975ed01002e4a9146","rssi":-80}
DigiH commented 11 months ago

How do you use OpenMQTTGateway? Can you make you own build with PlatformIO?

So far there are several differences (black) and identical bytes (light grey) with the two readings you made so far, with the weight (orange) and is_final (blue)

Screenshot 2023-07-20 at 19 37 45

One of the next steps to find out, is the setting for kg or lb, best with a steady object - gallon of milk or something, and switching the scale setting to kg in the app, get a JSON reading, the with the same object setting the scale to lb and have the JSON readin, to compare which bit/byte signifies the kg/lb display.

lachesis commented 11 months ago

I don't actually have the app. I can indeed build and flash using PlatformIO.

On Thu, Jul 20, 2023, 13:39 DigiH @.***> wrote:

How do you use OpenMQTTGateway? Can you make you own build with PlatformIO?

So far there are several differences (black) and identical bytes (light grey) with the two readings you made so far, with the weight (orange) and is_final (blue) [image: Screenshot 2023-07-20 at 19 37 45] https://user-images.githubusercontent.com/17110652/254963601-93ac132e-458d-4e32-8b73-bc0d6eb1358f.png

One of the next steps to find out, is the setting for kg or lb, best with a steady object - gallon of milk or something, and switching the scale setting to kg in the app, get a JSON reading, the with the same object setting the scale to lb and have the JSON readin, to compare which bit/byte signifies the kg/lb display.

— Reply to this email directly, view it on GitHub https://github.com/1technophile/OpenMQTTGateway/issues/1706#issuecomment-1644329948, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACU2WIO36CPNZVZSNB3RN3XRFUOTANCNFSM6AAAAAAZ3QPYDM . You are receiving this because you were mentioned.Message ID: @.***>

DigiH commented 11 months ago

Not the app, but If you build with PlatformIO for your ESP32 with which you got the above JSON messages you can change the current default decoder library reference

decoder = https://github.com/theengs/decoder.git#v1.5.7

to

decoder = https://github.com/DigiH/decoder.git#eufy

in platformio.ini to test my current branch, along with any additions I make after we find out more decoding details with the above suggested trials.

lachesis commented 11 months ago

I will try this tonight. Apparently my OTA updates are not working, so I'll need to go home and pull the board off the wall to flash it.

DigiH commented 11 months ago

No worries, or you can also let me know your OTA set up, as I am always doing OTA updates as well though PlatformIO. Might be something obvious.

Either way, if you use the Eufy branch, the next step would be the switching to kg and then lb, with both readings with the same static weight, so we can determine the unit bit/byte to allow for the appropriate weight and unit to be published as a next step.

lachesis commented 11 months ago

I found another generic ESP32-WROOM-32 board lying around and flashed it to a build with your fork of decoder library, using the following environment:

[env:esp32dev-ble-mine]
platform = ${com.esp32_platform}
board = esp32dev
board_build.partitions = min_spiffs.csv
lib_deps =
  ${com-esp32.lib_deps}
  ${libraries.ble}
  ${libraries.decoder}
build_flags =
  ${com-esp32.build_flags}
  '-DZgatewayBT="BT"'
  '-DLED_SEND_RECEIVE=2'
  '-DLED_SEND_RECEIVE_ON=0'
  '-DESPWifiManualSetup=true'
  '-Dwifi_ssid="mywifissid"'
  '-Dwifi_password="mywifipassword"'
  '-Dota_hostname="esp-garage"'
  '-DMQTT_SERVER="192.168.0.2"'
  '-DGateway_Name="OMG_ESP32_BLE"'
custom_description = Regular BLE gateway with adaptive scanning activated, automatically adapts the scan parameters depending on your devices

Weight decodes apparently correctly. Here is an example message from the scale:

 {
  "id": "CF:E5:0C:03:01:EC",
  "mac_type": 0,
  "adv_type": 0,
  "name": "eufy T9146",
  "manufacturerdata": "cfe50c0301eccfa2128c232624540100874a9146",
  "rssi": -92,
  "brand": "Eufy",
  "model": "Smart Scale",
  "model_id": "C1/P1",
  "type": "SCALE",
  "cidc": false,
  "weight": 91,
  "mac": "CF:E5:0C:03:01:EC"
}

Only weight and manufacturerdata varied throughout the runs. Here is a table of some values:

weight manufacturerdata
91 cfe50c0301eccfa2128c232624540100874a9146
94 cfe50c0301eccfa212b824ebe77401009a4a9146
94 cfe50c0301eccfac12b824a0a6460100ac4a9146

I meant to do some more in-depth experiments with different weights, but life got in the way. Additionally, I do not have the Eufy app, so I cannot switch the scale between lbs and kg. It is currently displaying lbs on the led display.

DigiH commented 11 months ago

Thanks for the further tests.

I have uploaded some changes with the unit bit set to what i think it might be, but for a final decoder it would really need to be verified with actual data and tests.

Additionally, I do not have the Eufy app, so I cannot switch the scale between lbs and kg.

Any chance of getting the app to verify the unit change witch with my above extrapolated changes? Or might it be possible to switch between kg and lb on the scale itself?

The same for the impedance, which I think is the two octets before the weight from your above additional data, but would need additional verification as well.

You can just rebuild and flash and my submitted changes should show up.

Also might there be a battery level inidcator on the scale itself or in the app? Could it be at 75%?

lachesis commented 11 months ago

My wife has the app. I will try to get her help in testing these various settings this week.

github-actions[bot] commented 10 months ago

This issue is stale because it has been open for 30 days with no activity.