Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Irrigation and history API

Use snapshots for current state and projections. Use history for recorded outcomes. All routes below are under /api/v1/irrigation.

Current state

GET /snapshot returns the irrigation snapshot. GET /stream sends the same shape as snapshot events.

FieldUse
last_refresh_epochSnapshot assembly time
timezoneLocal calendar used for planning
current_weatherSelected inputs with source, observation time, and freshness limit
zonesZone identity, planned runtime, reported state, and available soil data
zone_verdictsCurrent zone decisions
decision_traceCompared rules, reasons, and evidence
water_budgetsZone allocation and soil-model details
water_planProgressive daily projections
restart_required, restart_reasonsSaved changes that hold watering until restart

A zone’s running value must be read with running_known. ledger_running records LocalSky’s outstanding run tracking; it is not a substitute for controller confirmation. Nullable flow and soil fields remain unknown when unavailable.

Future plan

water_plan is omitted when no plan rows are available. Treat that as an unavailable projection, not a promise of no watering.

Each water_plan day contains its local date, day offset, optional start/finish times, forecast rain, expected rain, probability, evidence completeness, and zones.

Each zone names its planned seconds, reason code, reason, water need, model, and available depletion, trigger, capacity, and demand values.

next_run_state can be at, no_water_planned, no_legal_day, no_sunrise, or no_location. Check the state before interpreting next_run_epoch. A zero epoch is not a scheduled run.

These are projections. They do not prove that a valve was commanded or that water was delivered.

Runs and daily outcomes

GET /history?days=30

Returns from_epoch, to_epoch, runs, and daily. The default range is 30 days. days=0 requests all retained records; positive ranges are bounded to 36,500 days.

Run records include:

  • zone, start_epoch, duration_s
  • source, status, nullable skip_reason
  • nullable session_id, controller_id, note
  • nullable applied_mm, volume_gal
  • nullable cycle_index, cycle_count

Use session IDs to group related records. For applied-water totals, use the union of valve-open intervals per zone; overlapping command and observer records can otherwise count the same water twice. Dry-run rows are not delivered water.

Daily entries contain date_local, epoch, kind, and zones. Zone entries provide planned seconds and the recorded reason. Kinds include scheduled, scheduled_legacy, missed_window, and recorded_decision.

Daily planning evidence and actual run records have different meanings. A generic historical decision does not prove that a scheduled valve dispatch was skipped.

GET /decisions?days=30 returns verdict transitions. Its range clamps to 1 to 365 days. A transition is not the daily watering journal.

Export and review

EndpointResult
GET /export?days=365&format=csvDownloadable run/skip export; JSON also supported
GET /accuracy?days=30Completed-day forecast/observed comparison
GET /tuning?days=14Zone tuning suggestions and evidence
GET /explanationOptional advisor explanation
GET /anomaliesOptional advisory checks

Export ranges clamp to 1 to 3,650 days. Accuracy uses 1 to 365 days and does not score incomplete current days. Tuning uses 7 to 30 days.

History-dependent routes require persistent storage. An unavailable or failed history read must not be treated as an empty successful report.

Send a command

POST /action accepts JSON selected by kind.

KindOther fields
runzone, seconds
stopzone
stop_allNone
set_pause_untilepoch; zero clears
clear_pause_untilNone
togglekey: irrigation_pause or irrigation_dry_run; on: boolean
set_global_overridemode: auto, skip, or run
set_zone_overridezone; mode: auto, skip, or run
set_override_tomorrowmode: none, skip, or run
set_thresholdkey, value

Use the LocalSky zone slug, not a guessed controller name. For example:

{"kind": "stop", "zone": "front_lawn"}

Explicit run durations have a defensive ceiling of 7,200 seconds and remain subject to the applicable dispatch policy. A Force choice does not bypass every protection. See rules and thresholds.

Threshold writes accept max_wind_mph (0 to 50), min_temp_f (20 to 70), and rain_skip_in (0 to 10). Controls are stored in LocalSky; retired HA helpers are not the control store.

Successful dispatch responses include ok, the dispatch target, and, where available, confirm_within_s. Check subsequent reported state. If a request times out, inspect state before retrying a run.

Command failures

CodeMeaning
zone_unknownZone binding cannot be resolved
controller_auth_failedController credential rejected; distinct from LocalSky API authentication
controller_rate_limitedController or vendor throttled the request
controller_unsupportedOperation unsupported
controller_unreachableController connection or upstream operation failed

Preserve the response status, code, diagnostic, and request ID. Additional policy failures can hold a run. Do not translate every refusal into a retry.

POST /simulate evaluates a what-if scenario without dispatch. Tuning dismissals use POST /tuning/dismiss and POST /tuning/undismiss. The retired shadow routes report disabled; run_sequence_now is no longer an accepted action.

Error handling · Live streams · History guide