home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
73.43k stars 30.67k forks source link

Add support for Xiami Mi Smart Scales to Xiaomi BLE integration #87791

Closed jant90 closed 1 year ago

jant90 commented 1 year ago

The problem

Could support for the various Bluetooth bathroom scales by Xiaomi be added to the Xiaomi BLE integration? Known model numbers are: XMTZC01HM, XMTZC04HM, XMTZC02HM, XMTZC05HM.

While it should, the Passive BLE Monitor integration (HACS) doesn't support my scale either (Mi Body Composition Scale 2, model XMTZC05HM). So currently the only way to read out my scale is by using the ESPHome Miscale integration which is not ideal when we could use the more reliable Bluetooth proxies setup and have the device directly in HA.

What version of Home Assistant Core has the issue?

core-2023.2.3

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant OS

Integration causing the issue

Xiaomi BLE

Link to integration documentation on our website

https://www.home-assistant.io/integrations/xiaomi_ble/

Diagnostics information

No response

Example YAML snippet

No response

Anything in the logs that might be useful for us?

No response

Additional information

No response

home-assistant[bot] commented 1 year ago

Hey there @jc2k, @ernst79, mind taking a look at this issue as it has been labeled with an integration (xiaomi_ble) you are listed as a code owner for? Thanks!

Code owner commands Code owners of `xiaomi_ble` can trigger bot actions by commenting: - `@home-assistant close` Closes the issue. - `@home-assistant rename Awesome new title` Change the title of the issue. - `@home-assistant reopen` Reopen the issue. - `@home-assistant unassign xiaomi_ble` Removes the current integration label and assignees on the issue, add the integration domain after the command.

(message by CodeOwnersMention)


xiaomi_ble documentation xiaomi_ble source (message by IssueLinks)

Ernst79 commented 1 year ago

It is on my todo list. But question is why it doesn’t work in BLE monitor. Perhaps create an issue with some logs in the ble monitor github first, to fix that first

taha-yassine commented 1 year ago

Any ETA on when this will be availble? :)

Ernst79 commented 1 year ago

Unfortunately not. It’s still on my todo list, but family heath issues are keeping me busy. I keep it on the todolist, as long as nobody else picks this up.

taha-yassine commented 1 year ago

Unfortunately not. It’s still on my todo list, but family heath issues are keeping me busy. I keep it on the todolist, as long as nobody else picks this up.

Understandable. I hope things get better for you!

overlord-space commented 1 year ago

Hello!

I tried adding support for the Mi Body Composition Scale 2 [XMTZC05HM]. Although I'm not very proficient in Python and Home Assistant, I managed to achieve a working result. Source code: https://github.com/overlord-space/xiaomi-ble/tree/miscale

To make it work, you also need to add the following changes to the files:

xiaomi_ble/manifest.json

[[source file]](https://github.com/home-assistant/core/blob/dev/homeassistant/components/xiaomi_ble/manifest.json) add in `bluetooth` section: ```json { "connectable": false, "service_data_uuid": "0000181b-0000-1000-8000-00805f9b34fb" } ``` ![CleanShot 2023-07-16 at 02 50 52@2x](https://github.com/home-assistant/core/assets/7531551/d3eca74b-6cca-479b-98a5-7602006f37ec)

xiaomi_ble/sensor.py

[[source file]](https://github.com/home-assistant/core/blob/dev/homeassistant/components/xiaomi_ble/sensor.py) add import `UnitOfMass` from `homeassistant.const` and add inside `SENSOR_DESCRIPTIONS`: ```python (DeviceClass.MASS, Units.MASS_KILOGRAMS): SensorEntityDescription( key=f"{DeviceClass.MASS}_{Units.MASS_KILOGRAMS}", device_class=SensorDeviceClass.WEIGHT, native_unit_of_measurement=UnitOfMass.KILOGRAMS, state_class=SensorStateClass.MEASUREMENT, ), (DeviceClass.MASS, Units.MASS_POUNDS): SensorEntityDescription( key=f"{DeviceClass.MASS}_{Units.MASS_POUNDS}", device_class=SensorDeviceClass.WEIGHT, native_unit_of_measurement=UnitOfMass.POUNDS, state_class=SensorStateClass.MEASUREMENT, ), ``` ![CleanShot 2023-07-16 at 02 54 42@2x](https://github.com/home-assistant/core/assets/7531551/84ad36e4-4a42-44dc-af06-22b63a064ac0)

I successfully tested these changes on my device. If the code looks OK, I can submit a Pull Request. Or this can be helpful for a new implementation.

Ernst79 commented 1 year ago

Sure, it is always good to have this implemented. Please note that some of the MiScales also send impedance as measurement.

overlord-space commented 1 year ago

My modification should be compatible with the following models: XMTZC02HM, XMTZC05HM, NUN4049CN. It seems that they all transmit data in the same format and have the same service UUID.

Not covered only two models: XMTZC01HM, XMTZC04HM (v1, both of them do not transmit impedance).

Currently, there are a few issues:

Ernst79 commented 1 year ago

I propose we add the xiaomi devices to https://github.com/Bluetooth-Devices/xiaomi-ble. That will keep all decoding in the same location. The Xiaomi-ble parser already has a device that is using a different service UUID (HHCC) than the other Xiaomi devices, so we can add it in a similar way.

https://github.com/Bluetooth-Devices/xiaomi-ble/blob/fc8adf0ec1743d265a6617d73554da8fad0b3537/src/xiaomi_ble/parser.py#L1276

Ernst79 commented 1 year ago

@overlord-space Your changes have been added in xiaomi-ble 0.18.0.

https://github.com/Bluetooth-Devices/xiaomi-ble/releases/tag/v0.18.0

Ernst79 commented 1 year ago

@overlord-space Isn't impedance measured in Ohm? You now have it in %.

https://github.com/custom-components/ble_monitor/blob/dc24c0480cfc7a2712856a81dc627b1d6933e39a/custom_components/ble_monitor/const.py#L950C36-L950C41

Ernst79 commented 1 year ago

Created another update for xiaomi-ble. to use sensor-state-data predefined sensors. Had a discussing about the word weight, but it is better to use mass, to be in line with HA sensor definitions. I have the PR for HA almost ready, will create a PR probably tomorrow.

Ernst79 commented 1 year ago

@overlord-space can you do a real life test with the changes in PR #96807 for me?

overlord-space commented 1 year ago

@Ernst79 Works well, only one issue: empty prompt on device configuring.

Details

CleanShot 2023-07-18 at 18 53 34@2x

And I think it would be good to set the omega icon (mdi:omega) for impedance sensor by default.

overlord-space commented 1 year ago

Regarding the use of the word "mass" instead of "weight" and "Ohm" instead of percentages: I found the term SensorDeviceClass.WEIGHT in the documentation, but I couldn't find the corresponding constants for weight and Ohms in the current version of sensor-state-data library. Therefore, I used the constants for mass and percentages.

P.S. Now I see that you have updated the library version

Ernst79 commented 1 year ago

I have added the omega icon. Regarding the empty prompt. could you try that again (delete scale, restart HA and install it again. Make sure you refresh your browser a couple of times (F5) on beforehand. I suspect it is a cache issue in the browser. I can't check it myself for a MiScale, as I don't have one, but the other Xiaomi sensors work ok. Afaik there is no change needed in the code, at least while adding the hhcc sensors, it wasn't needed.

image https://github.com/home-assistant/core/pull/82069/files#diff-3d303380e68411152170f077392fb9e9a4b7df35cc17083fdafc1f68af1233ee

overlord-space commented 1 year ago

Regarding the icon - I tested it, everything is OK

Description does not appear even after clearing browser cache and restarting HA

Video

https://github.com/home-assistant/core/assets/7531551/1bad0e8a-8582-4a09-8955-45302f14b3f4

Ernst79 commented 1 year ago

Clear, I will check with the HA devs what I have missed.

Ernst79 commented 1 year ago

I have checked it with a HA developer

If you test the PR as a custom component you need to run the following first and copy the translations file into the custom component

python3 -m script.translations develop --all

Ernst79 commented 1 year ago

@overlord-space. Support for the V2 scales is merged into development. One question, in BLE monitor, I had a check build in to check that the weight isn't removed

weight_removed = control_byte_2 & (1 << 7)

I remember that was to prevent getting 0 kg as a weight, after you step off the scale. So, I only report (stabilized) mass/weight if the scale is stabilized and the weight is not removed from the scale (person is still standing on the scale). Shouldn't we add that to xiaomi-ble?

    elif device_type == "Mi Scale V2":
        if is_stabilized and (weight_removed == 0):
            result.update({"stabilized weight": weight})

If you want, I can include it for you, but I'm not sure to get the same info flag from the control bytes. In BLE monitor, I looked at the individual control bytes control_byte_2 & (1 << 7). I guess, in your combined control flags, this becomes bool(int(control_flags[8])), is that correct?

BTW, I'm working of MiScale V1 support right now. https://github.com/Bluetooth-Devices/xiaomi-ble/pull/54

overlord-space commented 1 year ago

@Ernst79 Yes, this is control_flags[8]. However, I would like to clarify that during the testing, I have never received an advertisement in which this flag differed from the weight_stabilized flag. Additionally, it seems to me that weight_stabilized cannot possibly be set to true if the scales do not detect any weight upon them.

all control flags

``` bit 0: unused bit 1: unused bit 2: unused bit 3: unused bit 4: unused bit 5: partial data bit 6: unused bit 7: weight sent in pounds bit 8: finished (is there any load on the scale) bit 9: weight sent in catty bit 10: weight stabilized bit 11: unused bit 12: unused bit 13: unused bit 14: impedance stabilized bit 15: unused ```

Ernst79 commented 1 year ago

This issue explains why we implemented it. There are some wrong measurements sometimes with weight removed = true, stabilized = true sometimes.

https://github.com/custom-components/ble_monitor/issues/366

I think I will add the same logic for now, to prevent similar issues as we had back than.

overlord-space commented 1 year ago

Okay

I would like to inquire whether it is possible to address the issue of preserving measurement state. The scales only send a measurement advertisement at the moment of weighing and then turn off. HA changes the all sensor status to Unavailable after approximately 20-40 minutes. Is it possible to resolve this problem?

Details

![CleanShot 2023-07-22 at 19 14 19@2x](https://github.com/home-assistant/core/assets/7531551/baa9179b-ab37-44a3-ba3b-ea9ef977c132)

Ernst79 commented 1 year ago

Hmmm, it should stay available, as we have said that it is a sleepy device. Did you restart HA when it went to unavailable?, as I know a restart will cause it to go to unavailable. It should not go to unavailable after 20-40 minutes, if that is the case, it’s a bug.

Ernst79 commented 1 year ago

Ah, I found the issue, there are only binary sensors that are sleepy. I’ll add the normal sensors as well.

Ernst79 commented 1 year ago

PR for MiScale V1 is ready. I'll fix the unavailable state in a separate PR, as this is a general issue for all xiaomi-ble sensors.