Avoid herb plants from running dry. Water them automatically with a pump whenever needed. Monitor moisture readings and receive notifications when level is too low through the openHAB smart home system and the MQTT messaging protocol. This was my final project for CS50x 2020.
- ESP8266 (I used a NodeMCU v2)
- Moisture sensor (I used this one)
- Water pump (I used this one, note: I found this typical Arduino pump is too weak)
- Relay (I used this one)
- Voltage regulator if your pump needs a Vcc incompatible with your board (I used this one)
- Wiring, resistors, LEDs, a power source (I use a 5.5mm terminal) etc.
- Connect to WiFi & MQTT
- Read moisture level (x times, build average)
If moisture < threshold, start water pumpStop pump when moisture threshold reached- Publish readings & pump status changes to MQTT topics
- Check for MQTT command to start pump
- If pump command received, enable pump for 5 seconds*
Note: I disabled automatic pumping seeing that the moisture sensor doesn't always return correct readings. Uncomment respective lines if you're feeling more adventurous.
openHAB integration is optional. You will need an MQTT client to read & control the pump, though. Make sure your WiFi & MQTT credentials are defined in the script.
The program will send and receive these MQTT commands:
Topic | Payload | Comment |
---|---|---|
stat/water_pump/STATUS | { "MOISTURE":"50", "PUMP_VCC":"OFF", "WATER_LEVEL":"OK" } | Published 1x per loop |
cmnd/water_pump/FLUSH | any | will turn on pump for 3 seconds |
cmnd/water_pump/FLUSH2 | any | will pump until target moisture reached |
Interpreting status messages:
- MOISTURE: Last reading (0 = dry, 100 = wet)
- PUMP_VCC: Pump ON or OFF?
- WATER_LEVEL: OK or WARNING
Bridge mqtt:broker:broker "mqtt broker" [ host="openhabianpi", port=1883, secure=false, username="XXXXXX", password="XXXXXX" ]
{
Thing topic water_pump "Water Pump" {
Channels:
Type number : water_pump_moisture_level "Moisture" [ stateTopic="stat/water_pump/STATUS", transformationPattern="JSONPATH:$.MOISTURE" ]
Type switch : water_pump_power "Pump power" [ stateTopic="stat/water_pump/STATUS", transformationPattern="JSONPATH:$.PUMP_VCC" ]
Type string : water_pump_water_level "Water level" [ stateTopic="stat/water_pump/STATUS", transformationPattern="JSONPATH:$.WATER_LEVEL" ]
Type datetime: water_pump_last_flush "Last flush"
Type datetime: water_pump_last_update "Last update"
}
}
Number water_pump_moisture_level "Moisture level [%d %%]" {channel="mqtt:topic:broker:water_pump:water_pump_moisture_level"}
Switch water_pump_power "Pump power" {channel="mqtt:topic:broker:water_pump:water_pump_power"}
String water_pump_water_level "Pump water level warning" {channel="mqtt:topic:broker:water_pump:water_pump_water_level"}
DateTime water_pump_last_update "Last update [%1$td.%1$tm.%1$tY / %1$tH:%1$tM]" { channel="mqtt:topic:broker:water_pump:water_pump_last_update" }
DateTime water_pump_last_flush "Last flush [%1$td.%1$tm.%1$tY / %1$tH:%1$tM]" { channel="mqtt:topic:broker:water_pump:water_pump_last_flush" }
Note: Google Assistant natively supports sprinklers. If you'd like to use the water pump via Google Assistant, expose the water_pump_power
item to openHAB cloud and tag it like so:
Switch water_pump_power "Pump power" {channel="mqtt:topic:broker:water_pump:water_pump_power", ga="Sprinkler"}
Default item=water_pump_moisture_level
Text item=water_pump_power
Default item=water_pump_water_level
Default item=water_pump_last_update
Default item=water_pump_last_flush
Chart item=water_pump_moisture_level label="Moisture last 24h" period=D refresh=1000
Chart item=water_pump_moisture_level label="Moisture last 1h" period=h refresh=1000
To get a push notification in the openHAB app when the water reservoir is assumed empty:
rule "water pump reservoir empty"
when
Item water_pump_water_level changed to "WARNING"
then
sendBroadcastNotification("Water pump: Out of water")
end
To update timestamps of last contact and last watering:
when
Item water_pump_power received command ON or
Item water_pump_power changed to ON
then
water_pump_last_flush.postUpdate(new DateTimeType());
end
rule "water pump update timestamp for last update"
when
Item water_pump_power received update or
Item water_pump_moisture_level received update or
Item water_pump_water_level received update
then
water_pump_last_update.postUpdate(new DateTimeType());
end