/plantcare

Xiaomi Mi Flora Plant Sensor telegram notifier

Primary LanguagePython

PlantCare: Xiaomi Mi Flora Plant Sensor telegram notifier

A monitoring tool to read Xiaomi Mi Flora sensors and to send notifications via Telegram if readings are out of configured boundaries.

As the official Xiaomi app doesn't always meet our expectation, this tool can help to look after your plant if you have a spare home server (or whatsoever with docker inside) with Bluetooth.

Supported parameters

Parameter alias
Soil moisture moisture
Light intensity light
Soil fertility conductivity
Temperature temperature
Battery charge battery

Set up

1. Create a telegram bot

Follow instructions here: https://core.telegram.org/bots#3-how-do-i-create-a-bot

A bot token will be used for configuration later.

Then you need to add the bot to a telegram channel and get a channel id. The easiest way to know what is the channel id is to check bot's status updates: https://api.telegram.org/bot<BotToken>/getUpdates Look at the response json. The channel id will be in "id" field of the "chat" object.

2. Build

docker build -t plantcare .

3. Create a configuration json

The full configuration json is as follows:

{
  "loglevel": "INFO",
  "telegram": {
    "token": "3059511111:ZZZZ-ZZZZZZZZZZZZZZZZZZZZZZ-AAAAAAA",
    "channel": "-321012345",
    "message": {
      "parse_mode": "MarkdownV2",
      "moisture": "*{plant}*\nMoisture is out of the boundaries*: {boundaries}\n*Current value*: {value}",
      "light": "*{plant}*\nLight is out of the boundaries*: {boundaries}\n*Current value*: {value}",
      "temperature": "*{plant}*\nTemperature is out of the boundaries*: {boundaries}\n*Current value*: {value}",
      "battery": "*{plant}*\nBattery level is out of the boundaries*: {boundaries}\n*Current value*: {value}",
      "conductivity": "*{plant}*\nFertility is out of the boundaries*: {boundaries}\n*Current value*: {value}"
    }
  },
  "adapter": "hci0",
  "max_attempts": 5,
  "sensors": {
    "Rose": {
      "mac": "10:EA:BA:58:10:B8",
      "wellbeing_range": {
        "moisture": {
          "min": 40,
          "max": 50
        },
        "conductivity": {
          "min": 19
        }
      }
    }
  }
}

Where wellbeing_range in the sensors section can have boundaries for multiple parameters.

loglevel (optional, default is "INFO")
Logging level for docker log output.

telegram : token (required)
Telegram bot token

telegram : channel (required)
Telegram channel id

telegram : message : parse_mode (optional, default is "MarkdownV2")
See https://core.telegram.org/bots/api#formatting-options

telegram : message : {moisture|light|battery|temperature|conductivity} (optional, defaults is "{plant}: 'PARAM' parameter is out of boundaries '{boundaries}'")
Notification templates for messages sent via telegram in case of readings are out of configured boundaries. You can overwrite none, one, or all of them in your config json.

A message template for a parameter (moisture, light, battery, temperature, or conductivity) may contain the following template placeholders:

  • {plant} - a plant name (see sensors bellow)
  • {boundaries} - configured boundaries for the sensor parameter. Depending on a wellbeing_range configuration (see sensors bellow), it can be [min, max] (if both min and max are configured), or ≥ min, or ≤ max)
  • {value} - a parameter value

A template formatting should follow Telegram formatting rules for a chosen parse_mode: https://core.telegram.org/bots/api#formatting-options

Don't forget escaping.

adapter (optional, default is "hci0")
In most cases the adapter name is "hci0". You can check it (or what other adapters you have in your system) by running this command:

docker run --rm plantcare ls /sys/class/bluetooth/

max_attempts (optional, default is 5) How many times it will try to connect to and to read from each sensor before giving up.

sensor (required)
A collection of objects where keys are sensors'/plants' names. They will be used for the {pant} placeholder in the message templates.

sensor : {plant} : mac (required)
Sensor's mac address. Run this command to see all bluetooth devices nearby (make sure you are close enough to the sensor):

docker run --net=host --privileged -it --rm plantcare blescan -a

And see device(s) which has "Complete Local Name: 'Flower care'" in the output.

sensor : {plant} : wellbeing_range (required)
A collection of objects where keys are parameter aliases (see above) and values are intervals. Intervals can have both min and max, or only one min/max. A notification regarding a parameter will not be sent while the parameter value is within wellbeing_range.

A minimal configuration json can be like this:

{
  "telegram": {
    "token": "3059511111:ZZZZ-ZZZZZZZZZZZZZZZZZZZZZZ-AAAAAAA",
    "channel": "-321012345",
    "message": {
      "moisture": "*{plant}* need to be watered"
    }
  },
  "sensors": {
    "Rose": {
      "mac": "10:EA:BA:58:10:B8",
      "wellbeing_range": {
        "moisture": {
          "min": 40
        }
      }
    }
  }
}

4. Run it

CONFIG environment variable should be passed with the configuration json (using --env or --env-file).

docker run --net host --rm --env CONFIG='{"telegram":{"token":"3059511111:ZZZZ-ZZZZZZZZZZZZZZZZZZZZZZ-AAAAAAA","channel":"-321012345","message":{"moisture":"*{plant}* need to be watered"}},"sensors":{"Rose":{"mac":"10:EA:BA:58:10:B8","wellbeing_range":{"moisture":{"min":40}}}}}' plantcare 

PlantCare app doesn't work in a daemon mode. However you can schedule periodical checks by crontab or willfarrell/crontab

Troubleshooting

If you see a connection error in logs, there are many possible reasons besides a typo in the config:

  1. your Bluetooth device is down
  2. LE capabilities are not enabled on your Bluetooth device
  3. both above
  4. something else

Bluetooth device is down

Check it on the host:

sudo hciconfig

The device you want to connect should have "UP RUNNING" status. If not run it:

sudo hciconfig hci0 up

LE capabilities are not enabled

If the device is up and running, but still can't connect to a sensor, try to enable LE:

sudo btmgmt le on

Remember to do so after reboot. Alternatively, you can do the same in small docker image

FROM alpine:3.12
RUN apk add --no-cache bluez-deprecated bluez-btmgmt
COPY your_script.sh /usr/src/scripts
CMD [ "ash", "your_script.sh" ]

And run it (with --net=host --privileged) in one docker-compose bundle with PlantCare.