Xiaomi Mi Flora Plant Sensor MQTT Client/Daemon

The Mi Flora plant sensors are already discussed in length by @Csongor_Varga and @Seaside in the following articles:

The Mi Flora is a small battery powered Bluetooth LE device which you stick into the soil of your planting pot. The device can be queried for the soil moisture/humidity, soil conductivity/fertility, sunlight intensity and air temperature.

I bought a few of these sensors myself and found that while they are great sensors and easy to connect, non of the solutions out there were easy to set up and run continuously. I invested a few hours and implemented something that should cover everyone’s needs, even of those having problems with gatlib, root privileges or the necessity of MQTT.

Xiaomi Mi Flora Plant Sensor MQTT Client/Daemon

A simple Linux python script to query arbitrary Mi Flora plant sensor devices and send the data to an MQTT broker,
e.g., the famous Eclipse Mosquitto. After data made the hop to the MQTT broker it can be used by home automation software, like openHAB.

The program can be executed in daemon mode to run continuously in the background, e.g., as a systemd service.

Features

  • Support for Xiaomi Mi Flora sensors (e.g. 12-17€)
  • Tested with Mi Flora firmware v2.6.2, v2.6.4, v2.6.6, v3.1.4, others anticipated
  • Build on top of open-homeautomation/miflora
  • Highly configurable
  • Data publication via MQTT
  • JSON encoded or following the Homie Convention v2.0.5
  • Announcement messages to support auto-discovery services
  • MQTT authentication support
  • No special/root privileges needed
  • Daemon mode (default)
  • Systemd service, sd_notify messages generated
  • MQTT-less mode, printing data directly to stdout/file
  • Automatic generation of openHAB items and rules
  • Reliable and intuitive
  • Tested on Raspberry Pi 3 and Raspberry Pi 0W

Check out the GitHub project for all details.

Interested? The installation instructions can be found at: https://github.com/ThomDietrich/miflora-mqtt-daemon/blob/master/README.md#installation

The code is quite stable by now. I’d be interested in your experience and improvement ideas! Drop by with an issue ticket or pull request if you have, you can also write a comment in this thread. I’d be especially interested in the opinion by @Csongor_Varga and @Seaside, does the daemon miss any features?

I want to thank @skatun for the beta-phase feedback and @janwh for the initial python script I derived this project from :beers:

22 Likes

Awesome! Thanks for taking the time to put this together. If I ever decide to take more than a lackadaisical approach to horticulture I will have to try one of these out.

1 Like

What sort of range do you see on these? I want to add some temp/humidity sensors throughout the house and there just happen to be some plants in some of those locations. :wink: I couldn’t tell from their literature, and I think I already asked about this in the past, but these sensors only work indoors, correct?

Excellent work! I might just have to try this out myself sometime soon. At least after I catch up on other projects.

@Simsal I’m not sure what you mean. I’ve never compared with the app (actually barely used it). Are there systematic differences or are you just seeing slightly different readings?

Hey @rlkoshak the range is not great. I’ve implemented 3 retries per sensor per cycle and am seeing a 90% success rate for one of my sensors located 7 meters away with just a bit of furniture and a balcony door in the direct path. Another sensor around the corner has a success rate of 50% and one in the another room separated by two walls with 0% (no surprise here).

Be aware, that I’ve set up 9 sensors. All others in closer proximity are not listed in the screenshot. It’s also easy to improve the link quality by moving the plant or sensor position in the pot slightly. The readings you are seeing in the screenshot are from my deliberately bad positioned testing sensors.

One great thing about the daemon is, that it can easily run on a RPi0W in another corner of the house.

Ah, I’d need better range than that. Are these beaconing out the sensor readings? If so, one of the reelyActive guys just mentioned over on that tutorial that their new version is able to relay BTLE sensor packets. That could be a way to extend the range a bit…

I don’t know if the Mi Flora is a supported device though.

Of course, if I went that far I could just run your service on the Pis and be done with it. :slight_smile:

1 Like

Hi all, when I do
cp /opt/miflora-mqtt-daemon/config.{ini.bak,ini}

I get the following file-not-found error:
Fehler: cp: der Aufruf von stat für „/opt/miflora-mqtt-daemon/config.ini.bak“ ist nicht möglich: Datei oder Verzeichnis nicht gefunden

What I’ve done before:

  1. installed openhab and mosquito mqtt by openhabian 1.3 from scratch
  2. followed the instructions step by step until the error occured: Xiaomi Mi Flora Plant Sensor MQTT Client/Daemon

Does anybody know, what’s my mistake?

More informations:

                  openHAB 2.1.0-1 (Release Build)

[09:16:06] openhabian@openHABianPi:~$ sudo systemctl status mosquitto
[sudo] password for openhabian:
â—Ź mosquitto.service - Mosquitto MQTT Broker
   Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled)
   Active: active (running) since Do 2017-08-24 18:06:01 CEST; 1 day 15h ago
     Docs: man:mosquitto(8)
           https://mosquitto.org/
 Main PID: 442 (mosquitto)
   CGroup: /system.slice/mosquitto.service
           └─442 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

Aug 24 18:06:01 openHABianPi systemd[1]: Starting Mosquitto MQTT Broker...
Aug 24 18:06:01 openHABianPi systemd[1]: Started Mosquitto MQTT Broker.

[09:17:24] openhabian@openHABianPi:~$ sudo apt install git python3 python3-pip bluetooth bluez
Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut.
Statusinformationen werden eingelesen.... Fertig
git ist schon die neueste Version.
python3 ist schon die neueste Version.
python3 wurde als manuell installiert festgelegt.
bluez ist schon die neueste Version.
Das folgende Paket wurde automatisch installiert und wird nicht mehr benötigt:
  triggerhappy
Verwenden Sie »apt-get autoremove«, um es zu entfernen.
Die folgenden zusätzlichen Pakete werden installiert:
  libpython3-dev libpython3.4 libpython3.4-dev python3-chardet python3-colorama python3-dev python3-distlib python3-html5lib python3-pkg-resources python3-requests python3-setuptools python3-six
  python3-urllib3 python3-wheel python3.4-dev
Vorgeschlagene Pakete:
  bluez-cups bluez-obexd python3-genshi python3-lxml python3-ndg-httpsclient python3-openssl python3-pyasn1
Die folgenden NEUEN Pakete werden installiert:
  bluetooth libpython3-dev libpython3.4 libpython3.4-dev python3-chardet python3-colorama python3-dev python3-distlib python3-html5lib python3-pip python3-pkg-resources python3-requests python3-setuptools
  python3-six python3-urllib3 python3-wheel python3.4-dev
0 aktualisiert, 17 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.
Es mĂĽssen 41,0 MB an Archiven heruntergeladen werden.
Nach dieser Operation werden 56,8 MB Plattenplatz zusätzlich benutzt.
Möchten Sie fortfahren? [J/n] J
Holen: 1 http://mirrordirector.raspbian.org/raspbian/ jessie/main libpython3.4 armhf 3.4.2-1 [1.121 kB]
Holen: 2 http://archive.raspberrypi.org/debian/ jessie/main bluetooth all 5.23-2+rpi2 [36,5 kB]
Holen: 3 http://mirrordirector.raspbian.org/raspbian/ jessie/main libpython3.4-dev armhf 3.4.2-1 [38,5 MB]
Holen: 4 http://mirrordirector.raspbian.org/raspbian/ jessie/main libpython3-dev armhf 3.4.2-2 [18,2 kB]
Holen: 5 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-pkg-resources all 5.5.1-1 [34,2 kB]
Holen: 6 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-chardet all 2.3.0-1 [96,1 kB]
Holen: 7 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-colorama all 0.3.2-1 [13,1 kB]
Holen: 8 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3.4-dev armhf 3.4.2-1 [418 kB]
Holen: 9 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-dev armhf 3.4.2-2 [1.202 B]
Holen: 10 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-distlib all 0.1.9-1 [113 kB]
Holen: 11 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-six all 1.8.0-1 [12,7 kB]
Holen: 12 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-html5lib all 0.999-3 [82,3 kB]
Holen: 13 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-urllib3 all 1.9.1-3 [55,5 kB]
Holen: 14 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-requests all 2.4.3-6 [203 kB]
Holen: 15 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-setuptools all 5.5.1-1 [134 kB]
Holen: 16 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-pip all 1.5.6-5 [97,2 kB]
Holen: 17 http://mirrordirector.raspbian.org/raspbian/ jessie/main python3-wheel all 0.24.0-1 [47,6 kB]
Es wurden 41,0 MB in 11 s geholt (3.643 kB/s).
[master 2ab52c1] saving uncommitted changes in /etc prior to apt run
 Author: openhabian <openhabian@openHABianPi>
 4 files changed, 89 insertions(+), 1 deletion(-)
 create mode 100644 openhab2/items/wunderground.items
 create mode 100644 openhab2/things/wunderground.things
Vormals nicht ausgewähltes Paket libpython3.4:armhf wird gewählt.
(Lese Datenbank ... 48414 Dateien und Verzeichnisse sind derzeit installiert.)
Vorbereitung zum Entpacken von .../libpython3.4_3.4.2-1_armhf.deb ...
Entpacken von libpython3.4:armhf (3.4.2-1) ...
Vormals nicht ausgewähltes Paket libpython3.4-dev:armhf wird gewählt.
Vorbereitung zum Entpacken von .../libpython3.4-dev_3.4.2-1_armhf.deb ...
Entpacken von libpython3.4-dev:armhf (3.4.2-1) ...
Vormals nicht ausgewähltes Paket bluetooth wird gewählt.
Vorbereitung zum Entpacken von .../bluetooth_5.23-2+rpi2_all.deb ...
Entpacken von bluetooth (5.23-2+rpi2) ...
Vormals nicht ausgewähltes Paket libpython3-dev:armhf wird gewählt.
Vorbereitung zum Entpacken von .../libpython3-dev_3.4.2-2_armhf.deb ...
Entpacken von libpython3-dev:armhf (3.4.2-2) ...
Vormals nicht ausgewähltes Paket python3-pkg-resources wird gewählt.
Vorbereitung zum Entpacken von .../python3-pkg-resources_5.5.1-1_all.deb ...
Entpacken von python3-pkg-resources (5.5.1-1) ...
Vormals nicht ausgewähltes Paket python3-chardet wird gewählt.
Vorbereitung zum Entpacken von .../python3-chardet_2.3.0-1_all.deb ...
Entpacken von python3-chardet (2.3.0-1) ...
Vormals nicht ausgewähltes Paket python3-colorama wird gewählt.
Vorbereitung zum Entpacken von .../python3-colorama_0.3.2-1_all.deb ...
Entpacken von python3-colorama (0.3.2-1) ...
Vormals nicht ausgewähltes Paket python3.4-dev wird gewählt.
Vorbereitung zum Entpacken von .../python3.4-dev_3.4.2-1_armhf.deb ...
Entpacken von python3.4-dev (3.4.2-1) ...
Vormals nicht ausgewähltes Paket python3-dev wird gewählt.
Vorbereitung zum Entpacken von .../python3-dev_3.4.2-2_armhf.deb ...
Entpacken von python3-dev (3.4.2-2) ...
Vormals nicht ausgewähltes Paket python3-distlib wird gewählt.
Vorbereitung zum Entpacken von .../python3-distlib_0.1.9-1_all.deb ...
Entpacken von python3-distlib (0.1.9-1) ...
Vormals nicht ausgewähltes Paket python3-six wird gewählt.
Vorbereitung zum Entpacken von .../python3-six_1.8.0-1_all.deb ...
Entpacken von python3-six (1.8.0-1) ...
Vormals nicht ausgewähltes Paket python3-html5lib wird gewählt.
Vorbereitung zum Entpacken von .../python3-html5lib_0.999-3_all.deb ...
Entpacken von python3-html5lib (0.999-3) ...
Vormals nicht ausgewähltes Paket python3-urllib3 wird gewählt.
Vorbereitung zum Entpacken von .../python3-urllib3_1.9.1-3_all.deb ...
Entpacken von python3-urllib3 (1.9.1-3) ...
Vormals nicht ausgewähltes Paket python3-requests wird gewählt.
Vorbereitung zum Entpacken von .../python3-requests_2.4.3-6_all.deb ...
Entpacken von python3-requests (2.4.3-6) ...
Vormals nicht ausgewähltes Paket python3-setuptools wird gewählt.
Vorbereitung zum Entpacken von .../python3-setuptools_5.5.1-1_all.deb ...
Entpacken von python3-setuptools (5.5.1-1) ...
Vormals nicht ausgewähltes Paket python3-pip wird gewählt.
Vorbereitung zum Entpacken von .../python3-pip_1.5.6-5_all.deb ...
Entpacken von python3-pip (1.5.6-5) ...
Vormals nicht ausgewähltes Paket python3-wheel wird gewählt.
Vorbereitung zum Entpacken von .../python3-wheel_0.24.0-1_all.deb ...
Entpacken von python3-wheel (0.24.0-1) ...
Trigger fĂĽr man-db (2.7.5-1~bpo8+1) werden verarbeitet ...
libpython3.4:armhf (3.4.2-1) wird eingerichtet ...
libpython3.4-dev:armhf (3.4.2-1) wird eingerichtet ...
bluetooth (5.23-2+rpi2) wird eingerichtet ...
libpython3-dev:armhf (3.4.2-2) wird eingerichtet ...
python3-pkg-resources (5.5.1-1) wird eingerichtet ...
python3-chardet (2.3.0-1) wird eingerichtet ...
python3-colorama (0.3.2-1) wird eingerichtet ...
python3.4-dev (3.4.2-1) wird eingerichtet ...
python3-dev (3.4.2-2) wird eingerichtet ...
python3-distlib (0.1.9-1) wird eingerichtet ...
python3-six (1.8.0-1) wird eingerichtet ...
python3-html5lib (0.999-3) wird eingerichtet ...
python3-urllib3 (1.9.1-3) wird eingerichtet ...
python3-requests (2.4.3-6) wird eingerichtet ...
python3-setuptools (5.5.1-1) wird eingerichtet ...
python3-pip (1.5.6-5) wird eingerichtet ...
python3-wheel (0.24.0-1) wird eingerichtet ...
Trigger fĂĽr libc-bin (2.19-18+deb8u10) werden verarbeitet ...
Updating FireMotD available updates count ...

[09:20:30] openhabian@openHABianPi:~$ git clone https://github.com/ThomDietrich/miflora-mqtt-daemon.git /opt/miflora-mqtt-daemon
Klone nach '/opt/miflora-mqtt-daemon'...
remote: Counting objects: 156, done.
remote: Total 156 (delta 0), reused 0 (delta 0), pack-reused 156
Empfange Objekte: 100% (156/156), 371.99 KiB | 518.00 KiB/s, Fertig.
Löse Unterschiede auf: 100% (93/93), Fertig.
Prüfe Konnektivität... Fertig.

[09:20:42] openhabian@openHABianPi:~$ cd /opt/miflora-mqtt-daemon

[09:21:00] openhabian@openHABianPi:/opt/miflora-mqtt-daemon$ sudo pip3 install -r requirements.txt
Downloading/unpacking miflora from git+https://github.com/open-homeautomation/miflora.git (from -r requirements.txt (line 1))
  Cloning https://github.com/open-homeautomation/miflora.git to /tmp/pip-build-1wu6rwk3/miflora
  Running setup.py (path:/tmp/pip-build-1wu6rwk3/miflora/setup.py) egg_info for package miflora

Downloading/unpacking paho-mqtt==1.3.0 (from -r requirements.txt (line 3))
  Downloading paho-mqtt-1.3.0.tar.gz (79kB): 79kB downloaded
  Running setup.py (path:/tmp/pip-build-1wu6rwk3/paho-mqtt/setup.py) egg_info for package paho-mqtt
    your setuptools is too old (<12)
    setuptools_scm functionality is degraded
    zip_safe flag not set; analyzing archive contents...

    Installed /tmp/pip-build-1wu6rwk3/paho-mqtt/pytest_runner-2.11.1-py3.4.egg

Downloading/unpacking wheel==0.29.0 (from -r requirements.txt (line 4))
  Downloading wheel-0.29.0-py2.py3-none-any.whl (66kB): 66kB downloaded
Downloading/unpacking sdnotify==0.3.1 (from -r requirements.txt (line 5))
  Downloading sdnotify-0.3.1.tar.gz
  Running setup.py (path:/tmp/pip-build-1wu6rwk3/sdnotify/setup.py) egg_info for package sdnotify

Downloading/unpacking colorama==0.3.9 (from -r requirements.txt (line 6))
  Downloading colorama-0.3.9-py2.py3-none-any.whl
Downloading/unpacking Unidecode==0.4.21 (from -r requirements.txt (line 7))
  Downloading Unidecode-0.04.21-py2.py3-none-any.whl (228kB): 228kB downloaded
Installing collected packages: miflora, paho-mqtt, wheel, sdnotify, colorama, Unidecode
  Running setup.py install for miflora

  Running setup.py install for paho-mqtt

  Found existing installation: wheel 0.24.0
    Not uninstalling wheel at /usr/lib/python3/dist-packages, owned by OS
  Running setup.py install for sdnotify

  Found existing installation: colorama 0.3.2
    Not uninstalling colorama at /usr/lib/python3/dist-packages, owned by OS
Successfully installed miflora paho-mqtt wheel sdnotify colorama Unidecode
Cleaning up...

[09:21:39] openhabian@openHABianPi:/opt/miflora-mqtt-daemon$ gatttool --help
Usage:
  gatttool [OPTION...]

Help Options:
  -h, --help                                Show help options
  --help-all                                Show all help options
  --help-gatt                               Show all GATT commands
  --help-params                             Show all Primary Services/Characteristics arguments
  --help-char-read-write                    Show all Characteristics Value/Descriptor Read/Write arguments

Application Options:
  -i, --adapter=hciX                        Specify local adapter interface
  -b, --device=MAC                          Specify remote Bluetooth address
  -t, --addr-type=[public | random]         Set LE address type. Default: public
  -m, --mtu=MTU                             Specify the MTU size
  -p, --psm=PSM                             Specify the PSM for GATT/ATT over BR/EDR
  -l, --sec-level=[low | medium | high]     Set security level. Default: low
  -I, --interactive                         Use interactive mode

[09:22:02] openhabian@openHABianPi:/opt/miflora-mqtt-daemon$ cp /opt/miflora-mqtt-daemon/config.{ini.bak,ini}
cp: der Aufruf von stat für „/opt/miflora-mqtt-daemon/config.ini.bak“ ist nicht möglich: Datei oder Verzeichnis nicht gefunden

[09:22:28] openhabian@openHABianPi:/opt/miflora-mqtt-daemon$

That is the content of my folder /opt/miflora-mqtt-daemon

[09:23:13] openhabian@openHABianPi:/opt/miflora-mqtt-daemon$ ls -l
insgesamt 324
-rw-r--r-- 1 openhabian openhabian     84 Aug 26 09:20 AUTHORS
-rw-r--r-- 1 openhabian openhabian   1935 Aug 26 09:20 config.ini.dist
-rw-r--r-- 1 openhabian openhabian 284281 Aug 26 09:20 demo.gif
-rw-r--r-- 1 openhabian openhabian   1079 Aug 26 09:20 LICENSE
-rwxr-xr-x 1 openhabian openhabian  15310 Aug 26 09:20 miflora-mqtt-daemon.py
-rw-r--r-- 1 openhabian openhabian   7500 Aug 26 09:20 README.md
-rw-r--r-- 1 openhabian openhabian    165 Aug 26 09:20 requirements.txt
-rw-r--r-- 1 openhabian openhabian    438 Aug 26 09:20 template.service

Does anybody know, what’s my mistake?

Hey!
Seems like a simple documentation error on my side. As you can see, there is no bak file in the folder but config.ini.dist. Hence the command needs to be

cp /opt/miflora-mqtt-daemon/config.{ini.dist,ini}

Makes sense right? :smile:

Obviously I lack the basic knowledge. :thinking:
Thanks for the patience with beginners like me!

Ok, miflora service is running.

[17:01:45] openhabian@openHABianPi:/opt/miflora-mqtt-daemon$ sudo systemctl status miflora.service
[sudo] password for openhabian:
â—Ź miflora.service - Xiaomi Mi Flora Plant Sensor MQTT Client/Daemon
   Loaded: loaded (/etc/systemd/system/miflora.service; enabled)
   Active: active (running) since Sa 2017-08-26 17:01:15 CEST; 21min ago
     Docs: https://github.com/ThomDietrich/miflora-mqtt-daemon
 Main PID: 24033 (python3)
   Status: "Aug 26 17:21:36 - Status messages published."
   CGroup: /system.slice/miflora.service
           └─24033 python3 /opt/miflora-mqtt-daemon/miflora-mqtt-daemon.py

Aug 26 17:01:15 openHABianPi systemd[1]: Started Xiaomi Mi Flora Plant Sensor MQTT Client/Daemon.

But now I ended up at integration to openhab. :poop:
I get that error in my items-file:

grafik

grafik

// MiFloraPlantSensor01.items

gWohnenZierkastanie
/*
// Mi Flora specific groups
Group gBattery "Mi Flora sensor battery level elements" (gAll)
Group gTemperature "Mi Flora air temperature elements" (gAll)
Group gMoisture "Mi Flora soil moisture elements" (gAll)
Group gConductivity "Mi Flora soil conductivity/fertility elements" (gAll)
Group gLight "Mi Flora sunlight intensity elements" (gAll)
*/
 
// Mi Flora "zierkastanie" (C4:7C:8D:62:84:72)
Number WohnenZierkastanie_Battery "WohnenZierkastanie Sensor Battery Level [%d %%]" <text> (gWohnenZierkastanie, gBatteryLevel, gBatteryLevel_Chart) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.battery)]"}
Number WohnenZierkastanie_Temperature "WohnenZierkastanie Air Temperature [%.1f °C]" <text> (gWohnenZierkastanie) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.temperature)]"}
Number WohnenZierkastanie_Moisture "WohnenZierkastanie Soil Moisture [%d %%]" <text> (gWohnenZierkastanie) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.moisture)]"}
Number WohnenZierkastanie_Conductivity "WohnenZierkastanie Soil Conductivity/Fertility [%d µS/cm]" <text> (gWohnenZierkastanie) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.conductivity)]"}
Number WohnenZierkastanie_Light "WohnenZierkastanie Sunlight Intensity [%d lux]" <text> (gWohnenZierkastanie) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.light)]"}
 

When I erase the error line, I get an error in the next line.

You missed a “Group” here. That’s the error.

While we are at it, let’s discuss your choice of changes. Why did you remove the underscore in “Wohnen_Zierkastanie” and why one group for all? I think the property specific groups are meaningful (e.g. for persistence and group based rules) but I guess it wouldn’t hurt to define additional groups for individual sensors and one group for all sensors in the generated items listing. Wdyt? Please feel free to file an Issue on GitHub.

Btw. I’ve pushed the README fix from above to the repository.

Upps! That’s embarrassing! Sorry, I was blind and didn’t see that stupid errror.

But even with the right group item I don’t get values displayed in my openHAB-UI. Hopefully not another stupid mistake.

grafik

Changed my item-file MiFloraPlantSensor01.items for testing, now it is:

// miflora.items

// Mi Flora specific groups
Group gUnknownRoom
Group gBattery "Mi Flora sensor battery level elements" (gAll)
Group gTemperature "Mi Flora air temperature elements" (gAll)
Group gMoisture "Mi Flora soil moisture elements" (gAll)
Group gConductivity "Mi Flora soil conductivity/fertility elements" (gAll)
Group gLight "Mi Flora sunlight intensity elements" (gAll)

// Mi Flora "Zierkastanie" (C4:7C:8D:62:84:72)
Number  UnknownRoom_Zierkastanie_Battery " UnknownRoom Zierkastanie Sensor Battery Level [%d %%]" <text> (gUnknownRoom, gBattery) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.battery)]"}
Number  UnknownRoom_Zierkastanie_Temperature " UnknownRoom Zierkastanie Air Temperature [%.1f °C]" <text> (gUnknownRoom, gTemperature) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.temperature)]"}
Number  UnknownRoom_Zierkastanie_Moisture " UnknownRoom Zierkastanie Soil Moisture [%d %%]" <text> (gUnknownRoom, gMoisture) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.moisture)]"}
Number  UnknownRoom_Zierkastanie_Conductivity " UnknownRoom Zierkastanie Soil Conductivity/Fertility [%d µS/cm]" <text> (gUnknownRoom, gConductivity) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.conductivity)]"}
Number  UnknownRoom_Zierkastanie_Light " UnknownRoom Zierkastanie Sunlight Intensity [%d lux]" <text> (gUnknownRoom, gLight) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.light)]"}

With python3 /opt/miflora-mqtt-daemon/miflora-mqtt-daemon.py I get:

[09:41:23] openhabian@openHABianPi:~$ python3 /opt/miflora-mqtt-daemon/miflora-mqtt-daemon.py

Xiaomi Mi Flora Plant Sensor MQTT Client/Daemon
Source: https://github.com/ThomDietrich/miflora-mqtt-daemon

[2017-08-27 09:41:42] Connecting to MQTT broker ...
[2017-08-27 09:41:42] MQTT connection established

Adding sensor to device list and testing connection ...
Name:          "Zierkastanie"
Internal name: "zierkastanie"
Device name:   "Flower care"
MAC address:   C4:7C:8D:62:84:72
Firmware:      2.9.4
[2017-08-27 09:41:48] Initial connection to Mi Flora sensor "Zierkastanie" (C4:7C:8D:62:84:72) successful

[2017-08-27 09:41:48] Announcing Mi Flora devices to MQTT broker for auto-discovery ...

[2017-08-27 09:41:49] Generating openHAB "miflora.items" file ...
// miflora.items - Generated by miflora-mqtt-daemon.
// Adapt to your needs! Things you probably want to modify:
//     Room group names, icons,
//     "gAll", "broker", "UnknownRoom"

// Mi Flora specific groups
Group gTemperature "Mi Flora Air Temperature elements" (gAll)
Group gBattery "Mi Flora Sensor Battery Level elements" (gAll)
Group gConductivity "Mi Flora Soil Conductivity/Fertility elements" (gAll)
Group gMoisture "Mi Flora Soil Moisture elements" (gAll)
Group gLight "Mi Flora Sunlight Intensity elements" (gAll)

// Mi Flora "Zierkastanie" (C4:7C:8D:62:84:72)
Number UnknownRoom_Zierkastanie_Temperature "UnknownRoom Zierkastanie Air Temperature [%.1f °C]" <text> (gUnknownRoom, gTemperature) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.temperature)]"}
Number UnknownRoom_Zierkastanie_Battery "UnknownRoom Zierkastanie Sensor Battery Level [%d %%]" <text> (gUnknownRoom, gBattery) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.battery)]"}
Number UnknownRoom_Zierkastanie_Conductivity "UnknownRoom Zierkastanie Soil Conductivity/Fertility [%d µS/cm]" <text> (gUnknownRoom, gConductivity) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.conductivity)]"}
Number UnknownRoom_Zierkastanie_Moisture "UnknownRoom Zierkastanie Soil Moisture [%d %%]" <text> (gUnknownRoom, gMoisture) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.moisture)]"}
Number UnknownRoom_Zierkastanie_Light "UnknownRoom Zierkastanie Sunlight Intensity [%d lux]" <text> (gUnknownRoom, gLight) {mqtt="<[broker:miflora/zierkastanie:state:JSONPATH($.light)]"}

[2017-08-27 09:41:49] Retrieving data from sensor "Zierkastanie" ...
[2017-08-27 09:41:49] Result: {"temperature": 23.2, "battery": 100, "conductivity": 16, "moisture": 13, "light": 89}
[2017-08-27 09:41:49] Publishing to MQTT topic "miflora/zierkastanie"

[2017-08-27 09:41:50] Sleeping (300 seconds) ...

[2017-08-27 09:46:50] Retrieving data from sensor "Zierkastanie" ...
[2017-08-27 09:46:52] Result: {"temperature": 23.2, "battery": 100, "conductivity": 17, "moisture": 13, "light": 178}
[2017-08-27 09:46:52] Publishing to MQTT topic "miflora/zierkastanie"

[2017-08-27 09:46:52] Sleeping (300 seconds) ...

and with sudo systemctl status miflora.service I get:

[09:47:15] openhabian@openHABianPi:~$ sudo systemctl status miflora.service
[sudo] password for openhabian:
â—Ź miflora.service - Xiaomi Mi Flora Plant Sensor MQTT Client/Daemon
   Loaded: loaded (/etc/systemd/system/miflora.service; enabled)
   Active: active (running) since So 2017-08-27 09:38:17 CEST; 9min ago
     Docs: https://github.com/ThomDietrich/miflora-mqtt-daemon
 Main PID: 414 (python3)
   Status: "Aug 27 09:44:18 - Status messages published."
   CGroup: /system.slice/miflora.service
           └─414 python3 /opt/miflora-mqtt-daemon/miflora-mqtt-daemon.py

Aug 27 09:38:17 openHABianPi systemd[1]: Started Xiaomi Mi Flora Plant Sensor MQTT Client/Daemon.
[09:47:58] openhabian@openHABianPi:~$

and vim /opt/miflora-mqtt-daemon/config.ini shows:

[09:06:53] openhabian@openHABianPi:/opt/miflora-mqtt-daemon$ vim /opt/miflora-mqtt-daemon/config.ini

# The period between two measurements in seconds (Default: 300)
period = 300

[MQTT]

# The hostname or IP address of the MQTT broker to connect to (Default: localhost)
hostname = localhost

# The TCP port the MQTT broker is listening on. SSL/TLS currently not implemented (Default: 1883)
port = 1883

# Maximum period in seconds between ping messages to the broker. (Default: 60)
keepalive = 60

# The MQTT base topic to publish all Mi Flora sensor data topics under.
# Default depends on the configured reporting_mode (mqtt-json: miflora, mqtt-homie: homie)
base_topic = miflora
#base_topic = homie

# Homie specific: The device ID for this daemon instance (Default: miflora-mqtt-daemon)
#homie_device_id = miflora-mqtt-daemon

# The MQTT broker authentification credentials (Default: no authentication)
username = xxxxxxxxxxxxx
password = xxxxxxxxxxxxx

[Sensors]

# Add your Mi Flora sensors here. Each sensor consists of a name and a Ethernet MAC address.
# Additional location information can be added to the name, delimited by an '@'.
# Scan for sensors from the command line with:
#    $ sudo hcitool lescan
#
# Examples:
#
#Schefflera@Living = C4:7C:8D:11:22:33
#JapaneseBonsai    = C4:7C:8D:44:55:66
#Petunia@Balcony   = C4:7C:8D:77:88:99
Zierkastanie@UnknownRoom = C4:7C:8D:62:84:72

and sudo hcitool lescan shows:

[09:48:08] openhabian@openHABianPi:~$ sudo hcitool lescan
LE Scan ...
10:F9:0D:F2:15:E3 (unknown)
C4:7C:8D:62:84:72 (unknown)
C4:7C:8D:62:84:72 Flower care
C4:7C:8D:65:68:04 (unknown)
C4:7C:8D:65:68:04 Flower care

Do I have to install and config the mqtt-binding? Or should it work without that?

@ThomDietrich You asked …

I’m using prpoerty specific groups. But at this moment I just have been impatient!
I couldn’t wait to see the miflora sensor up and running in my openHAB-UI.
.

Have not thought much about it.

Yes, I like that.

Have never worked with GitHub. Need to find a a good starting point, how to file an Issue on GitHub.
And at the moment I also need to learn at least a little bit about MQTT, to understand how it works.
And json, vim, linux … !? :sweat_smile:

Thank you!

Btw: Thank you for this tutorial and all your explanations! And of course for openhabian!!!
Without this, I wouldn’t have come as far as I am now.

That’s a very common problem and you’d always debug it the same way:

  • Check your items definition
  • Check events.log for incoming value changes
  • Check the binding and its configuration

The rest of your snippets looks good so I guess the problem is:

Of course :slight_smile: Check the items definition, they are bound to mqtt binding channels… Install the mqtt binding and configure it to connect to your broker (name it “broker”).

Okay I’ll look into that.

GitHub is easy if you start with the wish to create issues and comment on stuff, it’s not more complicated than this forum.

Sure thing. Glad it’s helpful to others! :wink:

1 Like

Installed it, but not sure about broker.url=tcp://localhost:1883

[13:15:30] openhabian@openHABianPi:/etc/openhab2/services$ vim mqtt.cfg
#
# Define your MQTT broker connections here for use in the MQTT Binding or MQTT
# Persistence bundles. Replace <broker> with an ID you choose.
#

# URL to the MQTT broker, e.g. tcp://localhost:1883 or ssl://localhost:8883
broker.url=tcp://localhost:1883

# Optional. Client id (max 23 chars) to use when connecting to the broker.
# If not provided a random default is generated.
#broker.clientId=<clientId>

# Optional. True or false. If set to true, allows the use of clientId values
# up to 65535 characters long. Defaults to false.
# NOTE: clientId values longer than 23 characters may not be supported by all
# MQTT servers. Check the server documentation.
broker.allowLongerClientIds=false

# Optional. User id to authenticate with the broker.
broker.user=openhabian

# Optional. Password to authenticate with the broker.
broker.pwd=xxxxxx

# Optional. Set the quality of service level for sending messages to this broker.
# Possible values are 0 (Deliver at most once),1 (Deliver at least once) or 2
# (Deliver exactly once). Defaults to 0.
broker.qos=0

# Optional. True or false. Defines if the broker should retain the messages sent to
# it. Defaults to false.
broker.retain=false

# Optional. True or false. Defines if messages are published asynchronously or
# synchronously. Defaults to true.
broker.async=true

# Optional. Defines the last will and testament that is sent when this client goes offline
# Format: topic:message:qos:retained <br/>
#broker.lwt=<last will definition>

No incoming values for miflora. :confused:

Should I install the MQTT-Actions addon?

I’m confused about the following message, when I do python3 /opt/miflora-mqtt-daemon/miflora-mqtt-daemon.py

[2017-08-27 09:41:49] Generating openHAB “miflora.items” file …

I don’t see a file named miflora.items. I only see my own MiFloraPlantSensor01.items

But there are items in PaperUI > Configuration > Items:

Config looks good. Check openhab.log to learn if the broker is connecting successfully. After that’s the case items bound to correct topics should update.

Nope. You are not sending any data back.

My bad. The message is misleading. The program is only generating the command line output. Writing to a file is your responsibility (I am not going to mess around in the end users openHAB config).
The whole feature is not finished yet. I intended to add command line arguments and then only generate the items after an explicit command, something like:

python3 /opt/miflora-mqtt-daemon/miflora-mqtt-daemon.py --generate-oh-items

I hope so :slight_smile: These are the ones defined in your MiFloraPlantSensor01.items

Seems like broker is connecting successfully.

2017-08-27 20:23:33.353 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'MiFloraPlantSensor01.items'
2017-08-27 20:23:47.478 [INFO ] [arthome.ui.paper.internal.PaperUIApp] - Started Paper UI at /paperui
2017-08-27 20:23:47.801 [INFO ] [panel.internal.HABPanelDashboardTile] - Started HABPanel at /habpanel
2017-08-27 20:23:48.105 [INFO ] [penhab.io.transport.mqtt.MqttService] - MQTT Service initialization completed.
2017-08-27 20:23:48.116 [INFO ] [t.mqtt.internal.MqttBrokerConnection] - Starting MQTT broker connection 'broker'

In debug-mode I see

2017-08-27 16:25:16.970 [DEBUG] [o.client.mqttv3.internal.ClientState] - paho68433445849: pending send key=2 message SUBSCRIBE names:[] qos:[]
2017-08-27 16:25:16.969 [DEBUG] [o.client.mqttv3.internal.ClientState] - paho68433445849: received key=1 token=org.eclipse.paho.client.mqttv3.MqttToken@195fc09 message=SUBACK msgId 1 granted Qos 0
2017-08-27 16:25:16.971 [DEBUG] [ient.mqttv3.internal.CommsTokenStore] - paho68433445849: key=2 message=SUBSCRIBE names:[] qos:[]
2017-08-27 16:25:16.972 [DEBUG] [ient.mqttv3.internal.CommsTokenStore] - paho68433445849: key=2 token=org.eclipse.paho.client.mqttv3.MqttToken@198173d
2017-08-27 16:25:16.972 [DEBUG] [o.client.mqttv3.internal.ClientState] - paho68433445849: new work or ping arrived 
2017-08-27 16:25:16.973 [DEBUG] [o.client.mqttv3.internal.CommsSender] - paho68433445849: network send key=2 msg=SUBSCRIBE names:[] qos:[]
2017-08-27 16:25:16.974 [DEBUG] [o.client.mqttv3.internal.ClientState] - paho68433445849: sent bytes count=4
2017-08-27 16:25:16.975 [DEBUG] [o.client.mqttv3.internal.ClientState] - paho68433445849: sent bytes count=23
2017-08-27 16:25:16.976 [DEBUG] [qttv3.internal.wire.MqttOutputStream] - null: Attempting to reconnect client: SUBSCRIBE names:[] qos:[]
2017-08-27 16:25:16.977 [DEBUG] [o.client.mqttv3.internal.ClientState] - paho68433445849: key=2
2017-08-27 16:25:16.977 [DEBUG] [se.paho.client.mqttv3.internal.Token] - paho68433445849: > key=2
2017-08-27 16:25:16.978 [DEBUG] [o.client.mqttv3.internal.ClientState] - paho68433445849: wait for new work or for space in the inflight window
2017-08-27 16:25:16.967 [DEBUG] [org.apache.http.wire                ] - << "          <relatedStateVariable>A_ARG_TYPE_LIST_URI</relatedStateVariable>[\n]"
2017-08-27 16:25:16.978 [DEBUG] [o.client.mqttv3.internal.ClientState] - paho68433445849: received bytes count=1
2017-08-27 16:25:16.985 [DEBUG] [o.client.mqttv3.internal.ClientState] - paho68433445849: received bytes count=3
2017-08-27 16:25:16.974 [DEBUG] [se.paho.client.mqttv3.internal.Token] - paho68433445849: >key=1 response=SUBACK msgId 1 granted Qos 0 excep=null
2017-08-27 16:25:16.972 [DEBUG] [e.paho.client.mqttv3.MqttAsyncClient] - paho68433445849: <

Complete openhab.log and events.log files.
openhab.log.xml (15.2 KB)
events.log.xml (158.8 KB)

Openhab.log files in debug-mode are too big to upload.
Edit: Uploaded short part of Openhab.log file in debug-mode.
openhab.log_debugmode.xml (11.4 KB)

I couldn’t find something related to miflora items.

Hey, I’ve added a another change improving the openHAB items function. The function is now called with

python3 /opt/miflora-mqtt-daemon/miflora-mqtt-daemon.py --gen-openhab

and now also includes groups for all Mi Flora sensors as well as per sensor.

@anfaenger you need to go at your issue step by step. That’s nothing anyone can do easily for you… :slight_smile:
Your log says the connection was established. Wonderful. First make sure that messages by the plants are indeed published to the broker. Use a stand alone broker for that. I can recommended mqtt-spy. Next check if your openHAB items are properly set up with the correct topics (the generated topics should be okay). This should not be problematic. Just give it a shot :wink:

Have tried the new command. It works very well.
And with copy & paste I put the listed items in my item-file.
Did not understand the first, but now I’ve got it.
Very helpfull! :+1:

I’ll trie that.

Thanks.

it works… thx @ThomDietrich

1 Like