grid state machine
sim —

architecture

state machine protocols

This tick: —

Words

  • push discharge to the grid
  • pull charge from the grid
  • hold neither

The call is the ask. Colour on the map is what the cabinet did.

When to push or pull

First match wins. No posted order.

  1. Official load-zone price, only with the ERCOT key. High → push. Low → pull. Until the key is set, skip this and use simulated price.
  2. Texas demand at or above today's 75th percentile → push.
  3. Texas demand at or below today's 35th percentile → pull.
  4. ERCOT storage discharging ≥ 200 MW → push. The Base fleet discharges with it.
  5. ERCOT storage charging (≤ −200 MW) → pull. The Base fleet charges with it.
  6. Otherwise hold.

Who answers

A live call reaches at least about a third of each service area, more as the peak or trough deepens. Hold reaches none.

Charge takes the emptiest cabinets first. Discharge takes the fullest first. Discharge stops at the customer's reserve. Charge stops at 95% full.

What outranks the ladder

  • A posted fleet order is one call for every home. The ladder is off.
  • Reverse demand skips prices and takes the opposite of the live call. A discharge becomes a charging window.
  • A set-signal on one home outranks the fleet call for that home.
  • An open maintenance ticket keeps the fleet manager off that home.

Prototype policy, not an ERCOT market award.

public api

This tick: —

Origin

JSON. No login. Same origin as this page: https://gridstatemachine.com/ live, http://127.0.0.1:8000 locally.

Secrets stay in the environment. They are never in a response. A post changes this live prototype until restart.

OpenAPI /openapi.json. Swagger /docs.

Tick

A tick is 10 seconds. GET is current memory. Dispatch and actions apply on the next tick. Agent flags update in memory now and show on the next scene poll.

400 is a bad body. 404 is an unknown home. Errors are {"detail": "…"}.

Reads

MethodPathWhat you get
GET/api/sceneThe map. One small row per home. The page polls this every 5 seconds.
GET/api/site/{id}One home in full: metrics, charts, snapshot, log, actions.
GET/api/dispatchApplied call, pending order, controller snapshot.
GET/api/agentHomes that are armed, set to dispatch, or grid-off, and whether reverse demand or peak now is on.
curl https://gridstatemachine.com/api/scene
curl https://gridstatemachine.com/api/site/aus-0004

Writes

MethodPathBody
POST/api/dispatch{"signal":"push","intensity":0.8} — one call for every home. auto returns the ladder.
POST/api/actions{"site_id","kind","payload"} — scheduled_service, set_signal, install_addon, remove_addon.
POST/api/agent{"site_id","chart_id","armed"}, or dispatch, or grid, or {"demand_pin":"peak"}, or {"demand_reverse":true}.
curl -X POST https://gridstatemachine.com/api/dispatch -H "Content-Type: application/json" -d "{\"signal\":\"auto\"}"

Chart ids: disco_meter_delta, base_temp, disco_voltage, frequency, soc_tracking, dispatch_response. Add-ons: solar, ev_charger.

one-line diagram