“Die Macht ist stark mit dieser Waage — aber ohne Encryption Key hört ble_monitor einfach nicht hin.”

Das Problem

Du hast eine Xiaomi Körperwaage (MJTZC01YM oder ähnlich) in Home Assistant eingebunden. Alles lief. Dann hat der Supervisor automatisch HA neu gestartet — und seitdem:

sensor.ble_weight_waage: unknown
sensor.ble_impedance_waage: unknown
sensor.<NAME>_muscle_mass: unknown
sensor.<NAME>_body_fat: unknown
bodymiscale.<NAME>: problem (impedance_unavailable)

Gewicht kommt manchmal noch durch (über eine zweite Integration), aber Körperfett und Muskelmasse bleiben dauerhaft unknown.

TL;DR

ble_monitor kann die verschlüsselten BLE-Pakete der Waage (MiBeacon V5) nicht entschlüsseln, weil der Encryption Key fehlt. Außerdem zeigt bodymiscale auf Sensor-Entitäten die nicht existieren. Beides fix: JSON in /homeassistant/.storage/core.config_entries patchen, HA neustarten.

Ursache

Problem 1: ble_monitor hat keinen Encryption Key

Xiaomi-Waagen neuerer Generation (MJTZC01YM) senden ihre Daten mit MiBeacon V5 verschlüsselt. ble_monitor braucht den Bindkey um die Pakete zu dekodieren.

Im HA-Log nach dem Neustart:

ERROR (Thread-5) [custom_components.ble_monitor.ble_parser.xiaomi]
No encryption key found for device with MAC <WAAGE-MAC>

Der Key existiert meist in der xiaomi_ble-Integration (die hat ihn beim Pairing gespeichert) — aber ble_monitor weiß nichts davon. Er fehlt im Config-Entry unter options.devices.

Problem 2: bodymiscale zeigt auf falsche Entitäten

bodymiscale war konfiguriert mit:

  • weight: sensor.body_composition_scale_xxxx_gewicht ← existiert (aber veraltet)
  • impedance: sensor.body_composition_scale_xxxx_impedanzexistiert nicht

Die korrekte Impedanz-Entität kommt von ble_monitor: sensor.ble_impedance_waage.

Was beim Neustart passiert

  1. HA startet, lädt ble_monitor neu
  2. ble_monitor scannt BLE-Pakete der Waage
  3. Pakete sind verschlüsselt, Key fehlt → keine Dekodierung → Sensoren bleiben unknown
  4. bodymiscale wartet auf Impedanz-Sensor der nie kommt → impedance_unavailable

Diagnose

# SSH auf deinen HA-Host
ssh <USER>@<HA-HOST>

# Encryption Key Status prüfen
sudo cat /homeassistant/.storage/core.config_entries | python3 -c "
import sys, json
data = json.load(sys.stdin)
for e in data['data']['entries']:
    if e.get('domain') == 'ble_monitor':
        for d in e.get('options', {}).get('devices', []):
            print('MAC:', d.get('mac'))
            print('encryption_key:', d.get('encryption_key', 'FEHLT!'))
"
# bodymiscale Konfiguration prüfen
sudo cat /homeassistant/.storage/core.config_entries | python3 -c "
import sys, json
data = json.load(sys.stdin)
for e in data['data']['entries']:
    if e.get('domain') == 'bodymiscale':
        print('weight:', e.get('options', {}).get('weight'))
        print('impedance:', e.get('options', {}).get('impedance'))
"
# Encryption Key aus xiaomi_ble holen (falls vorhanden)
sudo cat /homeassistant/.storage/core.config_entries | python3 -c "
import sys, json
data = json.load(sys.stdin)
for e in data['data']['entries']:
    if e.get('domain') == 'xiaomi_ble':
        print(json.dumps(e.get('data', {}), indent=2))
"

Lösung

Schritt 1: Encryption Key in ble_monitor eintragen

ssh <USER>@<HA-HOST>

sudo python3 -c "
import json, shutil

# Backup erstellen
shutil.copy('/homeassistant/.storage/core.config_entries',
            '/homeassistant/.storage/core.config_entries.bak')

with open('/homeassistant/.storage/core.config_entries', 'r') as f:
    data = json.load(f)

for e in data['data']['entries']:
    if e.get('domain') == 'ble_monitor':
        for dev in e.get('options', {}).get('devices', []):
            if dev.get('mac') == '<WAAGE-MAC>':  # MAC der Waage anpassen!
                dev['encryption_key'] = '<DEIN-ENCRYPTION-KEY>'
                print('Key eingetragen für:', dev['mac'])

with open('/homeassistant/.storage/core.config_entries', 'w') as f:
    json.dump(data, f, indent=2, ensure_ascii=False)
"

Wo bekomme ich den Encryption Key?

  • Er liegt in core.config_entries unter dem xiaomi_ble-Entry im data-Feld (Diagnose-Befehl oben)
  • Alternativ: Mi Fit / Xiaomi App → Geräte-Bindkey auslesen

Schritt 2: bodymiscale auf korrekte Sensoren umstellen

sudo python3 -c "
import json

with open('/homeassistant/.storage/core.config_entries', 'r') as f:
    data = json.load(f)

for e in data['data']['entries']:
    if e.get('domain') == 'bodymiscale':
        # Beide Quellen auf ble_monitor umstellen
        e['options']['weight'] = 'sensor.ble_weight_waage'
        e['options']['impedance'] = 'sensor.ble_impedance_waage'
        print('bodymiscale aktualisiert')

with open('/homeassistant/.storage/core.config_entries', 'w') as f:
    json.dump(data, f, indent=2, ensure_ascii=False)
"

Wichtig: Beide Sensoren (weight + impedance) müssen aus derselben Integration kommen — sonst triggert bodymiscale nicht zuverlässig.

Schritt 3: Dashboard-Entitäten fixen (falls nötig)

Falls dein Dashboard noch auf sensor.body_composition_scale_xxxx_* zeigt:

sudo python3 << 'EOF'
import json, shutil

shutil.copy('/homeassistant/.storage/lovelace.<DEIN-DASHBOARD>',
            '/homeassistant/.storage/lovelace.<DEIN-DASHBOARD>.bak')

with open('/homeassistant/.storage/lovelace.<DEIN-DASHBOARD>', 'r') as f:
    data = json.load(f)

replacements = {
    'sensor.body_composition_scale_xxxx_gewicht': 'sensor.ble_weight_waage',
    'sensor.body_composition_scale_xxxx_impedanz': 'sensor.ble_impedance_waage',
    'sensor.body_composition_scale_xxxx_heart_rate': 'sensor.ble_heart_rate_waage',
}

def fix_cards(cards):
    for card in cards:
        if 'entity' in card:
            card['entity'] = replacements.get(card['entity'], card['entity'])
        if 'entities' in card:
            for e in card['entities']:
                if isinstance(e, dict) and 'entity' in e:
                    e['entity'] = replacements.get(e['entity'], e['entity'])
        if 'cards' in card:
            fix_cards(card['cards'])

for view in data['data']['config'].get('views', []):
    fix_cards(view.get('cards', []))

with open('/homeassistant/.storage/lovelace.<DEIN-DASHBOARD>', 'w') as f:
    json.dump(data, f, indent=2, ensure_ascii=False)
print('Dashboard gefixt')
EOF

Schritt 4: HA neustarten

HA_TOKEN="<DEIN-HA-TOKEN>"
curl -s -X POST \
  -H "Authorization: Bearer $HA_TOKEN" \
  -H "Content-Type: application/json" \
  "http://<HA-HOST>:8123/api/services/homeassistant/restart"

HA braucht ~45 Sekunden zum Hochfahren. Danach auf die Waage stellen.

Verifikation

HA_TOKEN="<DEIN-HA-TOKEN>"

# BLE-Sensoren prüfen (nach Wägung)
curl -s -H "Authorization: Bearer $HA_TOKEN" \
  "http://<HA-HOST>:8123/api/states/sensor.ble_weight_waage" | \
  python3 -c "import sys,json; d=json.load(sys.stdin); print('Gewicht:', d['state'])"

# bodymiscale State prüfen
curl -s -H "Authorization: Bearer $HA_TOKEN" \
  "http://<HA-HOST>:8123/api/states/bodymiscale.<NAME>" | \
  python3 -c "import sys,json; d=json.load(sys.stdin); print('State:', d['state'], '| Problem:', d['attributes'].get('problem','none'))"

Erwartete Ausgabe:

Gewicht: 77.5
State: ok | Problem: none

Troubleshooting

BLE-Sensoren bleiben ‘unknown’ trotz Encryption Key

Sensoren direkt nach dem Neustart sind unknown — erst nach einer echten Wägung (aufstellen, warten bis Messung abgeschlossen) kommen Werte rein. Die Waage sendet nur beim aktiven Messvorgang.

bodymiscale zeigt ‘ok’ aber Muscle/Fat bleiben ‘unknown’

Bodymiscale braucht Weight UND Impedanz aus derselben Quellintegration. Falls weight von xiaomi_ble und impedance von ble_monitor kommen, kann bodymiscale nicht zusammenführen → beide auf ble_monitor-Entitäten setzen (Schritt 2).

Encryption Key unbekannt

# In allen xiaomi-Entries suchen
sudo cat /homeassistant/.storage/core.config_entries | python3 -c "
import sys,json
data = json.load(sys.stdin)
for e in data['data']['entries']:
    if 'xiaomi' in e.get('domain','').lower():
        print(e['domain'], '|', json.dumps(e.get('data',{})))
"

Lessons Learned

  • ble_monitor und xiaomi_ble teilen keine Konfiguration. Ein Key der in xiaomi_ble gespeichert ist, landet nicht automatisch in ble_monitor. Muss manuell übertragen werden.
  • bodymiscale ist sensibel bei Sensor-Quellen. Weight und Impedanz aus unterschiedlichen Integrationen führt zu inkonsistenten Berechnungen.
  • HA-Supervisor-Neustarts passieren automatisch (z.B. nach Updates). Der fehlende Encryption Key fällt erst dann auf — nicht beim initialen Setup, weil alte Sensor-States aus dem Cache kommen.
  • Backup vor JSON-Edits in .storage/ ist Pflicht. HA kann nicht mehr starten wenn die Config-Files korrupt sind.