Energy Technical Reference¶
The technical companion to the user-facing Energy & Power page. This documents the monitoring hardware, the full circuit-to-entity map, the time-of-use rate logic, and the sensor pipeline that turns raw watts into a month-to-date bill.
All the derived sensors, utility meters, and TOU templates described here live in configuration_tou_addition.yaml (loaded as the tou package). The raw per-circuit sensors come from the refoss_rpc integration. The full project workstream guide is projects/house_energy_strategy.md in the repo.
System Overview¶
| Property | Value |
|---|---|
| Panels | Two independent 200 A services |
| Monitoring | 2× Refoss EM16P (one per panel), installed & live 2026-06-13 |
| Integration | refoss_rpc (HACS, local_push via aiorefoss) — added per-device by local IP |
| Channels | 18 per panel (2 mains + 16 branch CTs) |
| Per-channel sensors | _power (W), _voltage, _current, _power_factor, _today_energy / _this_week_energy / _this_month_energy (kWh, total_increasing) |
| Whole-home basis | Sum of the 4 service-leg mains (both panels) — not a branch sum |
| HVAC control | Ecobee Eco+ owns all heating/cooling; HA is observation-only |
| Utility rate | Dominion Energy VA — Schedule 1G (residential TOU) |
Integration is local-push by IP
refoss_rpc discovers each EM16P by local IP on the same L2 subnet as HA (it fails across VLANs). Both hubs need DHCP reservations on the Eero — if a lease changes, HA loses the device. The hub is powered off the A-phase; install adds a 15 A breaker in a blank slot.
Panel 1 — Lighting & General¶
Physical Panel 1 · HA device "Panel 1 Energy Monitor" · raw channels em_channel_1–18 (phase-grouped: ch1–6 = A1–A6, ch7–12 = B1–B6, ch13–18 = C1–C6; ch1 = A1 main, ch7 = B1 main). Channels renamed in HA to the friendly entity IDs below.
| CT | Circuit | Entity ID |
|---|---|---|
| A1 / B1 | Service mains (200 A) | sensor.em_panel1_main_l1_power / _l2_power |
| A2 | Garage fridge + deep freezer + irrigation (combined circuit) | sensor.em_garage_fridge_irrigation_power |
| A3 | Family room lights/receptacles | sensor.em_family_room_power |
| A4 | Power vent (gas water-heater venter) | sensor.em_power_vent_power |
| A5 | Attic furnace blower | sensor.em_attic_furnace_power |
| A6 | Garage lights/receptacles | sensor.em_garage_lights_power |
| B2 | Master bath & lights | sensor.em_master_bath_power |
| B3 | Master bed lights/receptacles | sensor.em_master_bed_power |
| B4 | Bedrooms 2–3 lights/receptacles | sensor.em_bedrooms_2_3_power |
| B5 | Outside lights | sensor.em_outside_lights_power |
| B6 | Kitchen fridge | sensor.em_kitchen_fridge_power |
| C1 | Laundry nook lights | sensor.em_laundry_nook_lights_power |
| C2 | Kitchen/dining lights | sensor.em_kitchen_dining_lights_power |
| C3 | Foyer lights | sensor.em_foyer_lights_power |
| C4 | Baths from BR 4–5 | sensor.em_baths_br4_5_power |
| C5 | Living room lights/receptacles | sensor.em_living_room_power |
| C6 | Crawl furnace blower | sensor.em_crawl_furnace_power |
Dropped (no CT — 3): attic/smoke detectors (~0 W), disposal (seconds/day), upstairs-hall lights (swapped out so the Foyer could be monitored instead).
Panel 2 — Main Appliances¶
Physical Panel 2 · HA device "Panel 2 Energy Monitor" · raw channels a1–c6 (match the CT labels directly).
| CT | Circuit | Entity ID |
|---|---|---|
| A1 / B1 | Service mains (200 A) | sensor.em_panel2_main_l1_power / _l2_power |
| A2 + B2 | 3rd-floor air handler (240 V) | sensor.air_handler_power (leg-sum template) |
| A3 + B3 | Stove/oven (240 V) | sensor.stove_power (leg-sum template) |
| A4 + B4 | Dryer (240 V) | sensor.dryer_power (leg-sum template) |
| A5 | AC condenser — 2nd floor (240 V/×2) | sensor.em_condenser_floor2_power |
| A6 | AC condenser — 1st floor (240 V/×2) | sensor.em_condenser_floor1_power |
| B5 | AC condenser — 3rd floor (240 V/×2) | sensor.em_condenser_floor3_power |
| B6 | Dishwasher | sensor.em_dishwasher_power |
| C1 | Whirlpool tub | sensor.em_whirlpool_power |
| C2 | Kitchen nook receptacles | sensor.em_kitchen_nook_receptacles_power |
| C3 | Kitchen/dining receptacles | sensor.em_kitchen_dining_receptacles_power |
| C4 | Microwave | sensor.em_microwave_power |
| C5 | Bathroom GFI | sensor.em_bathroom_gfi_power |
| C6 | Washer | sensor.em_washer_power |
240 V leg-sums: the air handler, stove, and dryer each use two CTs (one per leg) and are summed in template sensors (= _l1_power + _l2_power). The three AC condensers use a single CT in 240 V/×2 mode (pure 240 V, balanced legs → exact).
Phase/sign & combined-circuit quirks
The EM16 is a 3-phase meter on US split-phase: a branch CT on the "wrong" leg reads the right magnitude but negative — inverted in the Refoss app (Circuit Factor), not re-clamped. Mains must read positive. A2 on Panel 1 is a combined circuit (garage fridge + deep freezer + irrigation) — it never reads 0; the continuous ~100–250 W floor is the freezers, bumps are irrigation. It doubles as a freezer-failure proxy alongside the garage food-temp sensors.
Derived & Whole-Home Sensors¶
All defined in configuration_tou_addition.yaml.
| Logical name | Entity ID | Definition |
|---|---|---|
| Whole-home power | sensor.whole_home_power | Sum of the 4 service-leg mains (both panels), in W |
| Whole-home energy | sensor.whole_home_energy_total | Riemann integral (integration, left method, 2-min max sub-interval) of whole-home power → kWh total_increasing |
| Energy by TOU tariff | sensor.whole_home_energy_peak / _off_peak / _super_off_peak | utility_meter (daily cycle) tracking whole_home_energy_total, tariff driven by the TOU-sync automation |
| Cost rate | sensor.energy_cost_rate | kW × sensor.tou_rate → $/h (tariff-accurate, instantaneous) |
| Cost accumulated | sensor.energy_cost_accumulated | Riemann integral of the cost rate → cumulative $ |
| Cost this month | sensor.energy_cost_this_month | utility_meter (monthly cycle) on the accumulated cost — the running bill total, resets on the 1st |
| Cost today | sensor.energy_cost_today | Today's per-tariff kWh × the season's weekday rates |
| 240 V leg-sums | sensor.air_handler_power / stove_power / dryer_power | Sum of each appliance's two leg CTs |
Sensor pipeline¶
flowchart TD
M[4 service-leg mains<br/>em_panel1/2_main_l1/l2_power] --> WHP[sensor.whole_home_power]
WHP -->|integration| WHE[sensor.whole_home_energy_total]
WHE -->|utility_meter daily, tariff-split| TOU[whole_home_energy_peak / off_peak / super_off_peak]
TOU --> CT[sensor.energy_cost_today]
R[sensor.tou_rate] --> CT
WHP --> CR[sensor.energy_cost_rate]
R --> CR
CR -->|integration| CA[sensor.energy_cost_accumulated]
CA -->|utility_meter monthly| CM[sensor.energy_cost_this_month]
P[sensor.tou_period] -->|TOU-sync automation| TOU Time-of-Use Logic¶
sensor.tou_period and sensor.tou_rate are triggered template sensors that re-evaluate every minute and on HA start. input_boolean.peak_mode is toggled by an automation when tou_period changes — use peak_mode in automations, not the raw period string. Season is months 5–9 = summer. Weekends and the 6 listed holidays are off-peak all day (no peak window).
Summer (May–Sep) — weekdays¶
| Period | Hours | Rate ($/kWh) |
|---|---|---|
| Super off-peak | 12:00 AM – 5:00 AM | 0.124709 |
| Off-peak | 5:00 AM – 3:00 PM, 6:00 PM – 12:00 AM | 0.142590 |
| Peak | 3:00 PM – 6:00 PM | 0.301638 |
Winter (Oct–Apr) — weekdays¶
| Period | Hours | Rate ($/kWh) |
|---|---|---|
| Super off-peak | 12:00 AM – 5:00 AM | 0.140752 |
| Off-peak | 5:00 AM – 6:00 AM, 9:00 AM – 5:00 PM, 8:00 PM – 12:00 AM | 0.146795 |
| Peak | 6:00 AM – 9:00 AM, 5:00 PM – 8:00 PM | 0.262161 |
Weekends & holidays (year-round)¶
| Period | Hours | Summer | Winter |
|---|---|---|---|
| Super off-peak | 12:00 AM – 5:00 AM | 0.124709 | 0.140752 |
| Off-peak | 5:00 AM – 12:00 AM | 0.142590 | 0.146975 |
Weekend winter off-peak rate
Weekend winter off-peak is 0.146975, fractionally different from the weekday winter off-peak (0.146795) — both are encoded exactly in sensor.tou_rate. sensor.energy_cost_today uses the weekday rates as the representative season values.
| Entity | Purpose |
|---|---|
sensor.tou_period | peak / off_peak / super_off_peak |
sensor.tou_rate | Current rate in $/kWh |
input_boolean.peak_mode | on during peak — the automation-facing flag |
TOU tariff-sync automation¶
A dedicated automation calls utility_meter.select_tariff (peak / off_peak / super_off_peak) whenever sensor.tou_period changes, so the whole_home_energy daily utility meter accrues today's kWh into the correct tariff bucket. Without this, whole_home_energy_{peak,off_peak,super_off_peak} and energy_cost_today would not split correctly.
HVAC Observation Sensors¶
HVAC is observation-only — these sensors never control anything (Ecobee Eco+ owns heating/cooling). See Climate & Comfort.
| Logical name | Entity ID | Definition |
|---|---|---|
| Condenser running (per floor) | binary_sensor.first_floor_condenser_running / second_ / third_ | device_class: running, true when condenser power > 200 W |
| Condenser runtime today (h) | sensor.first_floor_condenser_runtime_today / second_ / third_ | history_stats, time the running boolean was on since midnight |
The condenser→floor mapping is locked: 1 = 1st floor (CT a6), 2 = 2nd floor (CT a5), 3 = 3rd floor (CT b5). Three short-cycle automations (one per condenser) notify if a condenser cycles on→off within 8 minutes. The gas-furnace blowers (em_attic_furnace_power, em_crawl_furnace_power on Panel 1) are low-wattage run proxies — the gas furnaces themselves can't be seen by wattage.
Data Logging & Visualization¶
InfluxDB 1.x records the sensor domain (auto-included in influxdb_ha.yaml), so all EM16P power/energy channels are logged. Grafana queries it over InfluxQL (not Flux). Reminder on the schema: the InfluxDB measurement = the entity's unit_of_measurement, and the entity_id tag has no sensor. prefix.
The Grafana Home Intelligence dashboard's ⚡ Energy row is live and wired to sensor.whole_home_power (vs TOU rate), sensor.whole_home_energy_{peak,off_peak,super_off_peak} (Energy by TOU Period), Circuit Power Now, HVAC Power, and Today's Cost (sensor.energy_cost_today). Query detail is in Grafana Analytics.
On the HA side, everything surfaces on the Command dashboard's Energy tab — see Energy & Power for the user-facing layout, and the Automations Reference for the peak-hour appliance alert.
InfluxDB cardinality
~36 power channels updating every few seconds is significant write volume. The current decision is to keep full-resolution data in InfluxDB; if it becomes a problem, the fallback is HA long-term statistics for the breakdown and only mains/key circuits in Influx.
See Also¶
- Energy & Power — the user-facing version of this system
- Climate & Comfort — Ecobee, Eco+, and why HA doesn't drive HVAC
- Automations Reference — peak-hour appliance alerts, condenser short-cycle alerts
- Grafana Analytics — the ⚡ Energy row queries
- Entity IDs — full entity inventory