Skip to main content

System Variables

System variables are named, server-side values refreshed on an interval by variable drivers (sun & moon times, weather, water levels, calendar events, and more). They can be referenced anywhere a dynamic attribute is accepted — macro conditions, triggers, and schedule rules — using the [$variable_name] syntax.

The Variables Page

Open Variables

Admin → Automation → Variables manages variable driver instances. The grid lists each configured instance with its driver, prefix, interval, description, configuration, and enabled state. Use the grid's Add or Edit buttons to open the full-page editor, Reload to restart an instance, or Delete to remove it. The editor fields are:

  • Driver — pick from the installed variable drivers; selecting one shows the driver's description and pre-fills its default interval and configuration template for new rows. Each driver self-describes (template, per-field documentation, produced variables), so the editor guidance always matches the installed drivers.
  • Prefix — optional, prepended to every variable name the instance produces. Required to run two instances of the same driver (e.g. two usgs_waterdata instances watching different basins).
  • Update Interval — entered as a value plus unit (seconds/minutes/hours). The minimum accepted interval is 1 second.
  • Description — optional free-text note ("what this instance is for"); shown in the grid and beside the values.
  • Enabled — toggle. A disabled instance stops polling and produces no values; re-enabling it resumes on save.
  • Configuration — a schema-driven form generated from the driver's metadata: typed inputs per field with inline documentation, a map picker for latitude/longitude fields (search by address or zip, or click the map), and a Raw JSON toggle for hand-editing. Insert Template restores the driver's example shape.
  • Produced Variables — the variable names this instance will register, derived live from the driver and your current configuration (so a USGS stations-mode list updates as you add stations, even before you save). Click one to copy its [$name] reference.

Saving (or deleting/disabling) reloads the driver instance immediately — no restart needed, and the first update runs right away (the toast confirms "first update is running").

Below the grid, Current Values shows every stored variable value, grouped under the instance that produces it. Click a name to copy its [$name] reference; Refresh re-reads the latest values.

How Variables Work

Each configured instance carries:

FieldPurpose
DriverWhich variable driver to run (see list below)
IntervalRefresh period
ConfigurationDriver-specific settings (JSON)
PrefixOptional prefix applied to every variable name the driver produces
DescriptionOptional note describing the instance
EnabledWhether the driver runs

On boot (and whenever you save, reload, disable, or delete a row) the server (re)starts each enabled instance, runs an immediate update, and then refreshes on the configured interval. Each update writes its values to the variable store and an in-memory cache, so [$name] references resolve instantly.

Referencing Variables

A stored value can be dropped into any field that accepts a dynamic attribute — a macro If (condition) step, an Attribute Trigger condition, a Set Attribute step, or a Macro Schedule rule — using [$variable_name]:

  • [$outdoor_temperature] — the raw value
  • [$lake_elevation] > 493 — a trigger or condition comparison
  • [$sunset] — as a schedule rule, fires the macro at the next sunset

You can also do light math on the value inline:

  • Date/time variables take +N / -N in minutes: [$sunset]+30 is 30 minutes after sunset, [$sunrise]-15 is 15 minutes before. These are the rules to use for "X minutes after sunrise/sunset" schedules.
  • Numeric variables take an operator (+, -, *, /) and/or a clamp :min:max: [$outdoor_temperature]-2, [$wind_speed]*2, or [$x]*10:0:100 (multiply, then clamp to 0–100). Integer variables round to the nearest whole number.

Click any name in Current Values (or Produced Variables in the editor) to copy its [$name] reference to the clipboard.

Built-In Drivers

Driver (display name)Variables ProducedDefault Interval
sun_moon (Sun & Moon)sunrise, sunset, dawn, dusk, night (each a date/time), moon_phase1 hour
weather (Weather)outdoor_temperature, feels_like, outdoor_humidity, dew_point, wind_speed, wind_gust, wind_direction, air_pressure, visibility, cloud_cover, uv_index, precipitation, precipitation_today, precipitation_chance, weather_code, weather_condition, today_high, today_low, tomorrow_high, tomorrow_low, tomorrow_precipitation_chance, tomorrow_condition10 minutes
season (Season)season (spring / summer / fall / winter)24 hours
datetime (Date & Time)time (date), hour, minute, day_of_week, day_of_month, month, year1 minute
google_calendar (Google Calendar)google_calendar (JSON array of upcoming events)15 minutes
usgs_waterdata (USGS Water Data)lake_elevation, streamflow, gage_height, precipitation, water_temperature for a location (or per-station readings — see below)15 minutes

A few details that affect setup:

  • Sun & Moon, Weather, and USGS Water Data need a latitude/longitude — use the map picker in the Configuration form. Season and Date & Time need no configuration.
  • Sun & Moon date variables always hold the next upcoming occurrence — once today's sunset passes, sunset rolls to tomorrow's. Moon phase is one of new_moon, waxing_crescent, first_quarter, waxing_gibbous, full_moon, waning_gibbous, last_quarter, waning_crescent.
  • Date & Time values are in the server's time zone. day_of_week is SundaySaturday and month is the full month name (JanuaryDecember).
  • Weather fetches from the free Open-Meteo forecast API (the same service the weather page and widget use) — no API key, account, or URL configuration needed; just the latitude/longitude. Values are imperial (°F, mph, inches, miles) by default; add "units": "metric" to the configuration JSON for °C / km/h / mm / km. precipitation_chance is today's maximum probability of precipitation; weather_condition is condition text like partly cloudy or light rain (weather_code is the raw WMO code behind it).
  • Google Calendar needs the calendar shared with the GEM service account and an access token from the GEM calendar bridge; each event is stored as {summary, organizer, status, start, end, location}.

USGS Water Data (usgs_waterdata)

Reads latest readings from the USGS Water Data OGC API for any USGS-hosted monitoring location nationwide. This includes cooperator networks published through USGS — for example the LCRA Highland Lakes gauges in Texas under agency code TX071.

Give the driver a latitude/longitude and it auto-selects the best live gauge for each metric and produces a fixed set of variables:

{
"api_key": "optional — raises rate limits",
"latitude": 30.345,
"longitude": -97.84,
"radius_km": 25,
"overrides": {"streamflow": "USGS-08158000"}
}

Variables produced (float): lake_elevation (ft), streamflow (cfs), gage_height (ft), precipitation (in), water_temperature (°C). A metric with no live gauge in radius stays unset (logged once; the driver keeps checking each cycle in case one comes online).

How gauges are selected:

  • Only gauges with a fresh reading qualify (within max_age_hours, default 48) — discontinued stations whose "latest" value is years old are ignored.
  • streamflow and gage_height prefer the gauge with the largest drainage area in radius, then nearest — so the river main stem wins over a nearer storm creek reading 0 cfs. All other metrics pick the nearest qualifying gauge.
  • Selections are pinned for the life of the instance and logged at startup (streamflow -> USGS-08158000 Colorado Rv at Austin, 18.9km), so automation never silently switches gauges mid-season. Restart (save the variable) to re-select.
  • overrides pins a specific station per metric when the heuristic picks wrong — e.g. nearest water temperature may be a spring-fed site that doesn't reflect your lake.

Run multiple instances with different prefixes to watch more than one location (e.g. an unprefixed instance for the property plus a travis-prefixed one upstream).

Stations Mode (advanced)

Watch an explicit station list instead — useful for stations outside any sensible radius or parameters beyond the canonical five:

{
"api_key": "optional",
"stations": [
{"id": "TX071-08154500", "alias": "lake_travis", "parameters": ["00062"]},
{"id": "TX071-08161400"}
]
}
  • id (required) — the monitoring location id, AGENCY-SITENUMBER. Discover stations via the API's monitoring-locations collection (e.g. ?agency_code=TX071 or a bbox).
  • alias (optional) — friendly base name; defaults to the id lowercased (tx071_08161400).
  • parameters (optional) — USGS parameter codes to keep; omit to store everything the station reports.

Each reading is stored as <alias>_<parameter_name> (float). Common parameter codes:

CodeNameUnit
00060streamflowcfs
00065gage_heightft
00062lake_elevationft above datum
62614 / 62615lake_elevation_ngvd29 / lake_elevation_navd88ft
00045precipitationin
00010 / 00020water_temperature / air_temperature°C
00095specific_conductanceµS/cm
00300dissolved_oxygenmg/L
00400ph
63680turbidityFNU

Unmapped codes are stored as param_<code>. If both stations and a latitude/longitude are present, stations mode wins.

Notes

  • Readings are near-real-time (typically 15-minute telemetry) and flagged provisional by USGS until reviewed.
  • Readings older than max_age_hours (default 48) are skipped in both modes.
  • A station that returns no readings or a non-numeric value is logged and skipped; one failing station does not block the others.
  • Per the data volume, an update_interval of 15–60 minutes is appropriate.
  • Example triggers: [$lake_elevation] > 493 (flood watch), [$streamflow] > 5000 (high flow), [$lake_travis_lake_elevation] < 660 (drought stage, via a stations-mode instance).
  • Triggers — fire a macro when a variable crosses a threshold (e.g. [$lake_elevation] > 493).
  • Macros — reference variables in If/condition and Set Attribute steps.
  • Macro Schedules — use [$sunrise] / [$sunset] (optionally +N / -N minutes) as a schedule rule.