Skip to main content

OpenSprinkler

GEM integrates with OpenSprinkler — an open-source Wi-Fi sprinkler controller — over its documented local HTTP API. No cloud account is required. Each physical valve station maps to a GEM zone; on/off start or stop a manual run, and the device also exposes rain-delay, global enable/disable, reboot, and program-trigger commands.

Prerequisites

  • An OpenSprinkler v2.x or v3.x controller, OpenSprinkler Pi (OSPi), or OSBee running firmware 2.1.6 or newer.
  • Controller reachable on the LAN from the GEM server on port 80 (or the HTTP port you configured).
  • The OpenSprinkler device password. The factory default is opendoor — change it in the OpenSprinkler mobile app or web UI before deployment.

Setup

  1. In the OpenSprinkler app, confirm the controller IP and that you can run a station manually.
  2. (Recommended) Change the device password from the default.
  3. In GEM, System → Devices → Add Device with driver opensprinkler.
  4. Set ip to the controller's LAN IP. Paste your device password into password (the driver MD5-hashes it before sending; GEM stores it encrypted).
  5. Save and reload. The driver logs opensprinkler connected: <id> <name> stations: <n> once it can read station names.
  6. Run get_stations to enumerate the controller's stations and their names.
  7. Create one GEM zone per station you want to control. Set zone.address to the zero-based station index (station S01 in the OpenSprinkler app → address 0).
  8. (Optional) Set default_duration on each zone to override the device-level default manual-run duration in seconds.

Attribute reference

AttributeRequiredDefaultDescription
ipyesOpenSprinkler controller LAN IP.
passwordyesopendoorPlaintext password. Driver hashes it with MD5 before sending on every request.
portno80HTTP port on the controller.
status_intervalno10000ms between /jc polls.
default_durationno600Seconds for on when no level is provided and the zone has no default_duration.
request_timeoutno10000HTTP request timeout (ms).

Zone attributes

AttributeDescription
default_durationPer-zone override for the manual-run duration used by on. Falls back to the device default.
stateDriver-managed: on while the station is running, off otherwise.
remaining_secondsDriver-managed: seconds left in the current manual run (0 when idle).

Zone address format

zone.address is the 0-based station index. Station "S01" in the OpenSprinkler app is address 0, "S02" is 1, and so on. The driver does not change the GEM zone address representation — addresses are plain digits, no leading zeros required.

Commands

CommandArgsEffect
onaddress, optional level (seconds)/cm?sid=<addr>&en=1&t=<seconds> — start a manual run. level overrides default_duration.
offaddress/cm?sid=<addr>&en=0&t=0 — stop the station.
stop_all/cv?rsn=1 — stop every running station.
rain_delayhours (0 to clear)/cv?rd=<hours> — set rain-delay.
enable_controller/cv?en=1 — clear global disable.
disable_controller/cv?en=0 — globally suppress all irrigation.
reboot/cv?rbt=1 — soft-reboot.
run_programprogram_id/mp?pid=<id> — manually start a configured program.
get_status/jc — controller status.
get_stations/jn — station list with names.
get_programs/jp — program list.
raw_requestpathGET an arbitrary path on the controller (e.g. /jo). The pw= query is appended automatically.

set_level is not an analog dimmer here — sprinkler valves are on/off only. To pick a duration, pass it as level to the on command (in seconds).

Status polling

Every status_interval ms the driver fetches /jc and reads the ps (program-state) array, which holds [program_id, remaining_seconds, start_unix] per station. A station with remaining_seconds > 0 is reported as on with remaining_seconds set; everything else is off. The driver does not poll per-zone — one HTTP call covers the whole controller.

Known limitations

  • No remote authentication beyond the device password. The pw= parameter is MD5 of the password and is sent on every request. Use HTTPS via a reverse proxy or VPN if the controller is reachable beyond your LAN.
  • Result code 32 (not permitted). When the controller is in rain-delay or globally disabled, manual on requests are accepted but the station does not energize. Either clear the rain-delay or re-enable the controller first.
  • Station limit. OpenSprinkler v2/v3 supports up to 72 stations via expansion boards. Addresses beyond the configured count return result code 17 (out of range).
  • No event push. Status changes are visible on the next poll only. Lower status_interval to ~3000 ms for snappier UI feedback.

Troubleshooting

SymptomLikely cause
unauthorized (bad password)Password is wrong, or the controller still has the factory opendoor default while you configured something else in GEM.
out of rangeStation index is higher than the controller's configured station count. Run get_stations to confirm.
Status stuck at offController may be globally disabled or in rain-delay — run get_status and inspect en and rd.
Connection refusedOpenSprinkler is configured to a non-80 port. Set the port attribute.