GitHub - AdrianCX/picohive-irrigation: Pico W irrigation controller with Google Calendar and Telegram control

GitHub

6 min read Original article ↗

Standalone Raspberry Pi Pico W Irrigation
Controlled via Telegram/Google Calendar or an internal web page.

1. Main box

2. Cover open 3. Wires before the sheath 4. USB power connector
2. Open 3. Wires 4. USB

Videos: 1, 2

History

This started as a MicroPython project controlled from a separate Pi 4
That seemed wasteful, why not put telegram/google calendar directly on the pico?
... famous last words ...

Some time later, it's working, efficiently, securely, all on pico
To do that, I had to set up a whole firmware to handle things os

While doing that, another idea, have a nice (optional) central web page to help manage things:

  • Deploy firmware updates (encrypted/signed)
  • View device logs (have devices send logs encrypted via UDP)
  • View resolved crash callstacks and get alarms when devices crash

That's available at: https://picohive.com, signups free with device limits, will be open source if I ever close it down

As things usually go, why not add a linux build? valgrind/gdb would be nice, this will surely go faster ...
... famous last words again ... See Linux simulator to build/run with hardware mocks

How it looks

Pictures of web page in dark mode (it follows system settings, light mode is available as well)

5. General 6. Telegram 7. Calendar
5. General 6. Telegram 7. Calendar

The page has skins, because why not:

8. Original 9. Xenoform 10. Fallout
8. Original 9. Xenoform 10. Fallout

Telegram menu

Type /start in the chat and the bot replies with a menu (pin it to keep it handy): one row per valve (left, right, all), with off, 30s, 10m and 30m buttons.
It also sends a message whenever a valve opens or closes.

11. Telegram menu

Google Calendar

Any iCal compatible calendar will work, showing off google calendar since that's what I use:

  • Event title issues commands, format: <device id>/water/<valve>/<time>
  • Event start is what's used to trigger command, length doesn't matter, all day events are ignored
  • Example: garden/water/1/30m opens valve 1 for 30 minutes, garden/water/0/30s opens all valves for 30s
  • Hardcoded maximum limit of 60 minutes to prevent mishaps
  • Only commands in the Allowed setting run (ex: water stop, or water/1 for just valve 1)
  • Recurring events work, delete a single occurrence to skip a day

12. Google Calendar

How do I set it up

What you may need before setting up

  1. Picohive (optional)
    Add Device on picohive (generate the UUID, MQTT password and log key, pick a name)
    Open the device, go to Device Config, press Export and copy the line for step 4 below\
13. Add Device 14. Device Config 15. Export
13. Add Device 14. Device Config 15. Export
  1. Telegram bot (optional)
    Create a bot: /newbot to BotFather, save the token, add bot to a group, type /start choose-a-code

  2. Google calendar (optional)
    Create a new calendar (that doesn't accept invites), save the private iCal address

Device setup

  1. Flash a pico, it starts as access point picow_config / randompassword (yes, I know)
  2. Connect to the access point, the page opens by itself, if not, use http://192.168.4.1
  3. Configure wifi and a user/pass for the web ui
  4. Optional:
    4.1. Remote server enter line from picohive for logging/OTA/crash reporting
    4.2. Telegram enter token, enable Use the first chat..., enter choose-a-code from setup
    4.3. Calendar enter private iCal address, a device id (ex: garden) and the allowed commands (ex: water stop)\
  5. Reboot - everything works as configured - logs in picohive, events from telegram and calendar
  6. Reconfigure any time from its new ip address (find it in picohive logs or on router)
16. Wifi and login 17. Remote server 18. Telegram 19. Calendar
16. Wifi and login 17. Remote server 18. Telegram 19. Calendar

Buttons

  • 🟢 Green opens both valves for 30 minutes
  • 🔴 Red closes everything

Building

git clone --recursive <this repo>
cd irrigation
os/build_via_podman.sh pico2_w      # or pico_w

Flash build/<board>/irrigation.uf2 over USB
Later updates for OTA need the encrypted file irrigation.uf2.encrypted
Before you build your own, create your own OTA keys and certificate, as described in os/docs/ota.md.

Layout:

  • src/main.cpp: valve/button pins, Telegram menu, listeners
  • src/irrigation_manager.cpp: valve timers and button handling
  • src/commands/: water, stop, status
  • src/web/: page and text config

Linux simulator

The same app builds as a Linux program, with the hardware mocked
You can use it to work on the web page and the command logic without flashing anything
You can use gdb or valgrind as needed

os/build_via_podman.sh linux        # build/linux/irrigation
os/run_via_podman.sh                # http://localhost:8080, https://localhost:8443
os/run_via_podman.sh --valgrind     # or --gdb

Memory usage

From the Pico W in my garden (HTTPS server is off on RP2040).
MinFree is likely the peak: 3 TLS connections open at once (MQTT over TLS, Telegram, Calendar) plus the web page

[2026-10-20 19:29:33] 192.168.100.11 60 app[build/pico_w/irrigation] version[5087e39-dirty] os[v2.03-92-gadb6f5e-dirty] buildid[1b3204487b8a90a1c59ad4310d3cb7ebb97cc9ed] Heap[19144/228872] Free[209728] MinFree[131072] LargestFree[135124] Stack[2688/16384] lastRestartReason[reboot_command]
Heap in use 19KB of 224KB (8%)
Lowest free since restart 128KB
Largest free block 132KB, so fragmentation is low
Stack peak 2.6KB of 16KB
Last restart reboot command, not a crash

Hardware

Pictures 1-4 at the top.

20. Wiring

Wiring:

  • DRV8833: valve 1 on GPIO 16/17, valve 2 on GPIO 18/19, sleep on GPIO 15
  • Buttons: green on GPIO 13, red on GPIO 12, other leg to GND (internal pull-up)

These are the defaults in src/main.cpp, change them there if you wire it differently

Parts

I mostly used parts I already had, so there are simpler options if you're starting from scratch
I would advise Pico2 W for more RAM / flash / secure boot / OTP

Main box:

Power:

  • A long 2-wire cable carrying 5V (example)
  • 2x polyfuses on a proto board with screw terminals, one on 5V and one on GND (probably not needed, but in case of a short)
  • 3500uF electrolytic capacitor across VSYS/GND, 10V or higher
  • A USB power supply and a USB cable with one end cut off

Valves and plumbing:

License

MIT for this app. The os/ submodule is MPL-2.0, see its LICENSE.