Dec 29, 2020
I've been using Home Assistant (HA) to power my smart home for quite some time - from lighting and cameras to door and power sensors I've invested a fair bit into HA which runs on a Raspberry Pi 4 + SSD in my rack. There's basic automation such as turning on lighting at sunset, to more complex object detection that announces on Alexa when my dog (Missy) is at the backdoor and a whole lot more.
A project that's been on the list for a while brings together two of my interest: tech and gardening. I have several plants around the house which I often forget to water and so the goal was to set up soil moisture sensors that alert me when the plants are in need of water!
After a few different experiments I've settled on a solution using a capacitive soil moisture sensor and a ESP8266 chip for each pot. Right now, these are mains powered so a socket must be close by but fortunately that was the case for all my plants. (Future project: outdoor plant monitoring, perhaps with battery sensors + Zigbee).
Experiment #1: VegTrug/Xiaomi MiFlora Plant Monitor
Initially, I ordered one of the well known VegTrug/MiFlora monitors - for around £18 including shipping. They are a two pronged soil monitor that communicates sensor information over Bluetooth - they are battery powered. They include sensors for: brightness, temperature, soil moisture & conductivity. While these worked quite well, I was disappointed with the battery life which only lasted a couple of months but the biggest issue was with the Bluetooth range. Being Bluetooth, this meant they needed to be in range of my Raspberry Pi to emit sensor data. This was not a solution for all the plants in my house and therefore I looked for some kind of Bluetooth gateway that could be placed in each room, and transmit data for each plant in the room to HA over WiFi.
Experiment #2: ESP32 Bluetooth Sensor + VegTrug
To act as a Bluetooth gateway for the VegTrug/Xiaomi sensors, I purchased a ESP32 board with both Bluetooth and WiFi and configured the built in Bluetooth LE Tracker Hub on the ESP to watch for the sensor packets and then transmit them over WiFi to Home Assistant. This worked well.
sensor: - platform: xiaomi_hhccjcy01 mac_address: 'XX:XX:XX:XX:XX:XX' temperature: name: 'Anthurium Temperature' moisture: name: 'Anthurium Moisture' illuminance: name: 'Anthurium Illuminance' conductivity: name: 'Anthurium Conductivity' battery_level: name: 'Anthurium Battery Level'
However, the ease of setting this ESP up and the high cost of the VegTrug monitors got me thinking - perhaps there was a (better/cheaper) way to build something myself using an ESP chip and a soil sensor. Enter the final solution!
Solution: ESP8266 + Capacitive Soil Moisture Sensor
Having seen how easy it was to setup ESP chips using ESPHome and Home Assistant I set out to build a basic soil sensor and was impressed by how straightforward it was.
- ESP8266 Board - £4/each
- Capacitive Soil Moisture Sensor (v2.0) - £1/each
- Enclosure for soil sensor - £1/each
- Enclosure for ESP - £3/each
- USB Charger (two ports so can power two nearby plants) - £9/each
- Micro USB cables - £1.30/each
- I also used some jumper cables, heatshrink and expoy I had at home.
- Cost per sensor: £14.80~
- Connect each board to HomeAssistant over USB and run through the wizard in ESPHome to add a new chip. This will setup them up to connect over WiFi which allows you to push further firmware changes over the air.
- Wire the soil sensor to the following pins:
- VCC → 3V
- GND → Ground/G
- AOUT → A0 (ADC pin)
- Add the following YAML sensor to the chip - can now be flashed over the air.
sensor: - platform: adc unit_of_measurement: "%" icon: "mdi:flower-outline" accuracy_decimals: 0 pin: A0 filters: - calibrate_linear: - 0.3 -> 100 - 0.7 -> 0 name: "Soil Moisture Level" update_interval: 10s
4. Observe the log output in ESPHome when placing the sensor in water and dry air.
5. Reflash the YAML, changing the calibrate_linear as needed and also changing the update_interval to something more sensible, I went for 300s, e.g.
sensor: - platform: adc unit_of_measurement: "%" icon: "mdi:flower-outline" accuracy_decimals: 0 pin: A0 filters: - calibrate_linear: - 0.29 -> 100 - 0.71 -> 0 name: "Soil Moisture Level" update_interval: 300s
6. In Home Assistant, configure the automatically discovered ESP chips and that's it - the soil sensors will now appear in HA and are available for automation, dashboards etc.
I mounted the capacitive sensor in the smaller enclosure linked above using two small screws and some epoxy to seal it to avoid water entering when I watered the plants. The ESP was mounted in the larger enclosure from RS Components using some more epoxy - I had trouble finding an enclosure that would fit exactly, I'll perhaps look at a 3D printed version next time. I used a drill & soldering iron to cut holes for the sensor, micro USB port and cables - next time I will buy a Dremel!
- 3D Print cases for sensor + ESP so they are smaller / better fit
- Investigate battery powered ESP to remove need for USB cable/adapter
- Integrated brightness sensor
- Investigate lambda for ESPHome rather than filter
- Investigate only enabling power to sensor when testing moisture level to avoid unnecessary corrosion.
If you got this far, thanks for reading and feel free to reach out to me on Twitter if you've got any questions! Thanks! 👍