Skip to main content

Hunter Hydrawise

Driver: hydrawise

Cloud integration with Hunter Hydrawise irrigation controllers via the Hydrawise v2 GraphQL API. The driver signs in with the account email and password (OAuth2 password grant), auto-creates a GEM zone for each controller zone on startup, polls per-zone watering state and water usage, tracks the controller's rain/flow sensors as device attributes for automation triggers, and supports run, stop, suspend, and resume actions per zone or controller-wide.

No API key required

Unlike the legacy v1 REST integration, this driver does not use an API key. It works for accounts that cannot generate one — including trial and simulated controllers. The bearer token from sign-in expires after about an hour and is refreshed automatically.

Prerequisites

  • A Hydrawise account email and password.
  • At least one controller on the account — physical or simulated/trial; both are visible over the GraphQL API.

Setup

  1. In GEM, System → Devices → Add Device with driver hydrawise.
  2. Enter the Hydrawise account email and password (the password is stored encrypted).
  3. If the account has more than one controller, set controller_id (run get_controllers to list them). With a single controller this is auto-detected.
  4. Save. The driver logs in, resolves controllers, auto-creates a GEM zone for each controller zone, and begins polling. GEM ships with a dedicated irrigation subsystem, so this works out of the box — no subsystem setup is required. Each new zone is created under the first existing subsystem named irrigation, water, or sprinkler (normally irrigation; older sites provisioned before the irrigation subsystem existed fall back to water), is given the on/off water control, takes its label from the controller's zone name, and has its address set to the Hydrawise zone id. Set auto_sync_zones to false to disable auto-creation and manage zones by hand.
  5. To add or repair zones manually, run get_zones to list the zone id values (or run sync_zones to re-ensure them). zone.address is always the Hydrawise zone id, not the physical valve number.

Attributes

Device

AttributeRequiredDefaultDescription
emailyesEmail used to sign in to the Hydrawise app.
passwordyesPassword used to sign in (stored encrypted).
controller_idnoRequired when the account has more than one controller (from get_controllers). Auto-detected for single-controller accounts.
default_run_secondsno300Default run duration when seconds is not supplied to a run command.
min_poll_intervalno60Idle polling cadence (seconds) against the GraphQL API, used while no zone is watering. The web client is event-driven and the legacy API floored at ~60s — keep this at 60s or higher to avoid throttling.
active_poll_intervalno30Active polling cadence (seconds), used only while a zone is actively watering so time_remaining counts down responsively. Reverts to the idle interval once all zones stop.
auto_sync_zonesnotrueEnsure a GEM zone exists for each controller zone on connect. Set false to manage zones manually.
water_usage_intervalno600How often (seconds) week-to-date per-zone water usage is refreshed (kept off the fast poll).

Sensor readings tracked at the controller (device) level for use as automation trigger sources:

AttributeDescription
rain_sensor_activetrue when the controller's rain sensor is holding watering.
flow_rateLive flow-meter reading in litres/min; 0 when no flow sensor is present.
Water Flow dashboard

The controller's flow_rate and the per-zone water_usage_week are tagged with the water.flowrate / water.usage metric roles, so a Hydrawise controller appears automatically in the generic Water Flow widget — a live supply → zones diagram. See Power Management → The Water Flow widget.

Zone

zone.address is the Hydrawise zone id from get_zones. Driver-managed state attributes:

AttributeDescription
stateon while scheduledRuns.currentRun is present, off otherwise.
time_remainingSeconds left in the current run (currentRun.remainingTime); 0 when idle.
next_runSeconds until the next programmed run (from nextRun.startTime); meaningful when idle.
next_run_strHuman-readable schedule summary (mirrors the API's scheduledRuns.summary).
suspended_untilEpoch seconds the zone is suspended until, or 0 if not suspended.
water_usageWater delivered in the current run, in litres; 0 when idle.
water_usage_weekWeek-to-date water usage for the zone, in litres (refreshed on a throttle and via get_water_usage).

Water volumes are stored in canonical litres regardless of the account's display units (the API reports gallons or litres per locale; the driver converts).

You can also set one configurable attribute on a zone (in the zone's Attributes editor):

AttributeDefaultDescription
default_run_secondsfalls back to the device's default_run_seconds (300)Per-valve run duration used when a run / on command is sent to this zone without an explicit seconds argument. Overrides the device-level default for this zone only.

Commands

CommandArgsEffect
on / runaddress, optional secondsStart a manual run on the zone.
off / stopaddressStop the zone.
suspendaddress, hoursSuspend the zone for the given number of hours.
resumeaddressResume a suspended zone (native resumeZone).
runalloptional secondsStart all zones on the controller.
stopallStop all zones on the controller.
suspendallhoursSuspend all zones for the given number of hours.
resumeallResume all zones on the controller (native resumeAllZones).
get_controllersList controllers visible to the account (id, name, online, serial).
get_zonesList zones with their id, number, name, and controller.
sync_zonesEnsure a GEM zone exists for each controller zone (idempotent; runs automatically on connect unless auto_sync_zones is false).
get_water_usageoptional addressRefresh and return per-zone current-run and week-to-date water usage (litres).

The controller-wide commands (runall, stopall, suspendall, resumeall) require a resolved controller — set controller_id on multi-controller accounts.

on / run, off / stop, and stopall update the affected zone's state and time_remaining optimistically the moment the controller accepts the action, so the UI reflects the change immediately rather than waiting up to a poll interval. The next poll reconciles against the controller's real state.

Known limitations

  • Token lifetime. The OAuth bearer token expires after ~1 hour and is refreshed automatically, falling back to a fresh login if the refresh token is rejected.
  • Suspend date format. suspend / suspendall send the suspension end time in the GraphQL until argument as an RFC-822 string with a two-digit year and a numeric UTC offset (e.g. Thu, 04 Jun 26 16:41:04 +0000). ISO-8601, epoch, and four-digit-year forms are rejected with Invalid date format. Verified live against a real controller.
  • Sensor classification. Rain vs flow sensors are distinguished by response shape (a flow meter reports status.waterFlow; a rain sensor reports status.active). The controller used for verification had no sensors attached, so this mapping is correct-by-construction rather than confirmed against live sensor hardware.

Troubleshooting

SymptomCheck
Driver never connects / missing email or passwordVerify the email and password device attributes are set and correct.
All-zone commands return controller_id requiredThe account has multiple controllers — set controller_id (run get_controllers to list them).
Zone commands do nothingzone.address must be the Hydrawise zone id from get_zones, not the physical valve number.
Zones aren't auto-created on connectAn irrigation subsystem ships by default, so this normally just works. If it was deleted, recreate an irrigation, water, or sprinkler subsystem; also confirm auto_sync_zones is not false, then run sync_zones.
Login fails after working previouslyThe account password may have changed, or the account may be locked. Re-enter the password.