Intégration Balance connecté Mi Scale via ESPHome

Salut a tous,

Suite au message poster par notre ami @dckiller dans le sujet cidessous et son integration de la balance Miscale 1 et 2 via ESPHome, je vais vous faire un petit tutoriel rapide.

https://forum.hacf.fr/t/integrer-les-balances-xiaomi-mi-scale/

https://esphome.io/components/sensor/xiaomi_miscale2.html

Matériels requis.

  • Extenstion ESPHome (1.17.0).
  • Un ESP 32 avec Bluetooth
  • Une balance Xiaomi Miscale V1 ou V2
  • Récupérer son adresse MAC (au début de cet l’article).

Liens affiliés :

Configuration de l’extension et du matériel.

Lancer ensuite l’extension.

Configurer votre matériel sous ESPHome, puis dans la configuration ajouter ceci.

Config Esphome Miscale 1 (XMTZC01HM & XMTZC04HM)

esp32_ble_tracker:

sensor:
  - platform: xiaomi_miscale
    mac_address: 'XX:XX:XX:XX:XX:XX'
    weight:
      name: "Xiaomi Mi Scale Weight"

Config Esphome Miscale 2 (XMTZC02HM & XMTZC05HM)

esp32_ble_tracker:

sensor:      
  - platform: xiaomi_miscale2
    mac_address: 'XX:XX:XX:XX:XX:XX'
    weight:
      name: "Xiaomi Mi Scale Weight"
    impedance:
      name: "Xiaomi Mi Scale Impedance"

Intégration dans Home Assistant.

Puis dans votre fichier de configuration Home Assistant ajouter ceci (a modifier avec vos infos) :

Explication du fonctionnement.

Vous pouvez régler plusieurs profils avec la notion de poids.

Exemple avec trois utilisateurs.
Anthony poids environs 95Kg
Claire poids environ 60Kg
Agathe poids environ 12Kg

Code dans un packages nommé balance.yaml

sensor:
## Anthony
  - platform: template
    sensors:
      poids_anthony:
        friendly_name: "Poids Anthony"
        value_template: >-
          {% if states('sensor.xiaomi_mi_scale_weight') | float >= 85 and states('sensor.xiaomi_mi_scale_weight') | float <= 99 %}
            {{ states("sensor.xiaomi_mi_scale_weight") }}
          {% else %}
            {{ states("sensor.poids_anthony") }}
          {% endif %}
        unit_of_measurement: 'kg'
        icon_template: mdi:weight-kilogram
  - platform: template
    sensors:
      imc_anthony:
          friendly_name: 'IMC Anthony'
          value_template: >-
            {% set HEIGHT = (1.93)|float %}
            {% set WEIGHT = states('sensor.poids_anthony')|float %}
            {{- (WEIGHT/(HEIGHT*HEIGHT))|float|round(1) -}}
          icon_template: >
            {{ 'mdi:human' }}
  - platform: template
    sensors:
      # Indice de masse corporelle (IMC)	Interprétation (d'après l'OMS)
      imc_anthony_interpretation:
        friendly_name: "Interprétation IMC Anthony"
        value_template: >-
          {% if states("sensor.imc_anthony") | float < 18.4 %}
            Insuffisance pondérale
          {% elif states("sensor.imc_anthony") | float >= 18.5 and states("sensor.imc_anthony") | float <= 25 %}  
            Corpulence normale
          {% elif states("sensor.imc_anthony") | float >= 25.1 and states("sensor.imc_anthony") | float <= 30 %}
            Surpoids
          {% elif states("sensor.imc_anthony") | float >= 30.1 and states("sensor.imc_anthony") | float <= 35 %}  
            Obésité modérée
          {% elif states("sensor.imc_anthony") | float >= 35.1 and states("sensor.imc_anthony") | float <= 40 %}  
            Obésité sévère
          {% else %}  
            Obésité morbide
          {% endif %}
## Claire
  - platform: template
    sensors:
      poids_Claire:
        friendly_name: "Poids claire"
        value_template: >-
          {% if states('sensor.xiaomi_mi_scale_weight') | float >= 60 and states('sensor.xiaomi_mi_scale_weight') | float <= 75 %}
            {{ states("sensor.xiaomi_mi_scale_weight") }}
          {% else %}
            {{ states("sensor.poids_claire") }}
          {% endif %}
        unit_of_measurement: 'kg'
        icon_template: mdi:weight-kilogram
  - platform: template
    sensors:
      imc_Claire:
          friendly_name: 'IMC claire'
          value_template: >-
            {% set HEIGHT = (1.68)|float %}
            {% set WEIGHT = states('sensor.poids_claire')|float %}
            {{- (WEIGHT/(HEIGHT*HEIGHT))|float|round(1) -}}
          icon_template: >
            {{ 'mdi:human' }}
  - platform: template
    sensors:
      # Indice de masse corporelle (IMC)	Interprétation (d'après l'OMS)
      imc_Claire_interpretation:
        friendly_name: "Interprétation IMC claire"
        value_template: >-
          {% if states("sensor.imc_claire") | float < 18.4 %}
            Insuffisance pondérale
          {% elif states("sensor.imc_claire") | float >= 18.5 and states("sensor.imc_claire") | float <= 25 %}  
            Corpulence normale
          {% elif states("sensor.imc_claire") | float >= 25.1 and states("sensor.imc_claire") | float <= 30 %}
            Surpoids
          {% elif states("sensor.imc_claire") | float >= 30.1 and states("sensor.imc_claire") | float <= 35 %}  
            Obésité modérée
          {% elif states("sensor.imc_claire") | float >= 35.1 and states("sensor.imc_claire") | float <= 40 %}  
            Obésité sévère
          {% else %}  
            Obésité morbide
          {% endif %}
## Agathe
  - platform: template
    sensors:
      poids_agathe:
        friendly_name: "Poids agathe"
        value_template: >-
          {% if states('sensor.xiaomi_mi_scale_weight') | float >= 10 and states('sensor.xiaomi_mi_scale_weight') | float <= 20 %}
            {{ states("sensor.xiaomi_mi_scale_weight") }}
          {% else %}
            {{ states("sensor.poids_agathe") }}
          {% endif %}
        unit_of_measurement: 'kg'
        icon_template: mdi:weight-kilogram
  - platform: template
    sensors:
      imc_agathe:
          friendly_name: 'IMC agathe'
          value_template: >-
            {% set HEIGHT = (0.89)|float %}
            {% set WEIGHT = states('sensor.poids_agathe')|float %}
            {{- (WEIGHT/(HEIGHT*HEIGHT))|float|round(1) -}}
          icon_template: >
            {{ 'mdi:human' }}
  - platform: template
    sensors:
      # Indice de masse corporelle (IMC)	Interprétation (d'après l'OMS)
      imc_agathe_interpretation:
        friendly_name: "Interprétation IMC agathe"
        value_template: >-
          {% if states("sensor.imc_agathe") | float < 18.4 %}
            Insuffisance pondérale
          {% elif states("sensor.imc_agathe") | float >= 18.5 and states("sensor.imc_agathe") | float <= 25 %}  
            Corpulence normale
          {% elif states("sensor.imc_agathe") | float >= 25.1 and states("sensor.imc_agathe") | float <= 30 %}
            Surpoids
          {% elif states("sensor.imc_agathe") | float >= 30.1 and states("sensor.imc_agathe") | float <= 35 %}  
            Obésité modérée
          {% elif states("sensor.imc_agathe") | float >= 35.1 and states("sensor.imc_agathe") | float <= 40 %}  
            Obésité sévère
          {% else %}  
            Obésité morbide
          {% endif %}

Lovelace.

Pour la partie lovelace je ne vais pas refaire ce qui existe déjà, je vous propose d’aller voir l’article sur l’intégration de la balance via l’addons.

Trucs & Astuces.

To Do List.

  • Ajouter les liens affiliés.

Mise à jour.

1 « J'aime »

15 messages ont été fusionnés à un sujet existant : Intégrer les balances Xiaomi Mi scale

Slt,

Peux-tu tester ma dernière maj ? Les changements sont :

  1. une plateform pour les deux balance.
  2. Création des utisateurs sur esphome comme ca en cas de reboot de HA les données redescendent après le redémarrage.
  3. Mode Stabilisé afin que la balance envoi les données 1 seul fois quand elle clignotent et plus en permanence pendant 5min

Sur la mienne tout fonctionne bien maintenant j’ai besoin qu’un utilisateur de la 2 test notamment pour l’impédance.

Il faut changer uniquement l’adresse mac, chaque above et below pour déterminer les utilisateurs cela correspond à leur poids (entre x kg et x kg) et changer le Prénom dans name: Poids « Prénom » et name: Impédance « Prénom ».

Pense avant à supprimer tes sensor poids_anthony.,poids_Claire… Tu peux garder les IMC et l’indice corporelle les noms seront ok.

sensor:
  - platform: xiaomi_xmtzc0xhm
    mac_address: 'C8:47:8C:9F:7B:0A'
    weight:
      name: "Xiaomi Mi Scale Weight"
      on_value_range:
        - above: 69
          below: 72.99
          then:
          - lambda: return id(weight_user1).publish_state(x);
        - above: 73
          below: 80
          then:
          - lambda: return id(weight_user2).publish_state(x);
        - above: 46
          below: 60
          then:
          - lambda: return id(weight_user3).publish_state(x);
        - above: 28
          below: 45
          then:
          - lambda: return id(weight_user4).publish_state(x);
        - above: 5
          below: 20
          then:
          - lambda: return id(weight_user5).publish_state(x);
    impedance:
      name: "Xiaomi Mi Scale Impedance"
      id: impedance_xiaomi
      on_value:
        then:
          - lambda: |-
              if (id(weight_user1).state) {
                return id(impedance_user1).publish_state(x);
              } else if (id(weight_user2).state) {
                return id(impedance_user2).publish_state(x);
              } else if (id(weight_user3).state) {
                return id(impedance_user3).publish_state(x);
              } else if (id(weight_user4).state) {
                return id(impedance_user4).publish_state(x);
              } else if (id(weight_user5).state) {
                return id(impedance_user5).publish_state(x);
              }
  - platform: template
    name: Poids Aurélien
    id: weight_user1
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Impedance Aurélien
    id: impedance_user1
    unit_of_measurement: 'ohm'
    icon: mdi:omega
  - platform: template
    name: Poids Siham
    id: weight_user2
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Impedance Siham
    id: impedance_user2
    unit_of_measurement: 'ohm'
    icon: mdi:omega
  - platform: template
    name: Poids Théo
    id: weight_user3
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Impedance Théo
    id: impedance_user3
    unit_of_measurement: 'ohm'
    icon: mdi:omega
  - platform: template
    name: Poids Sacha
    id: weight_user4
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Impedance Sacha
    id: impedance_user4
    unit_of_measurement: 'ohm'
    icon: mdi:omega
  - platform: template
    name: Poids Noham
    id: weight_user5
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Impedance Noham
    id: impedance_user5
    unit_of_measurement: 'ohm'
    icon: mdi:omega
1 « J'aime »

Salut désolé je n’étais pas présent,

Pour ma part il ne me reconnais pas
platform: xiaomi_xmtzc0xhm
j’ai aussi essayé avec platform: xiaomi_xmtzc05hm
Je suis sur ton repo dans ESPHome je vis essayé dans le dev classique.

Slt,

J’espère rien de grave. Effectivement on ne ta pas beaucoup vue ces dernières jours.
Pour la platform finalement j’ai abandonné le regroupement cela ne fonctionne pas. Donc il faut continuer avec la version xiaomi_miscale2 par contre pour les utilisateurs il faut utiliser cette version avec l’autre (below, above) il y a des problèmes si le même utilisateur se pèse. Il faut qu’un autre utilisateur passe avant pour prendre en compte.

Voici la dernière version.

sensor:
  - platform: xiaomi_miscale
    mac_address: 'C8:47:8C:9F:7B:0A'
    weight:
      name: "Xiaomi Mi Scale Weight"
      on_value:
        then:
          - lambda: |-
              if (id(weight_miscale).state >= 69 && id(weight_miscale).state <= 72.99) { 
                return id(weight_user1).publish_state(x);}
              else if (id(weight_miscale).state >= 73 && id(weight_miscale).state <= 83) {
                return id(weight_user2).publish_state(x);}
              else if (id(weight_miscale).state >= 46 && id(weight_miscale).state <= 65) {
                return id(weight_user3).publish_state(x);}
              else if (id(weight_miscale).state >= 28 && id(weight_miscale).state <= 45) {
                return id(weight_user4).publish_state(x);}
              else if (id(weight_miscale).state >= 5 && id(weight_miscale).state <= 20) {
                return id(weight_user5).publish_state(x);}

  - platform: template
    name: Poids Aurélien
    id: weight_user1
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Poids Siham
    id: weight_user2
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Poids Théo
    id: weight_user3
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Poids Sacha
    id: weight_user4
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Poids Noham
    id: weight_user5
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
Config Esphome Miscale 2 (XMTZC02HM & XMTZC05HM)

sensor:
  - platform: xiaomi_miscale2
    mac_address: 'C8:47:8C:9F:7B:0A'
    weight:
      name: "Xiaomi Mi Scale Weight"
      on_value:
        then:
          - lambda: |-
              if (id(weight_miscale).state >= 69 && id(weight_miscale).state <= 72.99) { 
                return id(weight_user1).publish_state(x);}
              else if (id(weight_miscale).state >= 73 && id(weight_miscale).state <= 83) {
                return id(weight_user2).publish_state(x);}
              else if (id(weight_miscale).state >= 46 && id(weight_miscale).state <= 65) {
                return id(weight_user3).publish_state(x);}
              else if (id(weight_miscale).state >= 28 && id(weight_miscale).state <= 45) {
                return id(weight_user4).publish_state(x);}
              else if (id(weight_miscale).state >= 5 && id(weight_miscale).state <= 20) {
                return id(weight_user5).publish_state(x);}

  - platform: template
    impedance:
      name: "Xiaomi Mi Scale Impedance"
      id: impedance_xiaomi
      on_value:
        then:
          - lambda: |-
              if (id(weight_user1).state) {
                return id(impedance_user1).publish_state(x);
              } else if (id(weight_user2).state) {
                return id(impedance_user2).publish_state(x);
              } else if (id(weight_user3).state) {
                return id(impedance_user3).publish_state(x);
              } else if (id(weight_user4).state) {
                return id(impedance_user4).publish_state(x);
              } else if (id(weight_user5).state) {
                return id(impedance_user5).publish_state(x);
              }
  - platform: template
    name: Poids Aurélien
    id: weight_user1
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Impedance Aurélien
    id: impedance_user1
    unit_of_measurement: 'ohm'
    icon: mdi:omega
  - platform: template
    name: Poids Siham
    id: weight_user2
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Impedance Siham
    id: impedance_user2
    unit_of_measurement: 'ohm'
    icon: mdi:omega
  - platform: template
    name: Poids Théo
    id: weight_user3
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Impedance Théo
    id: impedance_user3
    unit_of_measurement: 'ohm'
    icon: mdi:omega
  - platform: template
    name: Poids Sacha
    id: weight_user4
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Impedance Sacha
    id: impedance_user4
    unit_of_measurement: 'ohm'
    icon: mdi:omega
  - platform: template
    name: Poids Noham
    id: weight_user5
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: Impedance Noham
    id: impedance_user5
    unit_of_measurement: 'ohm'
    icon: mdi:omega

Ben j’ai bien essayé ton code, je n’ai plus d’erreurs mais je n’ai aucune information qui remonte dans HA.

Je regarderais un peu plus demain

Slt, j’ai acheté la miscale 2 pour faire les test. Maintenant c’est tout bon. Attention j’ai refait la config en début de la page l’impedance ne se coller pas au bonne utilisateur. Pour le component j’y suis presque je but sur 1 problème mais je continue mes recherches. Il me manque juste à récupérer le poids avant le démarrage du component car pour l’instant il bloque la dessus. Mais si je le renseigne manuellement pas de soucis les données sont correct. Maintenant que j’ai la miscale 2 faut juste que j’adapte le components en ajoutant l’impedance pour les calculs supplémentaires mais si je solutionnes mon 1er problème le reste sera facile.

1 « J'aime »

Merci bien pour le travail dessus. Je testerai un peu plus tard pas trop de temps en ce moment.

Meilleures vœux

Bonjour à tous,
J’ai suivi le tuto, tout verifié mais quand je relance HA j’ai ce message d’erreur, pourriez vous me guider pour le corriger, svp? Envous remerciant par avance.

Logger: homeassistant.setup
Source: custom_components/bodymiscale/__init__.py:280
First occurred: 11:04:24 (1 occurrences)
Last logged: 11:04:24

Error during setup of component bodymiscale
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/setup.py", line 213, in _async_setup_component
    result = await task
  File "/config/custom_components/bodymiscale/__init__.py", line 114, in async_setup
    await component.async_add_entities(entities)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 315, in async_add_entities
    await asyncio.gather(*tasks)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 506, in _async_add_entity
    await entity.add_to_platform_finish()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 531, in add_to_platform_finish
    self.async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 296, in async_write_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 322, in _async_write_ha_state
    attr.update(self.state_attributes or {})
  File "/config/custom_components/bodymiscale/__init__.py", line 280, in state_attributes
    ATTR_WEIGHT: "{:.2f} kg".format(weight),
TypeError: unsupported format string passed to NoneType.__format__

Slt,

Je n’ai arrive pas à corriger cette erreur. Mais normalement cela n’affecte pas le fonctionnement. Tu devrais avoir un bodymiscale.xxxx de créer. Vérifie dans l’outils de développement.

Merci pour ta réponse, je viens de vérifier et je n’ai pas de bodymiscale.xxxx dans l’outils de développement.

Regarde mon échange avec une personne sur github dans l’issue closes. Tu trouveras certainement la solution. Sinon ouvre un nouveau problème.

Merci beaucoup je fais ça demain. J’ai lu le post sur le suivi de poids pour plusieurs personnes, est ce que c’est fonctionnel? En te remerciant pour ton investissement.

Oui cela fonctionne. J’ai écrit la doc ici pour la futur intégration en stable.

Merci beaucoup, je teste ça demain :wink:

Si tu veux mettre le post à jour pas de soucis

Slt, je vais attendre que tout passe en stable.

1 « J'aime »

Bonjour à tous,

Voila l’intégration est enfin disponible dans Esphome 1.17.0. Je vous ai ajouté un components pour récupérer votre score du corps et je suis en cours d’adaptation d’une carte pour rendre tout ça harmonieux dans votre Homeassistant.
Je vous ai également mis un lien de mon noeud rouge pour choisir l’utilisateur qui vient de se peser. Cela envoi une notification sur votre smartphone, vous cliquez sur l’utilisateur et cela envoi les données dans votre sensor.

Dans mon poste il y a aussi une carte manuel si vous êtes impatient. https://community.home-assistant.io/t/lovelace-body-miscale-card-2-0-0-inprogress-help-me/300362

1 « J'aime »