Quick Summary (TL;DR)
Start with your actual electricity contract, not a public wholesale price chart. For a fixed-rate tariff, a static price sensor is enough. For a predictable peak/off-peak tariff, a local clock-based template can publish the current applicable rate and a Utility Meter can divide usage by tariff. For a dynamic tariff, use the supplier’s authoritative retail price feed when available, or carefully transform a supported market feed into a contract-correct import price. In all three cases, keep energy consumed in kWh separate from electricity price in currency/kWh.
Home Assistant’s Energy dashboard can calculate estimated energy costs from a constant price or a compatible changing price sensor. It is not a substitute for the supplier’s bill: standing charges, taxes, network fees, time shifts, export credits and meter-data reconciliation may require additional accounting. Never let a missing or implausible tariff sensor trigger high-power loads. Use a tested default schedule or stop price-driven switching until the data recovers.
This guide shows the data model, practical Home Assistant YAML configurations, example calculations and validation checks for British and European households. All tariffs and figures below are illustrative rather than current supplier offers. Supplier-specific contract rules always take precedence.
Which type of electricity tariff do you have?
Before creating a sensor, read the tariff section of your electricity contract. A familiar tariff name does not define how energy is charged: some plans use a fixed unit rate all day, some switch at prescribed clock times, and some use day-ahead market prices with a supplier formula. Import and export rates may be entirely different. Even the clock may mean local civil time, UTC, or settlement periods specified by the supplier.
| Tariff model | What determines the import unit price? | Best Home Assistant starting point | Main trap |
|---|---|---|---|
| Fixed / single-rate | One contractual unit rate for every kWh during the pricing period | Constant price sensor or Energy dashboard constant price | Confusing the unit price with full bill cost |
| Time-of-use (TOU) | Defined peak, shoulder and off-peak periods | Clock-aware template sensor; optional Utility Meter split | Wrong boundary or daylight-saving interpretation |
| Dynamic retail | Interval prices linked to supplier/market data and contract formula | Retail integration or properly adjusted price feed | Treating raw wholesale price as retail price |
| Multi-component contract | Energy charge, taxes, network charges and standing fees | Explicit bill model layered over the current unit price | Adding fixed daily charges as a per-kWh mark-up |
| Export payment | Separate remuneration formula for energy sent to grid | Independent export-rate and exported-kWh entities | Subtracting export from consumption at import tariff |
Use the least complicated implementation that represents the contract accurately. A customer on a flat rate gains little from installing a dynamic-rate API solely for a pretty chart. A customer with half-hourly settlement, meanwhile, loses useful information if the source averages prices into one daily number.
Build the correct data model before any automation
Electricity price is an instantaneous rate associated with a time interval. Energy is an accumulated quantity. Money is the result of combining the two over matching time intervals. This difference affects the entity types you create and the values you feed to the Energy dashboard. A price of £0.25/kWh is not an energy sensor; a meter reading of 4,212 kWh is not a rate; an instantaneous load of 2.5 kW is not a monthly cost.
| Entity / quantity | Typical unit | Recommended meaning | Example |
|---|---|---|---|
| Grid import energy | kWh | Cumulative electricity imported from grid | sensor.grid_import_energy = 4,212.4 |
| Grid export energy | kWh | Cumulative electricity exported to grid | sensor.grid_export_energy = 918.7 |
| Instantaneous grid power | W or kW | Current rate of energy flow; use the appropriate import/export sign convention | sensor.grid_power = 1.7 kW |
| Current import price | GBP/kWh or EUR/kWh | Price applicable to energy imported now | sensor.grid_import_price = 0.245 |
| Current export price | GBP/kWh or EUR/kWh | Payment rate applicable to exports now | sensor.grid_export_price = 0.08 |
| Monthly bill estimate | GBP or EUR | Accumulated monetary estimate for specific bill period | sensor.estimated_energy_charge = 42.10 |
To appear in the Energy dashboard, a cumulative import kWh sensor generally needs device_class: energy and state_class: total_increasing (or the correctly configured total class); a power sensor normally uses device_class: power and state_class: measurement. Your tariff price sensor is a numeric sensor with a currency-per-energy unit and may use state_class: measurement. See the Home Assistant Energy FAQ and Template documentation.
Use one consistent currency for all cost computations. Home Assistant can display the chosen currency unit, but writing “GBP/kWh” on a sensor that contains pence per kWh does not automatically convert its value. For example, 24.5 pence/kWh means 0.245 GBP/kWh. Likewise, an index quoted in EUR/MWh must be divided by 1,000 to obtain EUR/kWh before adding contract-specific fees.
Option 1: Create a fixed electricity price sensor
Suppose your import unit rate is £0.265/kWh under a hypothetical contract. If the Energy dashboard accepts a constant price directly in your current installation, that is the simplest route: open Settings → Dashboards → Energy, edit the grid-consumption entry and configure the energy price. Alternatively, make a reusable template sensor if another dashboard, chart or automation needs the same value. This example assumes a stable price for illustration; update it when the contract changes.
template:
- sensor:
- name: "Grid Import Price Fixed"
unique_id: grid_import_price_fixed
unit_of_measurement: "GBP/kWh"
state_class: measurement
state: "0.265"
The template creates a numeric rate rather than a growing counter. Do not set device_class: energy or state_class: total_increasing on a price sensor. If your contract is in euros, use the supported currency-per-kWh unit appropriate to your configured Home Assistant currency and numeric values expressed in euros, not in cents.
An optional input_number helper is useful if the supplier announces a new price periodically. A template can read that helper rather than hard-code the rate; however, changes in the helper are your responsibility. Record the effective date and verify that historical periods continue to use the rate that was valid at the time. The Energy dashboard estimates historical cost from the recorded price at the time, not from today’s price multiplied by all historical kWh.
Option 2: Peak and off-peak tariff sensors
Consider an example contract that costs £0.31/kWh from 07:00 to 23:00 and £0.12/kWh from 23:00 to 07:00, in the local time zone. A Home Assistant template can switch between rates using local time. For a production deployment, verify that the supplier defines those hours in local clock time and confirm how the clock-change nights are billed.
template:
- sensor:
- name: "Grid Import Price TOU"
unique_id: grid_import_price_tou
unit_of_measurement: "GBP/kWh"
state_class: measurement
state: >-
{% set hour = now().hour %}
{{ 0.12 if (hour >= 23 or hour < 7) else 0.31 }}
This Jinja template reads Home Assistant’s local time and recalculates as time changes. It deliberately uses hours rather than date-specific supplier API calls. For tariffs starting at half past the hour, calculate minutes since midnight, use appropriately precise boundaries and test the exact transition minute. When the contract changes between weekdays, weekends or seasons, add those conditions rather than guessing from a generic off-peak timetable.
The important distinction is that a changing price sensor and a tariff-split consumption meter solve different tasks. The price sensor answers “What does the next imported kWh cost now?” The Utility Meter answers “How many kWh were imported during the peak and off-peak categories?” They can coexist; one does not automatically configure the other.
Use Utility Meter to split peak and off-peak consumption
Home Assistant includes a Utility Meter integration that can track consumption over daily, monthly or other cycles and assign energy to tariff buckets. When tariffs are defined, its select entity indicates the active tariff. Crucially, the integration does not independently know when your supplier changes rates: you must switch that selection using an automation or another trusted input.
The following YAML is a complete illustrative pattern for one monthly import meter whose source is an existing monotonically increasing grid-import kWh entity. Replace sensor.grid_import_energy with the meter you have verified; do not use net consumption from a solar inverter if you want actual import kWh.
utility_meter:
monthly_grid_import_tou:
source: sensor.grid_import_energy
cycle: monthly
tariffs:
- peak
- offpeak
automation:
- alias: "TOU - Set peak tariff"
id: tou_set_peak_tariff
triggers:
- trigger: time
at: "07:00:00"
- trigger: homeassistant
event: start
conditions:
- condition: template
value_template: "{{ 7 <= now().hour < 23 }}"
actions:
- action: select.select_option
target:
entity_id: select.monthly_grid_import_tou
data:
option: peak
- alias: "TOU - Set offpeak tariff"
id: tou_set_offpeak_tariff
triggers:
- trigger: time
at: "23:00:00"
- trigger: homeassistant
event: start
conditions:
- condition: template
value_template: "{{ now().hour >= 23 or now().hour < 7 }}"
actions:
- action: select.select_option
target:
entity_id: select.monthly_grid_import_tou
data:
option: offpeak
With the example entity naming, the integration can create sensor.monthly_grid_import_tou_peak, sensor.monthly_grid_import_tou_offpeak and select.monthly_grid_import_tou. Confirm the actual assigned entity IDs in Developer Tools, because existing names and entity registry conflicts can cause suffixes.
Including the Home Assistant start trigger matters: without it, restarting at 03:00 after a power interruption could leave yesterday’s tariff selected until the next scheduled change. A more advanced design should also handle restored time synchronisation, schedule updates and any supplier-specific exception days. Initial Utility Meter cycles are incomplete until the next full cycle begins, so do not compare an installation started mid-month to a complete supplier bill.
Worked example: why the average electricity price is not enough
Imagine 18 kWh imported during the day and 7 kWh at night under the illustrative TOU tariff. The energy charge is 18 × £0.31 + 7 × £0.12 = £6.42. Simply multiplying the total 25 kWh by the unweighted average of the two tariff rates (£0.215) would produce £5.375, understating the charge because more electricity was consumed at the expensive rate.
The correct consumption-weighted unit rate is £6.42 / 25 kWh = £0.2568/kWh. The weighting must follow energy used in each price period. This is also why Home Assistant needs time-aligned energy measurements to estimate the cost of a dynamic contract accurately.
| Period | Imported energy | Illustrative unit rate | Energy charge |
|---|---|---|---|
| Peak 07:00–23:00 | 18.0 kWh | £0.31/kWh | £5.58 |
| Off-peak 23:00–07:00 | 7.0 kWh | £0.12/kWh | £0.84 |
| Total | 25.0 kWh | Weighted average £0.2568/kWh | £6.42 |
Standing charges, additional taxes and any fixed fees are excluded from that calculation. A monthly bill may also have separately computed taxes or social tariffs. Keep the Energy dashboard’s “energy cost” and a comprehensive supplier-bill forecast labelled differently to avoid treating them as the same financial amount.
Option 3: Dynamic price sensors from your supplier or energy market
Dynamic pricing changes the rate over intervals. The most reliable source is usually an official supplier integration or feed that matches your retail contract. A market-price feed is second best when you can reproduce every element of the tariff formula and correctly identify the settlement intervals. A chart showing wholesale prices is only an information source until you establish that the values map to what your household pays.
Home Assistant currently provides official integrations for certain market-price and supplier sources, including Nord Pool, EnergyZero, easyEnergy and Tibber. Availability depends on country, market area and account or integration requirements. Do not assume any of them supports your UK supplier or your particular retail contract. Some UK supplier data may be accessed through independently maintained integrations; assess maintenance, authentication and historical accuracy before relying on them.
| Source | What it can provide | What you still must verify | Suitable uses |
|---|---|---|---|
| Supplier retail-price API | Contract-linked import rate, sometimes next-day prices | Account mapping, taxes, contract changes, reliability | Best choice for price-based billing and loads |
| Market-price integration | Spot/wholesale price for a chosen market area | Retail mark-up, VAT, levies, network fees, conversion and interval | Forecasts or retail-price calculation where applicable |
| Manual rate table | Known day/night/seasonal periods | Contract schedule, local time, price revisions | Simple time-of-use tariffs |
| Utility smart-meter data | Measured consumption and possibly separate tariff registers | Update delay, direction, billing register and units | Reconciliation and actual energy tracking |
| Custom REST/template sensor | Derived price from a chosen feed | Schema changes, stale data, error handling and unit conversions | Experienced owners with supported APIs |
For Nord Pool specifically, the official integration publishes a current price for the selected area and documents its transition between hourly and 15-minute market time units. Its price figures are base market prices and do not include VAT or additional retail costs. The market interval length may change within a rollout, so code that assumes 24 hourly samples or exactly one hour per price will eventually produce incorrect schedules.
Converting wholesale prices into retail unit prices
A contract may specify a market reference price plus a per-kWh supplier charge, then apply a relevant tax rate. For an illustrative euro-priced contract, assume a current wholesale feed value of €0.115/kWh, a variable supplier charge of €0.025/kWh and a hypothetical 20% VAT rate that applies to those components. The simple illustrative retail energy price would be (€0.115 + €0.025) × 1.20 = €0.168/kWh. The VAT and charge structure must be replaced with your actual contract rules: not all grid or tax components necessarily use this formula.
If your source reports €115/MWh, divide by 1,000 before adding €/kWh costs: €115/MWh is €0.115/kWh. If the source is in pence/kWh but your Home Assistant price sensor says GBP/kWh, divide by 100. Decimal mistakes of this kind can give credible-looking charts but absurd monthly cost totals.
template:
- sensor:
- name: "Contract Import Price"
unique_id: contract_import_price
unit_of_measurement: "EUR/kWh"
state_class: measurement
availability: >-
{{ is_number(states('sensor.market_price_eur_kwh')) }}
state: >-
{% set market = states('sensor.market_price_eur_kwh') | float %}
{% set variable_fee = 0.025 %}
{% set illustrative_tax_multiplier = 1.20 %}
{{ ((market + variable_fee) * illustrative_tax_multiplier)
| round(4) }}
Replace the placeholder entity ID and formula before using this. The important feature is the availability check: it prevents an unavailable upstream feed from being converted into a fake zero-price interval. It does not, however, detect a stale feed whose numerical value has stopped updating. In a production configuration, monitor source update timestamps, expected slot continuity and the source integration’s own diagnostics.
Dynamic price feeds must carry time, not just numbers
A good dynamic feed identifies when each price starts and ends, its time zone, currency, unit and whether the price is for import or export. A “current price” sensor is enough to populate a live dashboard, but it is not enough to safely schedule an EV charge that should begin in four hours. For scheduling, the automation or optimisation system needs a future price array and the correct validity time of each value.
| Check | Correct interpretation | Common failure |
|---|---|---|
| Currency | Matches the household contract and Home Assistant dashboard | GBP values labelled as EUR |
| Unit | Currency/kWh, with MWh and pence conversions applied | 100× or 1,000× scaling error |
| Period boundaries | Actual start/end timestamps with time zone | Assuming consecutive UTC hours equal local clock hours |
| Price meaning | Retail import charge vs spot wholesale vs export credit | Selecting loads from an unrelated market curve |
| Publication timestamp | Known updated time and freshness tolerance | Using yesterday’s prices during an API outage |
| Tomorrow coverage | All intervals required to finish a scheduled job | Optimiser schedules across missing hours |
| Negative rates | Handled according to actual retail contract rules | Assuming negative wholesale always means household payment |
| Missing data | Marked unavailable or scheduler falls back | Treating missing data as free electricity |
Daylight-saving transitions deserve particular testing. In the UK and much of Europe, the local day on a clock-change Sunday can contain 23 or 25 elapsed hours. A robust system uses timezone-aware timestamps provided by the price source. It does not assume that the list of tomorrow’s prices always contains 24 records, or that the local label 01:30 appears only once.
Another common error is confusing future publication with real-time measurement. A day-ahead market can publish tomorrow’s auction prices before the next day starts; that does not make a smart meter’s energy readings arrive at the same interval. To calculate actual costs, align the price that applied to each interval with the imported kWh recorded for that interval.
Add the price sensor to Home Assistant Energy
First, verify the electricity import entity in Settings → Developer Tools → States and Statistics. A valid grid import energy counter should report cumulative kWh and have an appropriate energy device class/state class. Use the Home Assistant Energy Dashboard grid, solar and battery entity guide to avoid mixing net power with imported energy.
- Open Settings → Dashboards → Energy, find the electricity grid section and choose the grid-import consumption source.
- Confirm the cumulative import kWh entity rather than a signed net energy total or instantaneous wattage sensor.
- Choose the constant price option for a fixed tariff, or the appropriate entity-price option for a variable price if your installed Home Assistant version supports it.
- For a variable price, select the tested numeric import price sensor with the correct currency/kWh unit; do not select an export-credit or wholesale-only sensor by mistake.
- Wait for statistics and a full billing window, then reconcile the energy charge with your supplier’s interval data or invoice.
Official instructions for creating grid connections and compatible statistics are in Integrating your electricity grid. If a sensor is missing from the picker, investigate its entity type, recorder inclusion, unit, state class and statistics errors before creating duplicate entities. The first partial day of data is not a suitable accuracy test.
Cost calculations: energy cost, standing charge and export
A straightforward energy-charge approximation is the sum of imported kWh during each pricing interval × import price during that same interval. For a flat tariff this reduces to total kWh multiplied by a constant rate. For variable tariffs it must be evaluated interval by interval. For export, calculate separately using exported kWh multiplied by the applicable export remuneration.
A complete household bill may contain a standing charge per day, value-added tax, supplier fee, regulated network components, metering charges and credits. Whether some costs are proportional to kWh or fixed per day depends on the jurisdiction and contract. Do not smuggle a £0.50/day standing charge into your import-price sensor as a fixed £0.02/kWh unless you deliberately intend an approximate modelling assumption: its effective per-kWh amount depends on consumption and would distort load-scheduling decisions.
| Illustrative item | Calculation | Amount |
|---|---|---|
| Weekday import, 9 kWh at €0.29/kWh | 9 × 0.29 | €2.61 |
| Overnight import, 6 kWh at €0.13/kWh | 6 × 0.13 | €0.78 |
| Export credit, 4 kWh at €0.07/kWh | 4 × 0.07 | −€0.28 |
| Daily standing charge | Illustrative fixed charge | €0.35 |
| Subtotal before any other tax/fees | 2.61 + 0.78 − 0.28 + 0.35 | €3.46 |
That simple example is not a statement about any specific country’s bill formula. Export credit cannot always be netted against import charges pound-for-pound or euro-for-euro; many schemes have separate settlement rules, caps or tax handling. For credible reporting, label energy-only forecasts and bill-inclusive forecasts distinctly and show any excluded charges.
Make price-based automations fail safely
Price sensors become a control input when you ask Home Assistant to enable an EV charger, immersion heater, storage heater or flexible appliance based on the rate. This makes the availability and freshness of the sensor important. A missed price update must not silently become a command to enable a large load. Equally, scheduling software must not bypass EV charger load balancing, inverter limits, water-temperature protection or thermal-system safety devices.
A safe first experiment is a notification or a dashboard badge, not power switching. For example, a binary sensor can report when a validated current import price is below a hypothetical threshold. Consumers of this sensor should still have explicit availability checks and physical-control interlocks. The threshold itself is purely illustrative.
template:
- binary_sensor:
- name: "Cheap Electricity Now"
unique_id: cheap_electricity_now
availability: >-
{{ is_number(states('sensor.contract_import_price')) }}
state: >-
{{ states('sensor.contract_import_price') | float < 0.15 }}
For any physical load, additionally check that the price source has recently refreshed, the requested operation is permitted by the device, the energy target and deadline are still achievable, and a manual override is respected. A boolean “cheap now” indicator alone is not a complete automation for an EV or heating system.
For a charging schedule, keep the charger’s certified load-management functions in charge of electrical limits; only submit allowed current or schedule requests through supported interfaces. For a hot-water tank, keep the thermostat, high-limit cut-out, hygienic hot-water strategy and manufacturer’s heat-pump controls operating independently of Home Assistant. Our hot-water cylinder scheduling guide explains the distinction between optimisation and safety.
Fixed versus time-of-use versus dynamic: three household decisions
Household A: fixed import rate, no flexible loads
A household without an EV, home battery or shiftable high-energy appliance will often be best served by a fixed import price in the Energy dashboard. The useful investment is better electricity metering, not an elaborate price forecasting stack. Check month-to-month usage and make an efficiency decision based on measured load; do not mistake dashboard complexity for savings.
Household B: dual-rate tariff and an EV
A household with a reliable overnight window should publish a local TOU price sensor and configure the charger’s native schedule for that period, including departure requirements. Utility Meter can separately quantify off-peak consumption. Home Assistant can coordinate the schedule, but if the home server reboots, the charger should retain its own approved settings and supply protections.
Household C: interval-based tariff, solar and home battery
The more complicated household needs a verified day-ahead tariff curve, consumption and solar forecasts, battery reserve constraints and import/export pricing. Native Home Assistant automations may still be enough for one load; an optimiser can be justified if several loads compete and there is a measurable benefit. See our Home Assistant vs evcc vs inverter apps comparison and EMHASS vs native automation analysis.
| Household | Recommended source | Additional hardware needed? | Suggested control |
|---|---|---|---|
| Fixed tariff, basic monitoring | Contract rate | Compatible grid import meter | Dashboard only |
| Known dual-rate tariff | Clock-based retail price | Optional tariff-aware meter/helper | Native device timer; local reporting |
| Dynamic price, simple EV | Supplier retail price feed | Approved charger plus grid metering | Charger-supported tariff schedule |
| Dynamic + solar + battery | Validated forward prices, grid and PV measurements | Gateway/meter and supported inverter interfaces | Constraint-aware scheduling with fallback |
How to validate your electricity price and consumption data
A new sensor should not be trusted because its chart looks smooth. Check one known billing date and a sample of boundary periods against the tariff schedule. At each interval, record the contract rate, sensor state, source timestamp and imported energy counter. For an automated schedule, compare the selected operating periods to the supplier’s published price intervals, then check whether the device actually obeyed the allowed control command.
- Units: Confirm currency, pence/cents conversions and MWh-to-kWh scaling.
- Contract: Confirm if source prices include VAT, supplier margins and variable network charges.
- Clock: Check tariff switches at real local times and during daylight-saving changes.
- Metering: Confirm the import kWh counter excludes export and has no unexplained resets.
- Persistence: Restart Home Assistant mid-period; ensure the correct TOU tariff remains selected.
- Outage: Disconnect the test price feed; ensure automations do not interpret missing price as zero.
- Billing: Compare a full supplier billing period and document standing charges or taxes excluded from the Energy dashboard.
If the difference between Home Assistant and the invoice is material, analyse it before changing your automation thresholds. Grid metering accuracy, delays in smart-meter reporting, missing recorder history, a tariff-effective-date mismatch or export accounting are plausible causes. The utility bill reconciliation guide provides a structured cross-check.
Common mistakes and how to fix them
| Symptom | Probable cause | What to check or change |
|---|---|---|
| Energy dashboard cost roughly 100× too large | Pence per kWh entered as pounds per kWh | Convert 25 p/kWh into 0.25 GBP/kWh |
| Cost about 1,000× too large | Market EUR/MWh interpreted as EUR/kWh | Divide EUR/MWh by 1,000 |
| Always shows cheap rate after restart | Utility Meter select not synchronised | Run clock-based tariff selection on Home Assistant start |
| Zero cost during internet outage | Unknown price defaulted to float(0) | Use numeric availability checks; monitor update age |
| Night-rate usage far below expectation | Wrong clock, schedule or energy source | Validate boundaries and real import kWh against supplier data |
| Energy dashboard rejects sensor | Missing numeric state or invalid unit/statistics | Inspect Developer Tools → States and Statistics |
| Negative market price triggers all loads | Wholesale price used without retail formula | Apply exact contract pricing and constraints |
| Tomorrow schedule breaks on clock change | Assumed fixed-length hourly array | Use explicit timezone-aware start/end timestamps |
| Invoice higher despite matching energy charge | Daily/network/tax charges omitted | Model fixed charges separately and label estimate |
Shopping checklist: what hardware is actually useful?
You do not need a new “dynamic tariff meter” simply to create a time-aware price sensor. A price feed is information; an energy meter measures consumption. Hardware becomes useful when you need trustworthy actual kWh figures, local operation, tariff switching evidence or approved device control. For a beginner deployment, prioritise compatibility and data quality over the number of features on a retail box.
| Purchase category | Choose for | Verify before buying |
|---|---|---|
| DIN-rail energy meter | Reliable cumulative grid import/export in a consumer unit | Correct phase count, current rating, certification and supported interface |
| CT-clamp monitoring system | Non-invasive current measurements at compatible circuits | Installation restrictions, accuracy, phase pairing and true energy measurement |
| Local data gateway | Expose metering data to Home Assistant without cloud reliance | Documented Modbus/MQTT/local API, maintenance and authentication |
| Home Assistant host | Continuous logging, price history and automations | Stable power, backup, reliable recorder storage and recovery |
| Approved EV charging controls | Shift charging into lower-priced periods | Charger schedule API, tariff integration and certified load management |
Mains monitoring equipment should be installed by a suitably qualified professional where required. Never work inside an energised electrical board as a shortcut to collecting better statistics. Our current transformer selection guide and single- versus three-phase monitoring guide explain compatibility and installation questions.
Start with the contract: a six-part tariff audit before writing YAML
The hardest part of a home electricity price sensor is rarely the template syntax. It is establishing which charge the value represents, when the charge applies and whether that number is suitable for billing estimation, display or automation. Those purposes overlap but are not identical. A tariff might make its rate available in a smartphone application while its invoice includes a separate time-based capacity charge. A wholesale feed might be precise to six decimals but have no contractual bearing on what your supplier bills. Conversely, a fixed tariff needs no API at all. Treat the signed contract and any published schedule of amendments as the authoritative input.
Before configuring the price sensor, record the billing country, supplier product name, tariff start/end dates, currency, VAT or sales-tax handling, grid/network variable charges, standing charges, import and export settlement rules, and the source of meter consumption. If the supplier switches a tariff seasonally, a static sensor needs an explicit update process. If the supplier prices in local time, confirm the official timezone and whether the time slots are defined by the beginning or end of a settlement interval. For customers with several meters or EV-specific contracts, document which register and sub-meter each rate applies to.
| Audit item | Question to answer | Required evidence | Consequence if wrong |
|---|---|---|---|
| Price definition | Wholesale, retail energy-only or all variable charges? | Contract formula and sample bill | The displayed cheapest hours may not be cheapest |
| Settlement period | 15, 30 or 60 minutes? | Supplier interval data with start/end | Consumption allocated to incorrect prices |
| Currency and scale | GBP/kWh, p/kWh, EUR/MWh or other? | Feed documentation and example value | 100× or 1,000× billing error |
| Effective dates | When does this contract or tax rate change? | Tariff letter or portal | Old price carried into a new billing month |
| Import/export distinction | Can power be sold at a different price? | Two rate schedules and two energy totals | Export earnings or purchases misrepresented |
| Standing and capacity fees | Daily, monthly, maximum-demand or fixed? | Bill breakdown | Invoice understated by non-energy components |
| Data completeness | Are all intervals published before an EV deadline? | API timestamps and day-ahead coverage | Incomplete schedule interpreted as cheap |
| Fallback | Who controls the load when API fails? | Approved equipment configuration | A network outage changes essential behaviour |
A useful design decision is to maintain two separate price concepts when required: the marginal import rate that informs whether using another kWh now is economical, and the full estimated bill that also incorporates standing fees, capacity charges or levies. If a standing charge is added artificially to each kWh, that may make a graph approximate the historic invoice, but it will corrupt the marginal rate used to decide when to charge a vehicle.
Meter architecture: avoid confusing site demand, grid import and net power
A modern house with solar PV and a battery can consume 4 kWh indoors while importing only 1 kWh from the public grid. Its tariff-linked import cost concerns the 1 kWh measured at the agreed grid boundary, not the 4 kWh of household load. A battery that charges from the grid at night can increase imported kWh now while reducing it later; counting the battery discharge as free energy will misstate the economics if charging losses and the earlier purchase are ignored. For energy billing, use the same boundary as the supplier meter whenever practicable.
Many inverters publish one signed net-grid-power sensor: positive power may mean import and negative export, or the opposite, depending on the manufacturer. A signed instantaneous net-power stream is not the same thing as two increasing cumulative counters. Using net energy over a whole day, after subtracting export from import, conceals the fact that the supplier may bill all imported units at one rate and remunerate exported units at another. Three-phase systems introduce another issue: some data sources report per-phase arithmetic or summed current that does not follow the utility meter’s billing rule. Verify the meter and integration before using an apparent whole-house kWh entity.
| Measurement | Valid use | Typical mistake | Verification |
|---|---|---|---|
| Grid import cumulative kWh | Actual purchased energy by interval | Subtracting export before assigning price | Compare import register against bill |
| Grid export cumulative kWh | Energy sold to grid | Applying the import rate to export | Check export settlement and registration |
| PV generation cumulative kWh | Solar plant production | Treating all PV as bill avoidance | Account for self-use, battery and export |
| Battery charge/discharge kWh | Storage losses and dispatch analysis | Double counting internal power flows | Check AC/DC conversion and meter location |
| Site load power kW | Present physical demand, rough forecasts | Using load power as paid grid import | Cross-check at grid interface |
| Grid signed power kW | Fast import/export trend | Mistaking sign for billing register | Test known import and export event |
| Supplier smart meter interval totals | Reference for bill reconciliation | Assuming live API data are immediate | Check timestamp, lag and corrections |
See our solar import/export metering guide and Home Assistant Energy dashboard entity guide for a fuller explanation of meter boundaries. Where the existing meter reports accurate delivered kWh, do not replace it with an ESP32AliExpress price power integral without first quantifying clock drift, sample loss and calibration errors. An external CT monitor can add visibility; it does not automatically become a billing-grade meter.
Correct time alignment: interval prices are not simply clock labels
A dynamic tariff record should ideally be modelled as a tuple of start_utc, end_utc, price, unit, currency and a source publication timestamp. The price is valid on a half-open interval: from its start inclusive to its end exclusive. Half-open intervals avoid double allocating the boundary instant. An imported energy increment between 14:10 and 14:25 must be assigned to the matching period; if an increment spans a tariff change, the meter or calculation needs finer-grained data or an explicitly disclosed allocation approximation.
Do not use an array position such as “slot 14” without attaching a timestamp. A 15-minute market has up to 96 ordinary intervals per 24-hour day, but daylight-saving changes produce local calendar days of different real durations. More importantly, a supplier may publish 30-minute retail settlement intervals even when the underlying day-ahead market uses 15-minute products. The correct granularity is the one used by the signed retail contract and consumption settlement, not whatever chart happens to be most detailed. An hourly averaged price might be adequate for retrospective charts, yet wrong for dispatching an EV into a cheap 15-minute slot.
| Time model | Typical records per ordinary day | Strength | Failure if simplified |
|---|---|---|---|
| Static tariff | 1 rate until effective-date change | Minimal maintenance | Missed contract changes |
| Two-rate local civil time | 2 or more daily rate changes | Clear peak/off-peak accounting | Timezone and DST boundaries |
| Hourly dynamic | 24 ordinary one-hour intervals | Simple planning | Loses intra-hour market detail |
| Half-hourly dynamic | 48 ordinary half-hour intervals | Matches some retail settlement products | Bad 15-minute mapping |
| Quarter-hour dynamic | 96 ordinary 15-minute intervals | Fine-grained price data | Mistakenly assuming fixed daily row count |
| Time-zone change day | Variable record count | Accurate contractual timestamping | Duplicated or missing local-clock periods |
Home Assistant’s time automations use its configured timezone. Validate that setting under Home information and test both the clock change at the end of March and the change at the end of October in the relevant region. Never compare a raw UTC string such as 2026-10-25T01:30Z to a naive local timestamp. A schedule on the repeated local hour requires the correct UTC offset to distinguish the two occurrences. The official Nord Pool integration explicitly warns that its market intervals can transition to 15 minutes; integrations and optimisers should be tested against this, not left with a hard-coded 24-slot assumption.
Practical YAML: a maintained fixed or seasonal tariff instead of hard-coding forever
A fixed-rate household can enter the current unit rate directly into the Energy dashboard. If several dashboards and calculations need the same rate, an input_number helper provides a central editable value, which can be wrapped in a numeric Template sensor. This approach has one operational advantage over a value typed into several YAML files: a household member can update the rate following a supplier letter without editing automation source. Its downside is that someone must verify the tariff’s effective date; a helper is not an automatic supplier API.
input_number:
import_rate_gbp_per_kwh:
name: Contract import rate GBP per kWh
min: 0
max: 2
step: 0.001
mode: box
initial: 0.265
template:
- sensor:
- name: Contract import rate
unique_id: contract_import_rate_helper
unit_of_measurement: "GBP/kWh"
state_class: measurement
availability: >-
{{ is_number(states('input_number.import_rate_gbp_per_kwh')) }}
state: >-
{{ states('input_number.import_rate_gbp_per_kwh') | float }}
The numeric helper value of 0.265 means 26.5 pence/kWh. The initial setting is optional and should be removed if you prefer the helper to restore its saved value rather than force the illustrative value on every restart. The example is documentation, not an actual UK offer; edit the numeric range and currency to suit your contract. A monthly tariff review automation can notify you to check the rate, but it should not invent a new price if the supplier feed is unavailable.
Do not copy this second template: root into a file that already has another top-level template: key without merging the list entries. Duplicate YAML keys can silently override the intended configuration depending on the parser. With a single clean configuration, confirm the helper and price sensor in Developer Tools, check that the sensor is numeric, and watch it change when the helper is edited.
A resilient TOU implementation: tariff selection, restart and date exceptions
Home Assistant Utility Meter supports consumption split into named tariff buckets. That gives the homeowner actual peak and off-peak kWh over the billing cycle rather than only an instantaneous rate. But its selector must be kept in sync with the utility contract. The basic example above uses two daily scheduled actions plus a start trigger. That works for a repeating day/night schedule; it does not cover public-holiday exceptions, dynamic prices, supplier-specific weekend rules, or seasonal changes by magic.
A further practical improvement is to schedule a periodic consistency check rather than relying entirely on the original two daily events. If Home Assistant is rebooting exactly at the tariff boundary, the periodic check can correct a stale select state. The pattern below computes the expected bucket for a simple 23:00–07:00 local night rate and sets the Utility Meter select only if the actual state differs. Use it alongside the meter configuration, or replace the separate two boundary automations with this reconciler; running both is unnecessary.
automation:
- id: reconcile_monthly_tou_tariff
alias: "TOU - Reconcile tariff on start and every 15 minutes"
triggers:
- trigger: homeassistant
event: start
- trigger: time_pattern
minutes: "/15"
variables:
expected_tariff: >-
{{ 'offpeak' if now().hour >= 23 or now().hour < 7 else 'peak' }}
conditions:
- condition: template
value_template: >-
{{ states('select.monthly_grid_import_tou') != expected_tariff }}
actions:
- action: select.select_option
target:
entity_id: select.monthly_grid_import_tou
data:
option: "{{ expected_tariff }}"
mode: single
A fifteen-minute check does not guarantee exact billing accuracy at a tariff boundary if Home Assistant is offline or the source meter samples infrequently. If exact allocation is required, use a meter or supplier record with actual per-period registers. On complex contracts, model the full tariff calendar from an authoritative schedule instead of trying to express every exception as a collection of hour comparisons. Utility Meter is an analysis tool; it cannot retroactively reconstruct lost per-period measurements from a missing meter history.
| Test | Expected result | Escalation if it fails |
|---|---|---|
| Start server at 03:00 | offpeak selected after boot | Check timezone and select entity ID |
| Start server at 14:00 | peak selected after boot | Check template and entity availability |
| Cross 23:00 boundary | New import increments counted in offpeak | Check source sample and event delay |
| Change tariff helper manually | Displayed current price follows edited value | Check one source of truth |
| Disconnect meter for 30 minutes | Missing energy recognised, not invented | Recover source history or flag gap |
| Supplier weekend exception | Correct special schedule | Replace simple clock template |
| DST transition | No duplicate accounting from naive timestamps | Inspect supplier settlement records |
Choosing the right data source: official integration, community integration or your own API
An official integration is not necessarily appropriate for every household: an integration called “Nord Pool” cannot identify a UK customer’s supplier-specific charge, and a retailer integration may expose one customer’s account data while another contract uses a different price formula. Evaluate the feed’s semantics before its convenience. Does it return the current applicable retail price or only the wholesale reference? Does it expose the complete future time series for tomorrow? Is there a timestamp for the last successful update? What happens when tomorrow’s publication is late? Is a negative price legally passed through to the homeowner after supplier fees? These are contractual questions, not merely API questions.
The official Tibber integration provides pricing and, when supported by the account and metering hardware, consumption and cost data. Its actual sensors and information depend on the customer account. The official Nord Pool integration instead provides market prices and explicitly excludes VAT and other added costs. The EnergyZero and easyEnergy integrations are relevant only where their market and provider definitions fit. For UK suppliers, community integrations may be useful but bring additional maintenance risk and authentication requirements; evaluate their latest documentation and supported tariff variants rather than assuming a third-party project covers every plan.
| Source selection | Why you might use it | Key risk | Suggested validation |
|---|---|---|---|
| Supplier-provided retail integration | Direct price aligned with customer plan | Unknown tax, contract or account mapping | Compare random 20 intervals to tariff portal |
| Official Nord Pool integration | Well-documented market time series | Not the complete retail rate | Apply and test actual contract transformation |
| Official Tibber integration | Price and potentially account usage/cost | Only for supported Tibber customers | Compare entity values with supplier account |
| Other native HA market integrations | Market access by country/provider | Regional, tax and product limitations | Check documentation and current coverage |
| Community integration | Specific supplier and tariff features | Release changes, tokens and maintenance | Test updates and alert on errors |
| Custom REST and template model | Transparent bespoke formula | User maintains API schema and clock logic | Contract-based automated regression tests |
| Manual two-rate schedule | No cloud dependency | Human tariff update and exceptions | Compare every change date against contract |
When selecting a community integration, also evaluate how secrets are stored, its permissions and maintenance history. Keep API credentials out of publicly shared YAML and screenshots. Do not copy a tariff response containing a customer identifier directly into published documentation. The output of a third-party API should be treated as untrusted data, with numeric range checks and freshness validation before it is used in an automation.
Worked accounting example: a full-day import, export and standing charge
Consider a hypothetical 24-hour period with three import price blocks. The home imports 4 kWh at £0.12/kWh, 8 kWh at £0.23/kWh and 6 kWh at £0.34/kWh. This makes total purchased energy 18 kWh. The import energy charge is £0.48 + £1.84 + £2.04 = £4.36, giving a consumption-weighted import rate of approximately £0.2422/kWh. If the house exports 5 kWh at a separate illustrative £0.07/kWh, the export credit is £0.35. Adding a separate £0.50 daily standing charge yields a simplified net daily amount of £4.51; actual tax, network charges, gross/net settlement and rounding can differ.
| Bill component | Quantity | Rate | Calculated amount |
|---|---|---|---|
| Off-peak import | 4 kWh | £0.12/kWh | £0.48 |
| Standard import | 8 kWh | £0.23/kWh | £1.84 |
| Peak import | 6 kWh | £0.34/kWh | £2.04 |
| Total import | 18 kWh | Weighted £0.2422/kWh | £4.36 |
| Export credit | 5 kWh | £0.07/kWh | −£0.35 |
| Daily standing fee | 1 day | £0.50/day | £0.50 |
| Illustrative net daily subtotal | — | Before other invoice items | £4.51 |
This example demonstrates why neither a single flat rate nor a net import-minus-export meter is adequate for all bills. If you multiplied the 13 kWh net import by the average purchase rate, the result would not recover the fact that exported energy is paid at a different rate. It also illustrates the difference between buying 18 kWh today and causing the household to consume 18 kWh: some energy could have passed through a battery at different times. Keeping a simple table of each billing component makes later reconciliation much more defensible.
If the invoice contains a standing charge of £0.50 per day over 31 chargeable days, that component totals £15.50 regardless of whether you import 1 kWh or 1,000 kWh. Allocating it into the instantaneous marginal import price creates a circular dependency: the “price per kWh” changes with the amount you use, which can distort price-aware automation. Reserve a separate billing view for such charges. For capacity or peak-demand charges, use the exact supplier-defined calculation, typically based on a specified maximum interval demand or contracted limit rather than ordinary per-kWh arithmetic.
Worked scheduling example: an EV can save money without a complex optimiser
Suppose an EV must receive 12 kWh from the grid before 07:00, measured at the site boundary for this example. The retail tariff is £0.10/kWh in one overnight window and £0.28/kWh in an alternative period. Moving 12 kWh of grid import from the higher to the lower window saves 12 × (£0.28 − £0.10) = £2.16 in variable purchase cost, before other contractual factors. But if the requirement is 12 kWh into the vehicle battery, the charger may need more grid energy because of charging loss. Assuming 90% end-to-end efficiency for illustration requires roughly 13.33 kWh from the grid; the corresponding arithmetic saving is about £2.40. Real efficiency varies with car, ambient temperature and current.
Price selection alone is not enough to create a feasible schedule. A single-phase charger operating at 6 A and 230 V draws roughly 1.38 kW before equipment losses; it cannot deliver 13.33 grid kWh inside a four-hour slot. A nominal 7.4 kW charger may instead be constrained by the household supply or vehicle. A half-hourly cheap-price period offers only one half-hour of energy, not a whole night. Schedule calculations must use the approved current limit, available phase(s), departure time and a conservative margin for failed starts or delayed vehicle communication.
| Scenario | Assumption | Arithmetic outcome | Decision |
|---|---|---|---|
| 12 kWh grid energy, dear slot | 12 × £0.28 | £3.36 | Baseline for comparison |
| 12 kWh grid energy, cheap slot | 12 × £0.10 | £1.20 | £2.16 variable saving |
| 12 kWh delivered to battery, 90% efficiency | 12/0.9 | 13.33 kWh grid import | Account for losses |
| Four-hour 6 A charging window | 230 V × 6 A × 4 h | About 5.52 kWh maximum grid energy | Cannot satisfy 13.33 kWh requirement |
| Two-hour 7 kW charging window | 7 kW × 2 h | Up to 14 kWh grid energy | Possible if device/supply allow |
| Feed fails at start time | Future price unknown | No valid price decision | Rely on charger-native fallback |
The cheapest theoretical interval should therefore be a candidate, not an unconditional command. For a regular off-peak contract, the car or charger’s own approved scheduling system may be both cheaper to maintain and more resilient than a complex Home Assistant optimisation. For a genuinely dynamic retail contract, forecasting helps only after the input prices, remaining energy demand and operating constraints are correct. Our EV charging with dynamic tariffs article examines that decision in more detail.
Home Assistant Energy dashboard: estimate bills without corrupting the source measurements
The Energy dashboard typically expects cumulative kWh sensors for grid import and export, with appropriate energy device class and long-term statistics. It can estimate cost using a known fixed rate or a suitable changing price entity, but pricing the same consumption more than once, or supplying cumulative cost in place of a rate, can produce nonsense. If an integration exposes a supplier-calculated cumulative monetary cost, follow the supported Energy dashboard configuration for that integration; do not mix a pre-integrated cost statistic and an independent price multiplication for the same import stream without checking for duplication.
A price sensor labelled GBP/kWh should contain numbers such as 0.245, not text such as “cheap” or “24.5p”. The price may have a state_class: measurement for history, but should never be declared as total_increasing because it is not an accumulating quantity. A grid import energy sensor usually is accumulating and may need device_class: energy and state_class: total_increasing, depending on its source data model. Check Home Assistant’s official grid integration guide and Template sensor reference before copying a configuration from an older tutorial.
Recorder continuity matters. If a tariff changes at 00:30 but the import meter updates only at 01:00 with the preceding hour’s cumulative kWh, the Energy dashboard may have too little temporal detail to allocate the consumption accurately across the two rates. A smooth 24-hour graph cannot recover the exact unknown 30-minute distribution. If accurate allocation is a financial requirement, use data with timestamps or settlement intervals aligned to the supplier meter. For dashboards, label any interpolation as an estimate rather than presenting it as invoice-equivalent precision.
Automations: separate price availability from permission to run a load
A cheap-price flag is not a safety interlock. It can indicate that electricity is likely to be cheaper, but it should never replace a manufacturer’s permitted operating mode, electrical protections, or household load limits. A conservative automation can publish a recommendation or notification without switching equipment. If a load is authorised for remote scheduling, create independent conditions: the price is numeric and fresh, the equipment reports itself available, the permitted time window has begun, a manual override is not active, and the task has not already completed. Safety-critical decisions belong to certified equipment, not a best-effort home server.
The following example creates a monitoring-only binary sensor indicating that the current contract-rate entity is numerically available and below an illustrative threshold. It does not command a relay, charger or heat pump. The availability check ensures that a cloud failure does not become the Boolean equivalent of a zero price; separate update-age checks are needed for sources that can freeze at a valid-looking old number.
template:
- binary_sensor:
- name: "Electricity price below threshold"
unique_id: electricity_price_below_threshold
availability: >-
{{ is_number(states('sensor.contract_import_price')) }}
state: >-
{% set price = states('sensor.contract_import_price') | float %}
{{ price < 0.15 }}
Price threshold logic can hide surprising assumptions. A £0.15/kWh threshold might be appropriate for one contract in one year and completely inappropriate in another; relative thresholds based on the full forthcoming day can be more useful for dynamic tariffs, but only if future intervals are complete. If the negative wholesale price is passed through to retail only partially, using a wholesale threshold would produce the wrong decision. In all cases, maintain a visible manual override and record whether the automation merely advised an action or actually changed the operating state of a device.
| Control dependency | Authoritative owner | Home Assistant responsibility | Failure response |
|---|---|---|---|
| Main connection/load limit | Installer-approved EVSE or protective equipment | Observe and request only allowed charging states | Local load limiting continues |
| Hot-water high-temperature protection | Cylinder thermostat and thermal cut-out | Monitor tariff and optional approved schedule | Independent protection remains active |
| Heat pump defrost/anti-freeze | Manufacturer controller | Non-critical schedule recommendation | Manufacturer programme continues |
| Battery cell limits/SoC protection | Battery management system | Read-only forecast or approved high-level mode | BMS and inverter enforce limits |
| Tariff forecasting | Supplier source and verified transformation | Validate timestamps and compare choices | No new price-based optimisation |
| Departure deadline | Driver/charger native deadline schedule | Optional convenient planning | Device-native plan protects usability |
Validate the system with a 14-day commissioning test
A good tariff setup deserves the same attention as an energy meter calibration. Start by running the price sensor only as a dashboard for several days. Record current contract rate, feed time, whether the utility tariff select matches the rate, import kWh and any tariff schedule exceptions. Then compare daily cost against a supplier portal or an independently calculated interval spreadsheet. Only after the data are believable should an owner consider using them for discretionary scheduling; even then, begin in “advisory” mode and compare the selected hours with what the device actually did.
| Day / test | Evidence to capture | Pass criterion | Notes |
|---|---|---|---|
| Day 1 — contract baseline | Contract documents, price unit, taxes | Price formula documented | Record tariff revision date |
| Day 2 — entities | Sensor units and HA entity IDs | Numerical units and valid statistics | Check energy vs power |
| Day 3 — peak boundary | Two rate changes plus kWh | Correct bucket and tariff price | Check source update lag |
| Day 4 — restart | Restart inside peak and off-peak | Correct restored select | Do not assume initial default |
| Day 5 — bad price | Unavailable or malformed source value | No false free-energy rate | No equipment commands |
| Day 6 — stale source | Feed timestamp unchanged beyond tolerance | Raise alert or mark invalid | May need separate timestamp entity |
| Day 7 — first bill cross-check | Daily supplier portal figures | Understand deviations | Account for posting delay |
| Days 8–10 — flexible demand | Metered EV or heater power and timestamps | Recommendation matches contract | No unsafe control wiring |
| Day 11 — time-zone review | UTC/local boundary records | Correct offset and interval | DST test with archive data |
| Day 12 — export credits | Import and export measured separately | No netting at wrong rate | Check contractual export plan |
| Day 13 — accounting reconciliation | Unit charges, VAT, standing fee | Difference explained or investigated | Document rounding rules |
| Day 14 — sign-off | Saved configuration, fallback test, backups | Repeatable evidence | Review after tariff change |
The most instructive failures are often plausible values. A source frozen at £0.12/kWh for six hours may appear beautifully stable, yet cost analysis and optimisation will be wrong if the tariff had moved to £0.33/kWh. A supplier app may report “current” while displaying the hour after the settlement period has already ended. Recording source publication time and price interval start/end is therefore as important as recording the price itself. A successful monitoring trial produces a documented error budget and a list of conditions under which the data must not control expensive loads.
Bill reconciliation: build a reproducible monthly calculation
An effective validation sheet can be built from interval records with the columns start_utc, end_utc, grid_import_kWh, retail_import_GBP_per_kWh, grid_export_kWh, retail_export_GBP_per_kWh, and the calculated monetary components. For each interval, calculate import charge as the imported kWh multiplied by the price valid for that interval; calculate export credit separately. Sum the intervals, then add fixed charges and taxes according to the actual contract. Do not apply one tax multiplier twice or include a tax already embedded in the unit rate.
For example, a monthly bill may report 380 kWh imported and 125 kWh exported. If the Energy dashboard reports only 362 kWh imported, the 18 kWh difference needs investigation independently of the price sensor. No clever pricing template can correct missing meter data. A clean diagnostic sequence is physical energy → temporal allocation → rate → charge → other invoice elements. If the physical imported kWh matches but the cost does not, the likely causes move towards tax, standing charges, rate period selection or a supplier adjustment. If even the kWh disagree, fix the meter first.
| Reconciliation layer | Independent reference | Tolerance / action |
|---|---|---|
| Imported kWh | Utility bill meter or settlement data | Investigate any material discrepancy |
| Exported kWh | Export statement and meter | Check export registration and data delay |
| Interval count | Supplier published period schedule | Do not silently fill missing slots |
| Retail unit price | Contract and invoice | Match currency, tax and effective dates |
| Variable imported charge | Interval sum or supplier statement | Explain rounding and tax difference |
| Fixed daily or monthly charges | Contract and invoice dates | Count chargeable days correctly |
| Peak capacity charge | Supplier demand calculation | Match averaging window and maximum demand |
| Estimated total bill | Independent spreadsheet | Record gap and investigation outcome |
Keep a snapshot of the tariff formula, meter calibration and integration version used for each billing period. A Home Assistant update can change how a price feed exposes attributes, while the supplier may change rate periods without an obvious dashboard warning. A date-stamped reconciliation record supports a rational decision about whether a software change improves accuracy. Our guide to verifying Home Assistant energy against the bill covers the metering side in detail.
Negative and near-zero prices: opportunities and traps
A negative wholesale rate is a real market phenomenon, but it is not a universal invitation to consume energy. Some retail contracts pass through negative prices; others impose floors, levies or additional variable charges that leave the net import price positive. A contract can even include different rates for import, export and control services. If an automation sees a negative number from a market integration, first determine whether that figure is your marginal retail import rate. Confusing market price with the supplier’s retail offer can make supposedly clever “charge now” decisions financially worse.
In a solar-equipped household, very low import prices can also change the relative merits of charging the battery, preheating water or exporting PV. Compare the tariff paid now against the value of preserving stored energy for later. Battery round-trip losses, degradation and any restrictions on charging from the grid matter. A 10 kWh battery charged from the grid at £0.10/kWh and returned at 85% usable efficiency yields only 8.5 kWh of usable output; saving £0.30/kWh later avoids £2.55 of future purchases, against £1.00 spent now, before any degradation or other fees. The apparent £1.55 gross opportunity can vanish under a different tariff, export opportunity cost or battery limits.
For an EV, its battery and charger protections govern charge current, temperature and minimum operating limits. Price data are supervisory information. For a domestic hot-water cylinder, the approved cylinder controls and hygiene requirements continue regardless of negative wholesale prices. For a heat pump, excessive rapid switching can undermine efficiency and equipment life. A bargain-hour algorithm that adds unscheduled thermal cycles may be more expensive than a steady low-temperature operating strategy once COP and heat losses are considered.
Security, maintenance and future-proofing
Every external tariff integration increases the number of components that can fail: the provider, login credentials, API token, cloud connection, integration software, entity registry and recorder database. Choose a stable Home Assistant host, back up your configuration, use integration-specific credentials with minimum needed permissions, and monitor authentication or data retrieval errors. If the supplier offers an official supported integration, that can reduce maintenance, but its existence does not remove the need to validate the retail contract model.
Keep the code small and auditable. Separate the raw-source price from any contract-adjusted price in different entities, naming their units explicitly. Build a simple diagnostic dashboard showing both values, source last update, the active tariff bucket and the import meter. After each integration update, sample known intervals and confirm that the price has not switched from EUR/kWh to EUR/MWh, or from net-of-tax to tax-inclusive. When using templates, avoid forcing invalid values to zero. When using dynamic forecast arrays, validate their date range, interval count and chronological ordering before they are delivered to an optimiser.
| Maintenance item | Suggested routine | Why it matters |
|---|---|---|
| Contract price formula | Check each tariff change | Supplier terms outrank API assumptions |
| API refresh status | Monitor daily | Detect stale but numeric values |
| Home Assistant release notes | Review before major upgrade | Integrations and template syntax evolve |
| Energy sensor statistics | Check monthly | Prevent gaps and false resets |
| Backup and restore | Test periodically | Recover price history and automations |
| EV/native device fallback | Test after controls change | Avoid missed departures or unsafe overrides |
| DST and interval timestamps | Test before clock change | Detect local-time ambiguity |
| Cost against bill | Reconcile per billing cycle | Quantify real financial error |
This is also why buying hardware exclusively because it promises “AI tariff optimisation” is rarely the first step. Spend first on credible grid measurements, clear contract interpretation and a reliable Home Assistant installation; add an optimiser when there is a specific flexible load that can be scheduled and an independently measurable advantage over the charger or appliance’s native capabilities.
Frequently asked questions
Can Home Assistant show my exact electricity bill?
It can estimate the cost of measured imported electricity and, with suitable data, export credits. Exact invoices can include standing charges, levies, taxes, rounding rules, estimated meter reads and contract-specific adjustments. Reconcile rather than assume parity.
What unit should my price sensor use?
Use a numeric currency-per-kWh value such as GBP/kWh or EUR/kWh and ensure the magnitude matches that unit. A pence-per-kWh feed must be divided by 100 before being labelled GBP/kWh.
Do I need Utility Meter for a changing price sensor?
No. Utility Meter is useful for tracking kWh within tariff buckets and billing cycles. A dynamic price sensor can independently provide the current rate to the Energy dashboard.
Does Utility Meter automatically know the off-peak times?
No. For tariffs defined in Utility Meter, an automation or other input must change the active tariff select entity. The correct state should be restored at start-up.
Are Nord Pool prices what my supplier charges?
Not necessarily. Nord Pool provides market prices without your supplier’s full retail fees and taxes. Apply the exact contract formula or prefer a retail-price sensor.
Can I use the next-day lowest price to start an EV charger?
Only if your actual contract tracks that price, the feed is current, the charger supports that schedule, and the plan respects charging deadlines and approved safety/load-management constraints.
Why do my tariff sensors sometimes show unavailable?
A provider API outage, expired credentials, a changed entity ID, invalid numeric values or internet failure can all cause this. Unavailable is usually safer than silently converting missing data to zero.
How do negative electricity prices work?
Some wholesale markets report negative rates. Whether your retail contract passes that through—and whether taxes or fixed per-kWh charges make the final import rate positive—depends on its written terms.
Should standing charges go into my pence-per-kWh sensor?
Normally not. A standing charge is fixed per day, while a unit price varies with kWh. Combining them distorts the incremental price used for load scheduling.
What happens on daylight-saving changeover days?
Local clock days can cover 23 or 25 elapsed hours. Trust timezone-aware interval timestamps from the supplier and avoid assuming a daily price array always contains 24 records.
Can the same sensor work for import and solar export?
Not safely if the contract has separate purchase and sale rates. Use separate import and export energy totals and applicable price entities.
Can my current electricity price sensor be used with EMHASS?
A current price alone is not enough for a forward-looking optimiser. It needs future interval prices plus appropriate load/device constraints, and those forecast rates should represent the contract you pay.
What should I do if Home Assistant loses its internet connection?
Keep ordinary device-native schedules and safety functions in place. Suspend decisions that require unknown future prices, or use an explicitly tested conservative local fallback.
Is a fixed tariff more reliable than dynamic integration?
The static data feed is easier to maintain, but economic suitability depends on the real contract and usage pattern. Reliability of the Home Assistant implementation and the tariff’s financial value are different questions.
Further reading and official references
- Home Assistant official: Integrating your electricity grid — accepted energy sensors and Energy dashboard configuration.
- Home Assistant official: Utility Meter — tariff splitting, select entity, billing cycles and restart behaviour.
- Home Assistant official: Template integration — numeric sensors, availability and units.
- Home Assistant official: Nord Pool — market prices, 15-minute transition, VAT exclusions and data access.
- Home Assistant official: Energy FAQ — statistics, supported units and missing entities.
- Further on esp32AliExpress price.co.uk: Price-aware Home Assistant automations for flexible loads (planned related article), and EV charging on dynamic tariffs.
Editorial note: Example prices, fees, thresholds and schedules are educational placeholders. Check the current supplier contract, meter configuration and Home Assistant documentation before applying them. Energy controls must never disable a manufacturer’s protection or required safety device.