Time-of-Use
as a live Home Assistant sensor

ZIP in, current peak / off-peak period out. Home Assistant automations for EV charging, thermostat and HVAC, and loads off the tariff clock — not a hardcoded 4–9 PM that drifts every season.

Don’t Hardcode Peak Hours

Home Assistant forums are full of now().hour and schedule helpers. They miss holidays, season flips, DST, and the day the utility refiles the tariff.

Hardcoded
template:
  - binary_sensor:
      - name: Peak hours
        state: >
          {{ now().weekday() < 5
             and 16 <= now().hour < 21 }}

Looks fine in June. Wrong in January, on a holiday, and the week the peak window moves.

From the tariff
automation:
  - alias: Charge EV when off-peak
    triggers:
      - trigger: state
        entity_id: binary_sensor.off_peak
        to: "on"

The period is a sensor. Automations follow the clock the utility actually bills.

ZIP → current period → automation

One REST call. Home Assistant already speaks REST. No custom component or HACS install required.

1

Pass a ZIP

Any U.S. ZIP, optional street if the ZIP is shared. Residential is the default customer class.

2

Read the period

off_peak, on_peak, mid_peak, super_off_peak, or critical_peak — plus when it next changes.

3

Trigger on state

EV charger, thermostat, HVAC, dishwasher, battery reserve, or the Home Assistant Energy dashboard tariff selector.

GET /api/v1/query/current?zip_code=94103
{
"confidence": "unique",
"results": [{
"period": "off_peak",
"next_change_at": "2026-05-16T16:00:00-07:00"
}]
}

Wire it in with REST

The YAML recipe — secrets, REST sensors, and boundary-aware automations — is in the docs.

What you'll paste

Three blocks: the API key in secrets.yaml (include the word Bearer), a REST sensor plus templates in configuration.yaml, and automations that refresh 45 seconds after next_change_at then fire on binary_sensor.off_peak. Swap the ZIP. Reload REST entities and template entities.

Entities the recipe creates

sensor.tou_period (live period + next_change_at attribute), sensor.tou_next_change (timestamp), and binary_sensor.off_peak (on during off-peak and super-off-peak).

Open the install recipe

Home Assistant automations for peak hours, without the clock math

EV charging

Turn the charger on when binary_sensor.off_peak goes on. Hold through super-off-peak. Stop at on-peak.

HVAC pre-cool

Drop the thermostat setpoint an hour before next_change_at when the next period is on-peak, then coast.

Wet loads

Delay the dishwasher, washer, and water heater until off-peak. Same binary sensor, different switches.

Home battery

Charge through off-peak, raise reserve at peak start. Period names only — no ¢/kWh from this API.

Energy dashboard

Drive the Home Assistant Energy dashboard and utility_meter tariff selects from sensor.tou_period instead of time triggers at 16:00. Pair with an energy monitor or power monitor — this API is the clock, the meter is the kWh.

Notify before peak

When sensor.tou_next_change is under an hour away and the current period is off-peak, send a Home Assistant notification to the phone.

The same API as a dedicated integration

A custom Home Assistant component — tou.tools (Time-of-Use) — wraps this exact flow: API key + ZIP in a config UI, an enum period sensor, an off-peak binary sensor, and a coordinator that reschedules itself for just after next_change_at.

The REST recipe in the docs is the path that works on any Home Assistant today — no extra component, no HACS or Home Assistant Community Store install. The custom integration is the same sensors without YAML, and it stays inside the free tier by polling only at boundaries. Install from REST; switch later if you want the UI.

The same periods are also an MCP server at /mcp, if a Home Assistant MCP client or LLM should query them as tools instead of a REST sensor.

sensor.tou_period
Enum: off_peak, mid_peak, on_peak, super_off_peak, critical_peak. Attributes include next_change_at, rate plan, and utility.
binary_sensor.off_peak
On while the period is off_peak or super_off_peak. The trigger most automations actually want.
sensor.tou_next_change
Timestamp device class. Fire a time trigger at the boundary instead of polling every 15 minutes.

Frequently asked

  1. How do I get time-of-use peak hours into Home Assistant?

    Call GET /api/v1/query/current with your ZIP and rate_plan_id from a REST sensor. Pin the plan on your bill first — a ZIP often has several. results[0].period is then the live period. Automate on that, or on a binary sensor that is on during off-peak and super-off-peak. YAML is in the Home Assistant docs.

  2. Does this return ¢/kWh?

    No. tou.tools is the timing layer: period names and boundaries. Prices live in riders, baselines, and customer class. Put your own rates on the Home Assistant Energy dashboard or in utility_meter if you need a dollar figure. An energy monitor or power monitor supplies the kWh.

  3. Will this work with my utility?

    If we have a seeded TOU plan for the utility that serves your ZIP, yes. See coverage. When a ZIP is ambiguous (common in Texas / ERCOT), the API returns every candidate plan instead of guessing — pick the one on your bill, or pass street / city / state.

  4. How many API calls does a home use?

    Refreshing at next_change_at is a handful of calls per day and fits the free plan (500/month, 3 locations). Polling every 15 minutes is ~2,880/month. The REST recipe does the former.

  5. Can I drive the Home Assistant Energy dashboard from this?

    Yes. On a state change of sensor.tou_period, call select.select_option on your meter’s tariff selector. Map off_peak / super_off_peak to your cheap tariff name. Pair with an energy monitor or power monitor for kWh. The Energy dashboard automation in the docs recipe is that mapping.

Start With a Free Key

No credit card. 500 calls/month. Enough for a house if you refresh at next_change_at (a few calls a day).

Get Free API Key