Balança Xiaomi Mi Body Composition Scale 2: Integração com vários perfis de usuário no Home Asssistant

image image

Este tutorial mostra como integrar a balança Xiaomi Mi Body Composition Scale 2 ao home assistant utilizando vários perfis de usuário, mesmo que o peso dos usuários sejam próximos.

Materiais utilizados:

Para integrar a balança ao Home assistante utilizei o ESPHome em um NodeMCU ESP-WROOM-32, detalhes da integração pode ser visualizada na documentação do ESPHome. O código utilizado para possibilitar vários perfis está disponível mais a frente neste tutorial.

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

A seleção do usuário que está sendo pesado é através de um switch na interface do Home Assistant. Após registrar o peso, o switch retorna automaticamente para a posição desligada.

IMG_1788

Caso os usuários tenham pesos em uma faixa diferente, é possível configurar para a seleção automática do perfil. Essa opção está disponível na documentação do ESPHome.

1. Código do ESPHome:

No código abaixo deve ser alteradas as informações de rede (rede wifi, senha e endereço IP) e o endereço MAC da balança.

O endereço MAC da balança deve ser consultado no aplicativo Mi Fit.

substitutions:
  #Configurações:
  Plataforma: ESP32
  TipoPlaca: esp32dev
  hostname: 'casa_esp_ble' #Hostname do dispositivo na rede
  PrefixoNome: "BLE - "
  RedeWifi: !secret RedeWifi #Nome da rede wifi que o dispositivo irá se conectar
  SenhaWifi: !secret  SenhaWifi #Senha da rede wifi que o dispositivo irá se conectar
  SenhaWifiReconfig: !secret SenhaWifiReconfig #Senha do AP Wifi para reconfiguração do wifi do dispositivo
  EndConfig: ${hostname}.local #192.168.1.50 #Endereço para configuração (IP que o esp está acessível atualmente na rede), especialmente usado quando quer alterar o hostname via OTA
  WifiOculto: 'False' #Se a rede wifi está oculta defina como 'True'
  WifiFastConnect: 'False' #Se o esp realizará a conexão à rede wifi sem escanear as redes disponíveis defina como 'True'

  SenhaAPI: !secret SenhaAPI #Senha para adicionar o esp no HA
  SenhaOTA: !secret SenhaOTA #Senha para atualizar o firmware do esp via OTA

  BalancaMAC: !secret BalancaMAC
  
esphome:
  name: $hostname
  platform: ${Plataforma}
  board: ${TipoPlaca}
  
wifi:
  networks:
  - ssid: ${RedeWifi}
    password: ${SenhaWifi}
    hidden: ${WifiOculto}
  fast_connect: ${WifiFastConnect}
  use_address: ${EndConfig}
  
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ${hostname}_WIFI
    password: ${SenhaWifiReconfig}

#Habilita um AP Wifi para reconfigurar em caso de perda de conexão com a rede configurada
captive_portal:

#Habilita a api para comunicar com o Home Assistant
api:
  password: ${SenhaAPI}

#Habilita a atualização de firmware por OTA
ota:
  password: ${SenhaOTA}
  
logger:
  baud_rate: 0

esp32_ble_tracker:

switch:
  #Comando reinicilizar esp remotamente
  - platform: restart
    id: ${hostname}_restart
    name: ${PrefixoNome} Reiniciar
    icon: mdi:restart
  
  #Switich Ativar Registro Pesagem Douglas
  - platform: template
    id: switch_pesagem_douglas
    name: Pesagem Douglas
    icon: mdi:toggle-switch
    lambda: return id(bs_pesagem_douglas).state;
    turn_off_action:
      - lambda: id(bs_pesagem_douglas).publish_state(false); #Desativa o sensor auxiliar de pesagem do Douglas
    turn_on_action:
      - lambda: id(bs_pesagem_douglas).publish_state(true); #Ativa o sensor auxiliar de pesagem do Douglas
      - lambda: id(bs_pesagem_jose).publish_state(false); #Desativa o sensor auxiliar de pesagem do José
      - lambda: id(bs_pesagem_maria).publish_state(false); #Desativa o sensor auxiliar de pesagem da Maria
      
  #Switch Ativar Registro Pesagem Maria
  - platform: template
    id: switch_pesagem_maria
    name: Pesagem Maria
    icon: mdi:toggle-switch
    lambda: return id(bs_pesagem_maria).state;
    turn_off_action:
      - lambda: id(bs_pesagem_maria).publish_state(false); #Desativa o sensor auxiliar de pesagem da Maria
    turn_on_action:
      - lambda: id(bs_pesagem_maria).publish_state(true); #Ativa o sensor auxiliar de pesagem da Maria
      - lambda: id(bs_pesagem_jose).publish_state(false); #Desativa o sensor auxiliar de pesagem do José
      - lambda: id(bs_pesagem_douglas).publish_state(false); #Desativa o sensor auxiliar de pesagem do Douglas
      
  #Switch Ativar Registro Pesagem José
  - platform: template
    id: switch_pesagem_jose
    name: Pesagem José
    icon: mdi:toggle-switch
    lambda: return id(bs_pesagem_jose).state;
    turn_off_action:
      - lambda: id(bs_pesagem_jose).publish_state(false); #Desativa o sensor auxiliar de pesagem do José
    turn_on_action:
      - lambda: id(bs_pesagem_jose).publish_state(true); #Ativa o sensor auxiliar de pesagem do José
      - lambda: id(bs_pesagem_douglas).publish_state(false); #Desativa o sensor auxiliar de pesagem do Douglas
      - lambda: id(bs_pesagem_maria).publish_state(false); #Desativa o sensor auxiliar de pesagem da Maria

text_sensor:
  #Informações da conexão wifi
  - platform: wifi_info
    #Endereço IP
    ip_address:
      id: ${hostname}_IP
      name: ${PrefixoNome} Endereço IP
      icon: mdi:ip-network
    #Nome da Rede
    ssid:
      id: ${hostname}_SSID
      name: ${PrefixoNome} Rede Wifi
      icon: mdi:wifi
  #Informação da versão da compilação
  - platform: version
    id: ${hostname}_versao
    name: ${PrefixoNome} Versão
    icon: mdi:information

binary_sensor:
  #Status (conectado ou desconectado)
  - platform: status
    id: ${hostname}_status
    name: ${PrefixoNome} Status
    device_class: connectivity

  - platform: ble_presence
    mac_address: ${BalancaMAC}
    name: ${PrefixoNome} Balança Status

  #Sensor auxiliar de pesagem do Douglas
  - platform: template
    id: bs_pesagem_douglas
    internal: true

  #Sensor auxiliar de pesagem do José
  - platform: template
    id: bs_pesagem_jose
    internal: true
  
  #Sensor auxiliar de pesagem da Maria
  - platform: template
    id: bs_pesagem_maria
    internal: true
    
sensor:
  #Sensor Intensidade Sinal Wifi
  - platform: wifi_signal
    id: ${hostname}_wifi_sinal
    name: ${PrefixoNome} Intensidade Wifi
    icon: mdi:signal
    update_interval: 10s

  #Intensidade sinal bluetooth da balançan
  - platform: ble_rssi
    mac_address: ${BalancaMAC}
    name: ${PrefixoNome} Balança Sinal

  #Sensores do perfil de Douglas
  - platform: template
    name: MIScale Douglas Peso
    id: douglas_peso
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: MIScale Douglas Impedância
    id: douglas_impedancia
    unit_of_measurement: Ω
    icon: mdi:omega
    accuracy_decimals: 0
    
  #Sensores do perfil de Maria
  - platform: template
    name: MIScale Maria Peso
    id: maria_peso
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: MIScale Maria Impedância
    id: maria_impedancia
    unit_of_measurement: Ω
    icon: mdi:omega
    accuracy_decimals: 0
    
  #Sensores do perfil de José
  - platform: template
    name: MIScale José Peso
    id: jose_peso
    unit_of_measurement: 'kg'
    icon: mdi:weight-kilogram
    accuracy_decimals: 2
  - platform: template
    name: MIScale José Impedância
    id: jose_impedancia
    unit_of_measurement: Ω
    icon: mdi:omega
    accuracy_decimals: 0
    
  #Sensores da balança
  - platform: xiaomi_miscale
    mac_address: ${BalancaMAC}
    #Sensor de peso da balança  
    weight:
      name: ${PrefixoNome} Balança Peso
      id: balanca_peso
      #Define o valor de peso do perfil selecionado se maior que zero
      on_value:
        then:
          - lambda: |-
              if (id(bs_pesagem_douglas).state and x>0) {
                id(douglas_peso).publish_state(x);
              } else if (id(bs_pesagem_maria).state and x>0) {
                id(maria_peso).publish_state(x);
              } else if (id(bs_pesagem_jose).state and x>0) {
                id(jose_peso).publish_state(x);
              }
    #Sensor de impedância da balança
    impedance:
      name: ${PrefixoNome} Balança Impedância
      id: balanca_impedancia
      #Define o valor de impedância do perfil selecionado se maior que zero
      on_value:
        then:
          - lambda: |-
              if (id(bs_pesagem_douglas).state and x>0) {
                id(douglas_impedancia).publish_state(x);
              } else if (id(bs_pesagem_maria).state and x>0) {
                id(maria_impedancia).publish_state(x);
              } else if (id(bs_pesagem_jose).state and x>0) {
                id(jose_impedancia).publish_state(x);
              }
          #Retorna os sensores auxiliar de pesagem para false após concluir a pesagem
          - lambda: id(bs_pesagem_douglas).publish_state(false); #Desativa o sensor auxiliar de pesagem do Douglas
          - lambda: id(bs_pesagem_jose).publish_state(false); #Desativa o sensor auxiliar de pesagem do José
          - lambda: id(bs_pesagem_maria).publish_state(false); #Desativa o sensor auxiliar de pesagem da Maria

Todas essas informações importantes (senhas OTA e API, configuração da rede wifi, endereço MAC da balança, etc) estão armazenadas no arquivo secrets.yaml (ver aqui e aqui para mais detalhes de configuração e uso).

2. Sensores no Home Assistenat (Template):

Devido os sensores de peso e impedância de cada usuário ficar indisponível caso o hub bluetooth ficar offline (nodemcu), criei sensores template para cada usuário que irá verifica se o valor está disponível antes de atualizar. Basta incluir no arquivo configuration.yaml.

  sensor:
  - platform: template
    sensors:
      #Sensor de peso do Douglas
      douglas_peso:
        friendly_name: Douglas Peso
        unit_of_measurement: kg
        icon_template: mdi:weight-kilogram
        value_template: >-
          {%if (states('sensor.miscale_douglas_peso')!="unknown" and states('sensor.miscale_douglas_peso')!="unavailable") %}
            {{states('sensor.miscale_douglas_peso')|float(2)}}
          {% else %}
            {{states('sensor.douglas_peso')}}
          {% endif %}
      #Sensor de impedância do Douglas
      douglas_impedancia:
        friendly_name: Douglas Impedância
        unit_of_measurement: Ω
        icon_template: mdi:omega
        value_template: >-
          {%if (states('sensor.miscale_douglas_impedancia')!="unknown" and states('sensor.miscale_douglas_impedancia')!="unavailable") %}
            {{states('sensor.miscale_douglas_impedancia')|float(2)}}
          {% else %}
            {{states('sensor.douglas_impedancia')}}
          {% endif %}

      #Sensor de peso da Maria
      maria_peso:
        friendly_name: Maria Peso
        unit_of_measurement: kg
        icon_template: mdi:weight-kilogram
        value_template: >-
          {%if (states('sensor.miscale_maria_peso')!="unknown" and states('sensor.miscale_maria_peso')!="unavailable") %}
            {{states('sensor.miscale_maria_peso')|float(2)}}
          {% else %}
            {{states('sensor.maria_peso')}}
          {% endif %}
      #Sensor de impedância da Maria    
      maria_impedancia:
        friendly_name: Maria Impedância
        unit_of_measurement: Ω
        icon_template: mdi:omega
        value_template: >-
          {%if (states('sensor.miscale_maria_impedancia')!="unknown" and states('sensor.miscale_maria_impedancia')!="unavailable") %}
            {{states('sensor.miscale_maria_impedancia')|float(2)}}
          {% else %}
            {{states('sensor.maria_impedancia')}}
          {% endif %}

      #Sensor de peso do José
      jose_peso:
        friendly_name: José Peso
        unit_of_measurement: kg
        icon_template: mdi:weight-kilogram
        value_template: >-
          {%if (states('sensor.miscale_jose_peso')!="unknown" and states('sensor.miscale_jose_peso')!="unavailable") %}
            {{states('sensor.miscale_jose_peso')|float(2)}}
          {% else %}
            {{states('sensor.jose_peso')}}
          {% endif %}
      #Sensor de impedância do José
      jose_impedancia:
        friendly_name: José Impedância
        unit_of_measurement: Ω
        icon_template: mdi:omega
        value_template: >-
          {%if (states('sensor.miscale_jose_impedancia')!="unknown" and states('sensor.miscale_jose_impedancia')!="unavailable") %}
            {{states('sensor.miscale_jose_impedancia')|float(2)}}
          {% else %}
            {{states('sensor.jose_impedancia')}}
          {% endif %}     

3. Card Simples no Lovelace

Um card simples com as informações do hub bluetooth, da balança e dos perfis de usuários no lovelace:

Código do lovelace:

type: grid
columns: 1
title: Balança Mi Scale 2
cards:
  - type: entities
    entities:
      - entity: binary_sensor.ble_balanca_status
      - entity: sensor.ble_balanca_sinal
      - entity: sensor.ble_balanca_peso
      - entity: sensor.ble_balanca_impedancia
    title: Balança
    state_color: true
  - type: grid
    columns: 3
    title: Sensores de Peso ESPHome
    cards:
      - type: entities
        entities:
          - entity: switch.pesagem_douglas
            name: ' '
          - entity: sensor.miscale_douglas_peso
            name: ' '
          - entity: sensor.miscale_douglas_impedancia
            name: ' '
        title: Douglas
        state_color: true
      - type: entities
        entities:
          - entity: switch.pesagem_maria
            name: ' '
          - entity: sensor.miscale_maria_peso
            name: ' '
          - entity: sensor.miscale_maria_impedancia
            name: ' '
        title: Maria
        state_color: true
      - type: entities
        entities:
          - entity: switch.pesagem_jose
            name: ' '
          - entity: sensor.miscale_jose_peso
            name: ' '
          - entity: sensor.miscale_jose_impedancia
            name: ' '
        title: José
        state_color: true
    square: false
  - type: grid
    columns: 3
    title: Sensores de Peso Home Assistant
    cards:
      - type: entities
        entities:
          - entity: sensor.douglas_peso
            name: ' '
          - entity: sensor.douglas_impedancia
            name: ' '
        title: Douglas
        state_color: true
      - type: entities
        entities:
          - entity: sensor.maria_peso
            name: ' '
          - entity: sensor.maria_impedancia
            name: ' '
        title: Maria
        state_color: true
      - type: entities
        entities:
          - entity: sensor.jose_peso
            name: ' '
          - entity: sensor.jose_impedancia
            name: ' '
        title: José
        state_color: true
    square: false
  - type: entities
    entities:
      - entity: binary_sensor.ble_status
      - entity: sensor.ble_rede_wifi
      - entity: sensor.ble_intensidade_wifi
      - entity: sensor.ble_endereco_ip
      - entity: switch.ble_reiniciar
      - entity: sensor.ble_versao
    title: Informações do Device
    state_color: true
square: false

4. Integração personalizada para informações adicionais da composição corporal:

Utilizando o custom component Body Metrics for Xiomi é possível incluir informações adcionais sobre a composição corporal a partir do peso e da impedância medida pela balança.

Detalhes podem ser condultados na documentação:

Para adicionar a integração deve-se instalar o custom componente via HACS ou manualmente conforme instruções na documentação, reiniciar o Home Assistant e incluir o código abaixo com as informações de cada usuário no arquivo configuration.yaml (incluir após instalar o custom component e reiniciar o HA) e realizar nova reinicialização do Home Assistant:

bodymiscale:
    jose:
      sensors:
        weight: sensor.jose_peso #Informar o sensor do peso criado através do template do Home Assistant (se informar o proveniente do ESPHome, quando ele for reinicializado ou estiver offline o sensor de composição corporal irá retornar erro)
        impedance: sensor.jose_impedancia #Informar o sensor de impedância criado através do template do Home Assistant (se informar o proveniente do ESPHome, quando ele for reinicializado ou estiver offline o sensor de composição corporal irá retornar erro)
      height: 177 #Altura em centímetros do usuário
      born: "1990-01-27" #Informar a data de nascimento do usuário no formato AAAA-MM-DD
      gender: "male" #Informar o sexo do usuário: male ou female
      model_miscale: "181B" #Informar o modelo da balança (181D para Mi Scale ou 181B para Mi Scale 2)

Após a reinicialização do Home Assistant um sensor com as informações estará disponível.
O status do sensor informa se há algum erro no cálculo e as informações estarão nos atributos do sensor.

5. Card personalizado com a composição corporal

type: custom:body-miscale-card
entity: bodymiscale.jose
image: /local/images/miscale2.jpg
model: true
unit: true
show_name: true
show_states: true
show_attributes: true
show_toolbar: true
show_body: true
show_buttons: true
entity_row: true
buttons:
  registrar_peso:
    icon: mdi:scale-bathroom
    label: Registrar Peso
    service: switch.toggle
    service_data:
      entity_id: switch.pesagem_jose
3 Likes

Muito bom, esperando minha balança chegar para testar.

2 Likes