How I Taught a Plant to Email Me (and Water Itself)

A humorous adventure: ESP8266 + ServiceNow + a very thirsty ficus
GitHub Repository: https://github.com/JBMatthews/self-watering-system

Introduction

My plant was silently judging me. Instead of just watering it like a normal person,
I decided to turn it into a full-blown IoT + ServiceNow integration project.
Why? Because I wanted to learn, practice cloud-to-hardware workflows, and prove that even a ficus can file a ServiceNow record.

Architecture Overview

  • ESP8266 reads capacitive soil moisture sensor
  • If too dry → toggles relay → pump runs
  • Posts JSON payload to ServiceNow Scripted REST API
  • ServiceNow logs it, Flow Designer emails me
  • Now Mobile app shows all the logs in real time

Hardware

  • ESP8266 dev board
  • Capacitive soil moisture sensor
  • 4‑channel relay (using one relay for now)
  • 5V submersible pump + tubing
  • USB 5V/2A wall adapter

Firmware

secrets.py

WIFI_SSID = "your_wifi"
WIFI_PASSWORD = "your_password"
SERVICENOW_INSTANCE = "https://your-instance.service-now.com"
SERVICENOW_ENDPOINT = "/api/x_461782_slf_water/self_watering_api/log"
SERVICENOW_USER = "admin"
SERVICENOW_PASS = "password"
RELAY_PIN = 14
MOISTURE_THRESHOLD = 30
WATERING_DURATION = 3
SLEEP_DURATION = 300
SATURATION_WAIT = 60

main.py (Core Logic)

Handles Wi-Fi connection, sensor reading, watering logic, saturation re-check, and logging back to ServiceNow.

def loop():
    wifi()
    while True:
        pct = moisture_percent()
        watered, status, note = False, "ok", "Reading only"
        if pct < secrets.MOISTURE_THRESHOLD:
            status, note = "dry", "Auto watering"
            water(secrets.WATERING_DURATION)
            watered = True
            time.sleep(secrets.SATURATION_WAIT)
            pct2 = moisture_percent()
            if pct2 < secrets.MOISTURE_THRESHOLD:
                note = "Second watering after recheck"
                water(secrets.WATERING_DURATION)
                pct = pct2
            else:
                status, pct = "watered", pct2
                note = "Adequately saturated"
        post(pct, watered, note, status)
        time.sleep(secrets.SLEEP_DURATION)

ServiceNow Side

  • Tables: System (plants), Logs (moisture + actions), Settings (thresholds)
  • Scripted REST API: Receives JSON from ESP8266
  • Flow Designer: Emails me if was_watered=true
  • Now Mobile: Form updated to show all fields (moisture, status, severity, notes)

Setup Instructions

  1. Clone repo: git clone https://github.com/JBMatthews/self-watering-system
  2. Flash MicroPython to ESP8266 using Thonny
  3. Upload secrets.py with your Wi-Fi + ServiceNow credentials
  4. Upload main.py and reboot the ESP
  5. Watch logs stream into ServiceNow → Logs table

Repo Structure

self-watering-system/
├── hardware/
│   ├── esp8266/
│   │   ├── main.py        # watering logic
│   │   ├── pump_test.py   # test relay/pump
│   │   └── secrets.py     # credentials
│   └── pico/              # legacy Pico code
├── servicenow/
│   ├── api_docs.md        # REST API documentation
│   └── post_moisture_data.js # Node.js test client
├── README.md
└── docs/
    └── blog_self_watering_project.html

Roadmap

  • Phase 1: Single plant watering + email notifications
  • Phase 2: Multi‑plant (up to 4 pumps via relay)
  • Phase 3: Window garden hub with dashboard + lighting