Which scale do you have exactly?
Mi Smart Scale 1 / Mi Smart Scale 2 do not send impedance. (Xiaomi XMTZC01HM, XMTZC04HM)
Mi Body Composition Scale 2 / Mi Body Fat Scale do send impedance.(Xiaomi XMTZC02HM, XMTZC05HM, NUN4049CN)
Which scale do you have exactly?
Mi Smart Scale 1 / Mi Smart Scale 2 do not send impedance. (Xiaomi XMTZC01HM, XMTZC04HM)
Mi Body Composition Scale 2 / Mi Body Fat Scale do send impedance.(Xiaomi XMTZC02HM, XMTZC05HM, NUN4049CN)
It’s the body composition scale 2, XMTZC05HM. The app works and calculates the impedance based metrics. Any idea what might be going on?
No, no idea. Does it work in BLE monitor?
I don’t use BLE monitor. I use Esphome. I was able to change the defaults there to limit the risk of missing the value:
esp32_ble_tracker:
scan_parameters:
# default is 320ms:
interval: 80ms
# default is 30ms:
window: 60ms
Hi @e-raser . Did you manage to find a solution? I have a similar setup to you, and cannot figure it out. Any help will be appreciated.
In this topic - which started looking to integrate another Bluetooth device - I also try to get the Mi Scale weight as sensor:
As long as it is not available for the native Bluetooth integration, this would be fine for me.
In case anyone benefits from this (BLE (data coming in unsorted) > split by user > BodyMiScale (one device for each users)), if You want to have 2 or more users You can create two sensor templates like this and just fill in the correct one based on the weight:
- platform: template
sensors:
filtered_weight_andris:
friendly_name: "Filtered weight Andris"
unit_of_measurement: "kg"
value_template: >
{{ states.sensor.ble_weight_mi_scale2.state if ((states.sensor.ble_weight_mi_scale2.state) | int) > 68 }}
- platform: template
sensors:
filtered_impedance_andris:
friendly_name: "Filtered inpedance Andris"
unit_of_measurement: "Ω"
value_template: >
{{ states.sensor.ble_impedance_mi_scale2.state if ((states.sensor.ble_weight_mi_scale2.state) | int) > 68 }}
- platform: template
sensors:
filtered_weight_niki:
friendly_name: "Filtered weight Niki"
unit_of_measurement: "kg"
value_template: >
{{ states.sensor.ble_weight_mi_scale2.state if ((states.sensor.ble_weight_mi_scale2.state) | int) < 68 }}
- platform: template
sensors:
filtered_impedance_niki:
friendly_name: "Filtered inpedance Niki"
unit_of_measurement: "Ω"
value_template: >
{{ states.sensor.ble_impedance_mi_scale2.state if ((states.sensor.ble_weight_mi_scale2.state) | int) < 68 }}
So I just have the Passive BLE monitor providing me the above weight and impedance values which I turn into two template sensors each (based on above or below 68), which in return are used as the weight and imp. source for the BodyMyScale integration (so the resulting 2x2 entries become the data feed of the BodyMiScale).
Some extra info on where to put that code would be welcomed.
do we put that into sensors.yaml?
in configuration.yaml?
do we have to alter something in bodymiscale?
I put it in configuration.yaml.
No altering is needed.
BodyMiScale requires a weight and an impedance sensor value to work. Normally You would add the sensor data (weight/impedance) coming from the BLE sensor. But if You create (with the above code) 2 template sensors (just like the original), then You basically mimic the BLE output, You create two pairs of very similar sensors. These template sensors can then provide the input to two MiBodyScale instances. See here:
Thanks for answering man. I have it working a couple of days now but it gets errors in the logs sometimes and also it is like this is not a real sensor somehow. Like its a float that get erased after restart.
some of the errors
Error doing job: Exception in callback _async_at_core_state.<locals>._matched_event(<Event homeassistant_start[L]>) at /usr/src/homeassistant/homeassistant/helpers/start.py:37
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 616, in state
numerical_value = int(value)
^^^^^^^^^^
ValueError: invalid literal for int() with base 10: ''
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 619, in state
numerical_value = float(value)
^^^^^^^^^^^^
ValueError: could not convert string to float: ''
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.11/asyncio/events.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "/usr/src/homeassistant/homeassistant/core.py", line 1236, in _onetime_listener
self._hass.async_run_job(listener, event)
File "/usr/src/homeassistant/homeassistant/core.py", line 719, in async_run_job
return self.async_run_hass_job(HassJob(target), *args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 671, in async_run_hass_job
hassjob.target(*args)
File "/usr/src/homeassistant/homeassistant/helpers/start.py", line 40, in _matched_event
hass.async_run_hass_job(at_start_job, hass)
File "/usr/src/homeassistant/homeassistant/core.py", line 671, in async_run_hass_job
hassjob.target(*args)
File "/usr/src/homeassistant/homeassistant/components/template/template_entity.py", line 478, in _async_template_startup
result_info.async_refresh()
File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 1035, in async_refresh
self._refresh(None)
File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 1215, in _refresh
self.hass.async_run_hass_job(self._job, event, updates)
File "/usr/src/homeassistant/homeassistant/core.py", line 671, in async_run_hass_job
hassjob.target(*args)
File "/usr/src/homeassistant/homeassistant/components/template/template_entity.py", line 429, in _handle_results
self.async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 745, in async_write_ha_state
self._async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 845, in _async_write_ha_state
state, attr = self._async_generate_attributes()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 786, in _async_generate_attributes
state = self._stringify_state(available)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 751, in _stringify_state
if (state := self.state) is None:
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 623, in state
raise ValueError(
ValueError: Sensor sensor.filtered_weight_gnf has device class 'None', state class 'None' unit 'kg' and suggested precision 'None' thus indicating it has a numeric value; however, it has the non-numeric value: '' (<class 'str'>)
Logger: homeassistant.helpers.event
Source: helpers/event.py:296
First occurred: December 15, 2023 at 12:39:58 (2 occurrences)
Last logged: December 15, 2023 at 12:39:58
Error while dispatching event for sensor.mi_body_composition_scale_7dc3_mass to <Job track state_changed event {'sensor.mi_body_composition_scale_7dc3_mass'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template<template=({{ states.sensor.mi_body_composition_scale_7dc3_mass.state if ((states.sensor.mi_body_composition_scale_7dc3_mass.state) | int) < 60 }}) renders=8>: <RenderInfo Template<template=({{ states.sensor.mi_body_composition_scale_7dc3_mass.state if ((states.sensor.mi_body_composition_scale_7dc3_mass.state) | int) < 60 }}) renders=8> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({'sensor.mi_body_composition_scale_7dc3_mass'}) rate_limit=None has_time=False exception=None is_static=False>}>>>
Error while dispatching event for sensor.mi_body_composition_scale_7dc3_mass to <Job track state_changed event {'sensor.mi_body_composition_scale_7dc3_impedance', 'sensor.mi_body_composition_scale_7dc3_mass'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template<template=({{ states.sensor.mi_body_composition_scale_7dc3_impedance.state if ((states.sensor.mi_body_composition_scale_7dc3_mass.state) | int) < 60 }}) renders=10>: <RenderInfo Template<template=({{ states.sensor.mi_body_composition_scale_7dc3_impedance.state if ((states.sensor.mi_body_composition_scale_7dc3_mass.state) | int) < 60 }}) renders=10> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({'sensor.mi_body_composition_scale_7dc3_mass'}) rate_limit=None has_time=False exception=None is_static=False>}>>>
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 616, in state
numerical_value = int(value)
^^^^^^^^^^
ValueError: invalid literal for int() with base 10: ''
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 619, in state
numerical_value = float(value)
^^^^^^^^^^^^
ValueError: could not convert string to float: ''
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 296, in _async_dispatch_entity_id_event
hass.async_run_hass_job(job, event)
File "/usr/src/homeassistant/homeassistant/core.py", line 671, in async_run_hass_job
hassjob.target(*args)
File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 1215, in _refresh
self.hass.async_run_hass_job(self._job, event, updates)
File "/usr/src/homeassistant/homeassistant/core.py", line 671, in async_run_hass_job
hassjob.target(*args)
File "/usr/src/homeassistant/homeassistant/components/template/template_entity.py", line 429, in _handle_results
self.async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 745, in async_write_ha_state
self._async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 845, in _async_write_ha_state
state, attr = self._async_generate_attributes()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 786, in _async_generate_attributes
state = self._stringify_state(available)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 751, in _stringify_state
if (state := self.state) is None:
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 623, in state
raise ValueError(
ValueError: Sensor sensor.filtered_weight_florentia has device class 'None', state class 'None' unit 'kg' and suggested precision 'None' thus indicating it has a numeric value; however, it has the non-numeric value: '' (<class 'str'>)
I am trying to get the new sensor way of home assistant and not the legacy one.
template:
- trigger:
- platform: numeric_state
value_template: "{{ states('sensor.mi_body_composition_scale_7dc3_mass') | float(0) >= 60 }}"
sensor:
- unique_id: filtered_weight_gnf
name: "filtered_weight_gnf"
friendly_name: "Filtered weight GnF"
unit_of_measurement: "kg"
state: "{{ states('sensor.mi_body_composition_scale_7dc3_mass') }}"
- trigger:
- platform: numeric_state
value_template: "{{ states('sensor.mi_body_composition_scale_7dc3_mass') | float(0) >= 60 }}"
sensor:
- unique_id: filtered_impedance_gnf
name: "filtered_impedance_gnf"
friendly_name: "Filtered inpedance GnF"
unit_of_measurement: "Ω"
state: "{{ states('sensor.mi_body_composition_scale_7dc3_impedance') }}"
But i get this error.
Configuration warnings
Invalid config for 'sensor' at configuration.yaml, line 12: required key 'platform' not provided
Hey GnF, I will not be able to help You with so deep tech, I did not check myself if I have errors as long as it works reliable (my system is running now for 4 years, so I have a lot of misconfigs). However as far as I am understanding what we are doing the sensor being reseted at restart is normal (as its just a template being filled out by its input when it arrives), but I think there should be a way to make it non volatile. Sorry that I can not help You further.
really man thanks for even answering.
I will post any finds i have.
this is what i have till now
# sensors.yaml
- platform: template
sensors:
filtered_weight_gnf:
unique_id: filtered_weight_gnf
friendly_name: "Filtered Weight GNF"
unit_of_measurement: "kg"
value_template: >-
{% if states('sensor.mi_body_composition_scale_7dc3_mass') | float > 60 %}
{{ states('sensor.mi_body_composition_scale_7dc3_mass') }}
{% endif %}
filtered_impedance_gnf:
unique_id: filtered_impedance_gnf
friendly_name: "Filtered Impedance GNF"
unit_of_measurement: "ohms"
value_template: >-
{% if states('sensor.mi_body_composition_scale_7dc3_mass') | float > 60 %}
{{ states('sensor.mi_body_composition_scale_7dc3_impedance') }}
{% endif %}
filtered_weight_florentia:
unique_id: filtered_weight_florentia
friendly_name: "Filtered Weight Florentia"
unit_of_measurement: "kg"
value_template: >-
{% if states('sensor.mi_body_composition_scale_7dc3_mass') | float <= 60 %}
{{ states('sensor.mi_body_composition_scale_7dc3_mass') }}
{% endif %}
filtered_impedance_florentia:
unique_id: filtered_impedance_florentia
friendly_name: "Filtered Impedance Florentia"
unit_of_measurement: "ohms"
value_template: >-
{% if states('sensor.mi_body_composition_scale_7dc3_mass') | float <= 60 %}
{{ states('sensor.mi_body_composition_scale_7dc3_impedance') }}
{% endif %}
I did try to use else return to 0 if it does not have a measure or if it looses data but it does not work ok. I will keep trying.
So the above again does not work very well.
Lets say user one and two.
User one uses the scale and all filtered sensors update normaly. Also the card for that user is working.
User two uses the scale and all is well.
If after a day or two user one has not use the scale but user two is keep using it then the card for user two is working normally but the card for user one says unavailable.
Damn
Since the data are stored in a time based db maybe the data from user one are now old? And this integration does not see them?
I have to find a way to keep updating the filtered value on the new sensors on the time even if there are no new data. Damn
Hopefully someone can help me here…
I´ve successfully configured the integration through BLE, and the first weigh-in shows up correctly. But I just cant get it to update with new values when i´m weighing myself again. The Zepp Life app registers new weight but nothing is updated in HA…
Why is this? There´s no error logs either
The signal strength is: -73 dBm. Maybe thats the issue? But the scale is 3 meters away from my raspberry pi
Make sure to keep standing on the scale until the weight-display has switched itself off again.
did that, twice, also restarted HA. No change
Zepp Life registers the changes
Be careful, you cannot be on the Zepp application at the same time.
Dont know what fixed it. I “reinstalled” the Bluetooth integration, then opened the integration and clicked on configure and checked “passive scanning”. Cant say if I had this enabled before.
Having the Zepp app open does, in fact, hinder the information to be sent to HA.
I dont have to wait for the display to switch off. Its enough if I wait until the measurment-bar is fully complete.
Is this still the case?
Meanwhile I integrated it using OMG.
But having it natively with plain „Bluetooth on HA“ would be an improvement.