Xiaomi Mi Flora und Node Red – Pflanzen überwachen mit dem Raspberry

Genug Licht, Wasser und ab und an etwas Dünger, das macht unsere Pflanzen froh. Ob alles passt, verrät uns der Mi Flora von Xiaomi. Der kleine Bluetooth-Sensor wird normalerweise direkt mit der passenden App auf dem Smartphone gekoppelt, kann jedoch auch in den Raspberry funken.

Voraussetzungen

  • Ein Raspberry mit Bluetooth, etwas ein Model 3B, 4 oder auch Zero W. Installiertes Raspberry Pi OS (Buster oder neuer)
  • Xiaomi Mi Flora oder „Nachbauten“, ab ca. 12 Euro im Asiashop

Bluetooth Adresse finden

Zunächst überprüfen wir ob Bluetooth im Raspberry funktioniert und der Mi Flora entdeckt wird. Die gefundene Adresse benötigen wir später um die Daten auszulesen.

#Bluetooth Umgebungsscan
sudo hcitool lescan

#Scan abbrechen mit CTRL-C

#Beispielausgabe
LE Scan ...
31:D3:AF:2D:59:F0 (unknown)
51:32:37:CC:82:EE Flower Care

Neben vermutlich einigen „Unbekannten“ Geräten sollte in der Liste auch ein „Flower Care“ und damit unser Xiaomi Device auftauchen.

Einbindung per Node Red

Ist bereits Node Red installiert, ist die Einrichtung schnell erledigt. Die passende Node ist node-red-contrib-xiaomi-devices und wird einfach über die „Palette“ installiert.

Node installieren

Der einfache Flow

Im neuen Baustein Xiaomi BLE müssen wir lediglich die Bluetooth Adresse eingeben und durch inject auslesen. Die verfügbaren Daten sehen wir nach einer erfolgreichen Verbindung im Debug Fenster.

Einfacher Flow für den Mi Flora Sensor
[{"id":"ee7913c3.bbd26","type":"Xiaomi BLE","z":"83c28990.49ea18","name":"","address":"C4:7C:8D:6A:9C:C7","scanningTimeout":60,"x":470,"y":240,"wires":[["dc4d7fc3.9f3d68"]]},{"id":"5ae25c26.766174","type":"inject","z":"83c28990.49ea18","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":220,"y":240,"wires":[["ee7913c3.bbd26"]]},{"id":"dc4d7fc3.9f3d68","type":"debug","z":"83c28990.49ea18","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":780,"y":240,"wires":[]}]

Der fortgeschrittene Flow

Die gewonnen Daten können wir nun regelmäßig per MQTT im Netzwerk verteilen, im Dashboard ausgeben, über Influx nach Grafana leiten …

[{"id":"ca093678.f26d7","type":"Xiaomi BLE","z":"3785f120.90cd96","name":"Mein Mi Flora","address":"C4:7C:8D:6A:9C:C7","scanningTimeout":"20","x":440,"y":780,"wires":[["34548b43.4f3f2c","81042299.84e26"]]},{"id":"34548b43.4f3f2c","type":"debug","z":"3785f120.90cd96","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":890,"y":780,"wires":[]},{"id":"6a17af57.b4c798","type":"inject","z":"3785f120.90cd96","name":"Abruf alle 10 Min","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"600","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":780,"wires":[["ca093678.f26d7"]]},{"id":"81042299.84e26","type":"split","z":"3785f120.90cd96","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"topic","x":420,"y":980,"wires":[["3353ba18.c0f926","a0bbcaeb.928498"]]},{"id":"7627408b.d36d08","type":"inject","z":"3785f120.90cd96","name":"Demo Daten","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"battery\":100,\"temperature\":22.4,\"light\":608,\"moisture\":20,\"conductivity\":149}","payloadType":"json","x":170,"y":980,"wires":[["81042299.84e26"]]},{"id":"c6ddc559.5b7c1","type":"mqtt out","z":"3785f120.90cd96","name":"","topic":"","qos":"","retain":"","broker":"","x":870,"y":980,"wires":[]},{"id":"3353ba18.c0f926","type":"function","z":"3785f120.90cd96","name":"MQTT Topic festlegen","func":"msg.topic = \"pflanzen/miflora/\" + msg.topic;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":680,"y":980,"wires":[["c6ddc559.5b7c1"]]},{"id":"a0bbcaeb.928498","type":"switch","z":"3785f120.90cd96","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"battery","vt":"str"},{"t":"eq","v":"temperature","vt":"str"},{"t":"eq","v":"light","vt":"str"},{"t":"eq","v":"moisture","vt":"str"},{"t":"eq","v":"conductivity","vt":"str"}],"checkall":"true","repair":false,"outputs":5,"x":590,"y":1160,"wires":[["86d74f08.7093f8"],["ea29e549.1c8c4"],["2cc343f3.8a2df4"],["160a38fa.0e8c87"],["1c6fef43.1d71d9"]]},{"id":"86d74f08.7093f8","type":"ui_chart","z":"3785f120.90cd96","name":"","group":"7cbba92f.3b546","order":4,"width":0,"height":0,"label":"Batterie","chartType":"line","legend":"false","xformat":"HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":"48","removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#b4ad2c","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":880,"y":1080,"wires":[[]]},{"id":"ea29e549.1c8c4","type":"ui_chart","z":"3785f120.90cd96","name":"","group":"7cbba92f.3b546","order":4,"width":0,"height":0,"label":"Temperatur","chartType":"line","legend":"false","xformat":"HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":"48","removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#b44828","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":890,"y":1120,"wires":[[]]},{"id":"2cc343f3.8a2df4","type":"ui_chart","z":"3785f120.90cd96","name":"","group":"7cbba92f.3b546","order":4,"width":0,"height":0,"label":"Licht","chartType":"line","legend":"false","xformat":"HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":"48","removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#f5aa9d","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":870,"y":1160,"wires":[[]]},{"id":"160a38fa.0e8c87","type":"ui_chart","z":"3785f120.90cd96","name":"","group":"7cbba92f.3b546","order":4,"width":0,"height":0,"label":"Feuchtigkeit","chartType":"line","legend":"false","xformat":"HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":"48","removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#256cf5","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":890,"y":1200,"wires":[[]]},{"id":"1c6fef43.1d71d9","type":"ui_chart","z":"3785f120.90cd96","name":"","group":"7cbba92f.3b546","order":4,"width":0,"height":0,"label":"Leitfähigkeit","chartType":"line","legend":"false","xformat":"HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":"48","removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#256cf5","#64e850","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":890,"y":1240,"wires":[[]]},{"id":"183605e2.5b40ba","type":"comment","z":"3785f120.90cd96","name":"Dashboard Grafiken","info":"","x":630,"y":1080,"wires":[]},{"id":"ce098039.3f9be8","type":"comment","z":"3785f120.90cd96","name":"Daten zum MQTT Server","info":"","x":650,"y":900,"wires":[]},{"id":"7cbba92f.3b546","type":"ui_group","z":"","name":"Mi Flora Sensor","tab":"ad98b36d.a329b8","order":1,"disp":true,"width":"6","collapse":false},{"id":"ad98b36d.a329b8","type":"ui_tab","z":"","name":"Pflanzen","icon":"dashboard","disabled":false,"hidden":false}]

Mi Flora ohne Node Red

Um allein die Daten auszulesen und per MQTT zu verschicken ist die Installation von Node Red natürlich übertrieben. Ein paar Zeilen Python erledigen einen genau so guten Job und sparen wertvolle Ressourcen. Die passende Anleitung und das notwendige Script findet ihr zum Beispiel auf Github von Thom Dietrich oder dieser Quelle.

Bluetooth Fehler

Die Bluetooth-Verbindung auf dem Raspberry scheint leider nicht immer die stabilste zu sein. Fehler wie „Set scan parameters failed: Input/output error.“ beim Scannen mit den hcitool oder „Gerät konnte nicht gefunden werden“ hatte ich selbst leider schon öfters.

Eine möglich Lösung ist dabei ein Neustart der betreffenden Services:

sudo service bluetooth restart
sudo service dbus restart

Um uns die Arbeit zu erleichtern und sicher sein, überlassen wir den täglichen Restart einem Cronjob:

#Cronjobs verwalten, für einen Service müssen wir diese als Sudo ausführen
sudo crontab -e

#Diese Zeile im Editor hinzugefügt startet den Service jeden Tag um Mitternacht
0 0 * * *  /usr/sbin/service bluetooth restart >/dev/null 2>&1