Ich habe oben genannten Roboter und nach einigem Rumtüfteln die Einbindung in smarthome hinbekommen. Damit sich andere den Kopf nicht zerbrechen müssen ( bzw. ich nach der nächsten komplett Zerlegung meines Systems nicht wieder bei 0 anfange) habe ich ein kleines HowTo verfasst.
Startpunkt: Das xiaomi Plugin funktioniert mit dieser Generation nicht mehr. Es muss das MIOT Protokoll verwendet werden. Aktuell nur in einer DEV Version verfügpar.
Zusätzlich brauchst du natürlich die IP und den eindeutigen 32-stelligen Token. Hierzu gibt es genügend Anleitungen im Netz.
Was ich auf die harte Tour rausfinden musste ist dass der Roboter sämtliche im Startbefehl mitgegebnen Rauminformationen ignoriert. Ihr müsst erst die Einstellungen für einen Raum definieren und dann den Roboter dorthin schicken. Die Raum ID's starten bei 1. Kann man durch probieren rausbekommen oder auch durch eine spezielle Version der Xiaomi Home App (venv Version) die in der Lage ist die Befehle als Logdateien auszugeben.
Alternativ nutzt ihr das Skript hier und verändert Werte in einzelnen Räumen. Ihr könnt dann auf der App sehen welcher Raum sich verändert hat. Damit sind die ID's ermittelt.
Dann habe ich mir eine items.yaml gebaut (natürlich für jeden Raum)
Die Logic funktioniert nach 3 Regeln:
1. Safe Values: Es sendet niemals 0 für Wasser oder Saugen (der Roboter mag das nicht). Stattdessen wird 1 als Platzhalter gesendet, wenn eine Funktion aus ist.
2. Modus-Steuerung: Die eigentliche Funktion (Nur Saugen vs. Wischen) wird über den Modus-Parameter (letzte Ziffer) gesteuert.
3. Ablauf: Erst Konfiguration senden (siid:6) -> Warten -> Startbefehl senden (siid:4).
Falls du später mal Logs debuggen musst, hier ist der Schlüssel zum Protokoll:
Der Konfigurations-String (customeClean):
Das Format ist [ID, A, B, C, D].
Index Bedeutung Werte
0 Raum ID 1-99 (Kartenabhängig)
1 Wasser 1 (Niedrig) - 3 (Hoch). Keine 0 senden!
2 Saugen 1 (Leise) - 4 (Turbo). Keine 0 senden!
3 Dummy Immer 0
4 Modus 0 = Nur Saugen/1 = Nur Wischen/2 = Saugen & Wischen
Wichtigste Erkenntnis:
Der Roboter ignoriert die Parameter im Startbefehl (selects). Man muss zwingend erst customeClean senden, kurz warten, und dann starten.
Sollte es Fragen geben oder etwas fehlen gerne melden.
Startpunkt: Das xiaomi Plugin funktioniert mit dieser Generation nicht mehr. Es muss das MIOT Protokoll verwendet werden. Aktuell nur in einer DEV Version verfügpar.
Was ich auf die harte Tour rausfinden musste ist dass der Roboter sämtliche im Startbefehl mitgegebnen Rauminformationen ignoriert. Ihr müsst erst die Einstellungen für einen Raum definieren und dann den Roboter dorthin schicken. Die Raum ID's starten bei 1. Kann man durch probieren rausbekommen oder auch durch eine spezielle Version der Xiaomi Home App (venv Version) die in der Lage ist die Befehle als Logdateien auszugeben.
Alternativ nutzt ihr das Skript hier und verändert Werte in einzelnen Räumen. Ihr könnt dann auf der App sehen welcher Raum sich verändert hat. Damit sind die ID's ermittelt.
#!/usr/bin/env python3
import json
from miio import MiotDevice
IP = '192.168.X.X'
TOKEN = 'DEIN_TOKEN_HIER'
# TEST-ID: Hier 1, 2, 3... durchprobieren
TEST_ID = 5
# Wir senden: Wasser Hoch (3), Saugen Turbo (4), Modus Mix (2)
# Wenn sich der Raum in der App ändert, hast du die ID gefunden.
CONFIG = [[TEST_ID, 3, 4, 0, 2]]
dev = MiotDevice(ip=IP, token=TOKEN)
print(f"Setze ID {TEST_ID} auf TURBO...")
# siid:6 (Config), aiid:2 (Set)
dev.send("action", {'siid': 6, 'aiid': 2, 'in': [{'piid': 4, 'value': json.dumps({"customeClean": CONFIG})}]})
import json
from miio import MiotDevice
IP = '192.168.X.X'
TOKEN = 'DEIN_TOKEN_HIER'
# TEST-ID: Hier 1, 2, 3... durchprobieren
TEST_ID = 5
# Wir senden: Wasser Hoch (3), Saugen Turbo (4), Modus Mix (2)
# Wenn sich der Raum in der App ändert, hast du die ID gefunden.
CONFIG = [[TEST_ID, 3, 4, 0, 2]]
dev = MiotDevice(ip=IP, token=TOKEN)
print(f"Setze ID {TEST_ID} auf TURBO...")
# siid:6 (Config), aiid:2 (Set)
dev.send("action", {'siid': 6, 'aiid': 2, 'in': [{'piid': 4, 'value': json.dumps({"customeClean": CONFIG})}]})
HTML-Code:
sauger:
start_mission:
type: bool
visu_acl: rw
# Trigger für die Logik
enforce_updates: 'true'
rooms:
kitchen:
select:
type: bool
visu_acl: rw
fan:
type: num
visu_acl: rw
# 0=Aus, 1=Leicht, 2=Standard, 3=Stark, 4=Turbo
water:
type: num
visu_acl: rw
# 0=Aus, 1=Niedrig, 2=Mittel, 3=Hoch
1. Safe Values: Es sendet niemals 0 für Wasser oder Saugen (der Roboter mag das nicht). Stattdessen wird 1 als Platzhalter gesendet, wenn eine Funktion aus ist.
2. Modus-Steuerung: Die eigentliche Funktion (Nur Saugen vs. Wischen) wird über den Modus-Parameter (letzte Ziffer) gesteuert.
3. Ablauf: Erst Konfiguration senden (siid:6) -> Warten -> Startbefehl senden (siid:4).
HTML-Code:
#!/usr/bin/env python3
import logging
import json
import time
logger = logging.getLogger(__name__)
# Import Fallback für verschiedene miio Versionen
try: from miio import MiotDevice
except ImportError:
try: from miio.miot_device import MiotDevice
except ImportError: from miio.device import Device as MiotDevice
# === KONFIGURATION ===
IP = '192.168.X.X'
TOKEN = 'dein Token'
# ID MAPPING (Muss zur Karte passen!)
ROOM_MAPPING = {
'kueche': 1,
'bad': 2,
...
}
try:
trigger_source = trigger['source']
trigger_value = trigger['value']
# === START MISSION ===
if trigger_source == 'sauger.start_mission' and trigger_value == True:
dev = MiotDevice(ip=IP, token=TOKEN)
logger.info("### LOGIK START: Zonenreinigung (Safe Params) ###")
config_list = [] # Payload für siid:6 (Einstellungen)
start_list_ids = [] # Payload für siid:4 (Start)
for name, rid in ROOM_MAPPING.items():
if hasattr(sh.sauger.rooms, name):
room_item = getattr(sh.sauger.rooms, name)
# Nur selektierte Räume beachten (Item muss True sein!)
if room_item.select():
# 1. Rohwerte aus Visu (0-4)
raw_fan = int(room_item.fan()) if room_item.fan() is not None else 2
raw_water = int(room_item.water()) if room_item.water() is not None else 1
# 2. Werte bereinigen ("Safe Values") & Modus bestimmen
# Der Roboter akzeptiert keine 0 bei Fan/Water.
# Wir senden min. 1 und steuern "Aus" über den Modus.
safe_fan = raw_fan if raw_fan > 0 else 1
safe_water = raw_water if raw_water > 0 else 1
mode = 2 # Default: Mix
# --- MODUS LOGIK ---
if raw_water == 0:
# Wasser Aus -> Modus 0 (Nur Saugen)
mode = 0
# Bei Modus 0 (Nur Saugen) erwartet der Roboter oft
# auch an der Wasser-Stelle (Index 1) den Fan-Wert oder ignoriert ihn.
# Wir lassen safe_water auf 1 oder raw_fan, sicher ist sicher.
elif raw_fan == 0:
# Saugen Aus -> Modus 1 (Nur Wischen)
mode = 1
else:
# Beides An -> Modus 2 (Mix)
mode = 2
logger.info(f" + Raum {name} (ID {rid}): Mode={mode} | Sende: Water={safe_water}, Fan={safe_fan}")
# 3. Das Protokoll-Array bauen
# Struktur: [ID, WASSER, FAN, 0, MODUS]
config_list.append([rid, safe_water, safe_fan, 0, mode])
# Start-Payload (Dummy Werte, wichtig ist nur die ID)
start_list_ids.append([rid, 1, 1, 2, 1])
if config_list:
# SCHRITT A: Konfiguration in den Roboter schreiben (siid:6)
try:
json_config = json.dumps({"customeClean": config_list})
dev.send("action", {'siid': 6, 'aiid': 2, 'in': [{'piid': 4, 'value': json_config}]})
except Exception as e:
logger.error(f"Fehler Konfig: {e}")
# WICHTIG: Pause, damit der Roboter speichert
time.sleep(1)
# SCHRITT B: Reinigung starten (siid:4)
try:
json_start = json.dumps({"selects": start_list_ids})
dev.send("action", {
'siid': 4, 'aiid': 1,
'in': [{'piid': 1, 'value': 18}, {'piid': 10, 'value': json_start}]
})
logger.info("Startbefehl gesendet.")
except Exception as e:
logger.error(f"Fehler Start: {e}")
# Reset Start-Button
time.sleep(1)
sh.sauger.start_mission(False)
else:
logger.warning("Keine Räume ausgewählt! (Prüfe select-Items)")
sh.sauger.start_mission(False)
# === BASIS BEFEHLE (Start/Pause/Home) ===
elif trigger_source == 'sauger.command':
dev = MiotDevice(ip=IP, token=TOKEN)
cmd = str(sh.sauger.command())
if cmd == 'start': dev.send("action", {'siid': 2, 'aiid': 1})
elif cmd == 'pause': dev.send("action", {'siid': 2, 'aiid': 2})
elif cmd == 'home': dev.send("action", {'siid': 3, 'aiid': 1})
except Exception as e:
logger.error(f"CRASH: {e}")
Der Konfigurations-String (customeClean):
Das Format ist [ID, A, B, C, D].
Index Bedeutung Werte
0 Raum ID 1-99 (Kartenabhängig)
1 Wasser 1 (Niedrig) - 3 (Hoch). Keine 0 senden!
2 Saugen 1 (Leise) - 4 (Turbo). Keine 0 senden!
3 Dummy Immer 0
4 Modus 0 = Nur Saugen/1 = Nur Wischen/2 = Saugen & Wischen
Wichtigste Erkenntnis:
Der Roboter ignoriert die Parameter im Startbefehl (selects). Man muss zwingend erst customeClean senden, kurz warten, und dann starten.
Sollte es Fragen geben oder etwas fehlen gerne melden.
