Prerequisites

Grid Lens requires Home Assistant 2024.1 or later with the following already working:

  • The Energy dashboard configured with at least grid consumption sensors
  • Your electricity retailer and current plan details (tariff rates, peak/off-peak times)

Solar, battery, and EV sensors are optional but unlock more accurate modelling.

Note: Grid Lens works with any HA-compatible energy sensor. You don't need a specific inverter or meter brand.

Install the App

Via HACS (recommended)

Add the Grid Lens repository to HACS as a custom repository:

  1. Open HACS → Integrations → ⋮ menu → Custom repositories
  2. Add https://github.com/dankasak/gridlens with category Integration
  3. Search for "Grid Lens" and install
  4. Restart Home Assistant

Manual install

Copy the custom_components/grid_lens folder from the GitHub repo into your HA config/custom_components/ directory, then restart.

Configure

After restarting, go to Settings → Devices & Services → Add Integration and search for Grid Lens.

Setup is four short screens:

  1. Your state and email address. If more than one network in your state has plan data, you'll be asked which distributor operates the poles and wires at your address — it's printed on your bill, and it isn't your retailer.
  2. Your energy sensors (grid import, and optionally export, solar and price). These are pre-filled from your Home Assistant Energy dashboard if you've set one up.
  3. Your battery, if you have one — capacity and charge/discharge rates. The checkbox is pre-ticked if your Energy dashboard already has a battery configured.
  4. Your current electricity plan.

If your Energy dashboard lists individual appliances, you'll also get a screen to pick which of them can be shifted to cheaper hours, and set each one's maximum power.

Everything else — controlled load, allowed run hours, modulating charger control, battery efficiency and charge limits — has a sensible default and can be changed later under Grid Lens → Configure. Nothing you skip at setup is lost.

Proof-of-concept phase: Grid Lens currently supports NSW — Ausgrid (Sydney, Central Coast, Newcastle, and Hunter regions). We are expanding to Endeavour Energy, Essential Energy, and other states rapidly. If your network isn't covered yet, setup will tell you so on the first screen rather than letting you fill in the rest.
Free plan: Setup never asks you to pay. Your free account models your current plan at no cost; upgrading to compare against every plan is offered afterwards as a notification.

View the dashboard

Grid Lens adds a Grid Lens dashboard to your Home Assistant sidebar automatically — no cards to add, no YAML. It has three views:

  • Plan Comparison — cost across all modelled plans for a date range you choose, the optimal usage profile under each, and the estimated bill for the period. Type in the retailer filter at the top to narrow the list as you type; the plan you're currently on always stays in view so you keep a baseline to compare against. The Exclude Greedy Consumption checkbox alongside it keeps opportunistic runs (see Greedy Consumption) out of what alternative plans are scored against, so a device that only ran extra because your current plan made it free doesn't make every other plan look worse than it is. Your own plan's cost is never affected — it's always your real bill. While the checkbox is on, every alternative plan's card shows a diagonal-striped banner under its charts, since its numbers are an adjusted estimate rather than your literal historical usage on that plan. The What if? panel lets you try a different battery size and solar system size — including none at all — to see what every plan would cost with that hypothetical setup instead of what you actually have. Pick a battery size in kWh (0 = no battery) and a solar percentage (0 = no solar, 100 = your real system, 200 = double it), or use the "No solar or battery" / "My current setup" shortcuts. Because a hypothetical system has no real bill to measure against, every total shown — including for the plan you're on — becomes the optimiser's estimate rather than your actual metered cost, which is why a striped banner marks the whole comparison as a what-if scenario until you exit it.
  • Battery Plan — live energy flow, forecast vs. measured power, the battery state-of-charge curve, and the planned dispatch timeline.
  • Settings — deferrable load controls, allowed run times, and optimiser tuning.

The cards find their own entities, so they keep working as you add, remove, or reconfigure loads.

Required sensors

Grid Lens needs at least one of the following entity types, already configured in your Energy dashboard:

Sensor typeRequired?Notes
Grid consumption (kWh)RequiredTotal energy drawn from grid
Grid export (kWh)OptionalNeeded for feed-in tariff modelling
Solar production (kWh)OptionalEnables solar self-consumption analysis
Battery charge / discharge (kWh)OptionalEnables battery optimisation
EV / deferrable load (kWh)OptionalEnables load-shifting recommendations

Shade correction

If trees or a neighbouring roofline consistently shade your panels at certain times of day, your solar forecast provider has no way to know — it models weather and panel geometry, not your specific obstruction, so it over-forecasts the same hours every day regardless of cloud cover. Shade correction learns a per-hour correction by comparing your forecast against your own actual production history (via Home Assistant's own recorder — no data leaves your instance for this), and feeds it into the battery optimiser's forecast, not just a display number.

Off by default. Turn it on under Settings → Devices & Services → Grid Lens → Configure → Shade correction — it needs a Solar production sensor configured (see Required sensors above) to learn from. The forecast sensor it compares against is auto-detected; you only need to pick one manually if you run more than one forecast source.

Deferrable loads

A deferrable load is electricity usage you can shift to a cheaper time of day — for example an EV charger, pool pump, hot water system, or air conditioner.

To include a deferrable load in the optimisation, you need a sensor that measures its consumption. Grid Lens will model what each plan would cost if you shifted that load to its cheapest window.

Configure deferrable loads under Settings → Devices & Services → Grid Lens → Configure → Deferrable loads after setup. You set up one appliance at a time, and Grid Lens only asks what that appliance actually needs — a pool pump it can’t switch takes three answers, while a modulating EV charger is walked through its setpoint and battery settings on their own screens.

No consumption sensor at all for a controllable appliance (common for an IR-remote-controlled aircon)? Grid Lens can estimate one for you — see Estimated loads under Load control below.

Allowed run times

Each deferrable load has a weekly schedule — a per-weekday, half-hourly grid of when that appliance is allowed to run. Grid Lens picks the cheapest half-hours inside your rules; it never runs a load outside them.

Edit it on the Allowed Run Times card on the Grid Lens dashboard by painting hours with the mouse. A pool pump might be daytime-only; an EV charger might be unrestricted.

Note: the optimiser plans forward from now, not from midnight, so its first day spans two weekdays. Anywhere Grid Lens shows you "hours available", it means the next 24 hours — not a calendar day.

Today Boost

Grid Lens learns how much energy each deferrable load needs per day from its own sensor, averaged over the last 14 days. When today isn't typical — a long drive tomorrow, guests staying — override it with Today Boost, on the Power Flow page's expandable device panel or on the Deferrable Loads card (same controls, either place).

Set the kWh you actually need today; 0 means "use the historical average". The plan re-solves around it immediately.

A chart next to the input shows each device's actual daily use over the last two weeks, with the average of those days beside it — so you can see what "typical" is before deciding how far above it to go. Devices are listed biggest-consumer-first, so the ones most worth adjusting are at the top.

If you ask for more than the load's allowed window can physically deliver, the card shows you that ceiling rather than silently ignoring the excess.

If a load has its own battery with a charge ceiling set (an EV charged only to, say, 90%), and today it starts already close to that ceiling, Grid Lens can only schedule the charge that fits underneath it — which may be well below the 14-day average. When that happens the row shows a “SOC-limited” line with what it scheduled versus the usual amount; raise the load's Max SOC % under Configure to allow more.

Charge target

Today Boost tells Grid Lens how much energy a load needs today — but not by when. If you're heading off on a long drive and want the car at 100% by a specific time, set a charge target instead: a percentage and a deadline, on any load with an SOC sensor and capacity configured (the same setup Today Boost's SOC-limited ceiling uses).

Grid Lens still picks the cheapest, most solar-heavy slots between now and your deadline — it only forces full-power charging in the run-up if that's what it takes to make the target in time. It's not the same as forcing the load On, which charges flat-out immediately regardless of price.

Find it on the Grid Lens dashboard under Settings → Charge Targets — one row per eligible load, with a percentage field and a date/time field. Set both to activate; leaving the percentage at 0 cancels it. It's also available as two Home Assistant services, grid_lens.set_charge_target and grid_lens.clear_charge_target, for scripts and automations.

The target clears itself automatically once the load reaches it, or once the deadline passes — nothing to remember to turn back off.

Above your everyday charge ceiling? A target percentage higher than the load's configured Max SOC % (see Today Boost) is allowed — Grid Lens raises the ceiling for that one occasion, then returns to your everyday limit once it's done.
Only within the planning horizon. Grid Lens plans roughly 24–48 hours ahead. A deadline further out than that isn't ignored, just not yet accounted for — it's picked up and treated normally once it comes within range on a later replan.

Battery control

Comparison and planning are read-only. Battery control is the optional step where Grid Lens actually operates your inverter to follow the plan it found.

Turn on the Battery Control switch. From then on, every five minutes Grid Lens reconciles your battery against the current plan — charging from solar, charging from the grid during genuinely free or cheap windows, holding, or discharging into expensive periods.

  • Your configured minimum and maximum state-of-charge are always respected.
  • If you've told Grid Lens not to grid-charge, it will only ever charge from solar surplus.
  • The Minimum Export Price setting lets you say "below this feed-in rate, don't bother selling" — the optimiser will prefer storing the energy or spending it on a deferrable load instead. The same figure also widens Greedy Consumption's export-surplus trigger, so a load set to run greedily will soak up export priced below your floor rather than let it be sold cheap. It's available even without a battery, as long as you have at least one deferrable load.
Failure behaviour: if Home Assistant restarts, the plan goes stale, or you turn the switch off, Grid Lens hands the battery straight back to your inverter's own energy management system. It never leaves your battery stuck in a forced mode.

Battery control is brand-agnostic by design. Sigenergy is supported today; more inverter drivers are being added.

Load control

Grid Lens can also switch simple on/off appliances — anything exposed to Home Assistant as a switch entity that draws roughly a fixed power when running (a pool pump, a smart-plug-fed charger, a resistive heater) — or as a climate entity, so an air conditioner works the same way. Grid Lens only ever decides when it runs, never its mode or target temperature — those stay under your own control.

An EV charger that accepts a charging-current limit is handled differently, and better — see EV chargers below.

Assign a control switch (or climate entity) to a deferrable load via Grid Lens → Configure. Each controllable load then gets its own controls — on the Power Flow page's expandable device panel and on the Deferrable Loads card:

ControlDefaultWhat it does
Control switchOffMaster opt-in — Grid Lens drives this appliance per the plan.
On now / Off now—Manual override. Forces the appliance and stops Grid Lens driving it entirely, until you choose Auto.
Auto—Hands control back to the plan.
Everything is off by default. A fresh install never touches an appliance until you explicitly enable control for it. And Grid Lens will never force a running appliance off because it had a problem — if it loses its plan or Home Assistant restarts, it stops driving the load and leaves it exactly as it is.

EV chargers — variable charging current

An EV charger is not really an on/off appliance. Most can be told how many amps to deliver, and Grid Lens will use that: instead of slamming the charger fully on or fully off, it dials the charging current up and down to match what the plan wants and what your solar is actually producing right now.

This works with any charger integration that exposes a charging-current limit as a Home Assistant number entity — which is essentially all of them. Known-good shapes include OCPP (number.…_maximum_current), Easee, Wallbox, Zaptec, go-e, openEVSE, Tesla and Sigenergy. Point Grid Lens at that entity under Grid Lens → Configure and it takes over from there; there's no per-brand setup required.

Setting up a charger from a list, when yours is on it. The Deferrable Loads wizard's first modulating-load screen offers an optional Charger Brand dropdown. Pick your charger's brand and Grid Lens scans this Home Assistant instance for that brand's entities and pre-fills the fields below — still fully editable, nothing is saved until you finish the wizard as normal. Leave it on "Other" (the default) to fill everything in by hand, exactly as before this existed. A brand marked "(unverified pattern)" in the list hasn't been confirmed against real hardware yet — worth trying, but check what it fills in before saving; not listed at all just means pick the entities yourself below, same as always.

Some brands also carry a short Charger brand note, shown on the next screen once you've picked that brand. It only appears when there is something about that charger worth knowing before you save — typically a setting in the charger's own integration that would otherwise quietly fight Grid Lens's schedule. For a go-eCharger / Wattpilot, for instance, the note points you at a switch.…_charge_pause entity that ships disabled: if you enable it and leave it on, the charger inserts its own pauses that Grid Lens knows nothing about, so the note tells you to leave it off.

SettingDefaultWhat it does
Charging current entity—The charger's current-limit number entity. Leave it empty to keep plain on/off control.
Units / phases / voltageAutoDetected from the entity itself. Only set these if auto-detection gets it wrong.
Minimum current6 AThe lowest current your car will accept. Rarely needs changing.
Plugged-in sensor—Optional. Lets Grid Lens stop commanding a charger with no car attached.
Start / Stop buttons—Optional pair, for a charger with no stateful on/off switch at all, or whose current entity refuses to be set to exactly 0. Leave both blank if your Control Entity switch (or writing 0 A) already stops delivery — that's the common case. If used, both must be set together.
Max CurrentCharger maximumYour own ceiling — "never charge above 10 A", whatever the plan wants.

With Greedy Consumption switched on, a modulating charger does something an on/off one can't: it tracks your surplus continuously, every 30 seconds, ramping the current to absorb exactly what you're exporting. An on/off appliance has to wait until the whole of its draw is covered before it can switch on at all. For live surplus tracking you'll also need a grid power sensor configured — without one, the charger simply follows the optimiser's plan instead.

Why 6 amps matters. An electric car can't charge below about 6 A — offer it less and it won't charge slowly, it will refuse outright. So Grid Lens never commands an in-between current: it either charges at 6 A or more, or not at all. It also holds on a little past the point where it would otherwise stop, because a car that gets cut off can take half a minute to start again — better to ride out a passing cloud than restart the session.
Turn off the charger's own scheduling first. Many chargers ship with their own solar-following or scheduled-charging mode (PV surplus, Eco mode, a preferred-departure timer). Leave one of those switched on alongside Grid Lens and the two will fight over the same current setpoint — whichever wrote last wins, unpredictably. Before wiring a charger into Grid Lens, switch its own app or Home Assistant entities back to a plain "always available" / manual mode and let Grid Lens be the only thing driving the current.

Estimated loads

Some controllable appliances have no way to report their energy use at all — the classic case is an air conditioner driven by an infrared blaster, which can only send commands, never read anything back. You can still add these under Grid Lens → Configure → Deferrable loads → Add a deferrable load, choosing “No energy sensor, but I can switch it on and off from HA”: give it a name, its control entity, and a rough estimate of its power draw in kW.

Turn on auto-refine and point Grid Lens at a whole-house load power sensor, and it will quietly improve that estimate over time: whenever the appliance switches on, it compares your house's power draw just before and a few minutes after (long enough for a compressor to spin up) and folds a plausible reading into a running estimate. It learns from ordinary use — you don't need to do anything for it to collect data — and discards anything that looks unreliable (another controlled device changing state at the same time, an implausible jump). Leave auto-refine off, or skip the load power sensor, and it simply stays on your manual estimate.

Once configured, an estimated load behaves exactly like any other deferrable load — it gets its own schedule, Today Boost, Greedy Consumption, and all the same controls above.

Also fixes the Power Flow card for devices with no live power sensor — even ones that already have a real energy meter. Some devices (many ECHONET Lite air conditioners, for example) only report a running energy total, never an instant wattage, and the Power Flow card needs a live number to draw a node. The moment you set the whole-house load power sensor above, Grid Lens automatically builds one for every controllable device that's missing it — nothing else to configure.

Greedy Consumption

On most solar homes there are hours every day when your battery is full, your panels are still producing, and the surplus goes to the grid for a feed-in tariff of almost nothing. That's free energy leaving the house.

Greedy Consumption lets a load opportunistically run whenever energy is genuinely free, regardless of what the plan scheduled for that moment. Enable it per appliance. There are three triggers:

TriggerFires whenCan it cost money?
Free importYour plan's import price for this window is zero.No
Export surplusYour feed-in price is at or below your Minimum Export Price (zero if you haven't set one) and you're already exporting at least as much as this appliance draws — so running it can't create new grid import, it just uses export you'd rather not sell that cheap.No new import — only gives up feed-in revenue below the floor you set
Forecast surplusOver the next several hours — up to the point your plan itself next draws the battery down for something it values, like an evening export peak — the plan expects to export energy below your Minimum Export Price (zero if you haven't set one) at a rate that's worth running the appliance for. It runs proportionally to that rate (a fraction of full power for a charger, fully on for a simple switch) rather than all-or-nothing, and only once your battery has both the discharge rate and the spare charge to actually supply it, so it draws down the battery rather than the grid.No new import — only forgoes below-floor export the plan would have made anyway

The first two only fire once free energy is already flowing. That's often too late: mid-morning your battery absorbs every spare watt, so nothing looks free, even though the plan already knows the afternoon will spill far more than the appliance could ever consume. By the time surplus export actually appears, hours of run-time are gone.

Forecast surplus fixes that by starting the load early — proportionally, at the average rate the plan expects to waste energy over the safe part of that window. It's a separate opt-in because it's the one trigger that fires ahead of any live signal — the other two only ever confirm energy that is already flowing. It's safe two ways: it stops looking ahead at the point your plan itself starts drawing the battery down for something valuable (so it never borrows charge your plan was saving for the evening), and it checks, live, that your battery has both the discharge rate and enough spare charge to supply the appliance for the whole of that window right now — running it then draws the battery down instead of the grid, and that gap gets refilled by the very energy the forecast expects to spill. No battery configured (or its sensors not readable) simply means this trigger never fires — there's no buffer to safely bet on.

Optional guardrails: Greedy Respects Schedule confines greedy to the appliance's own allowed run times. And a manual override always wins — greedy is suppressed entirely while you have a load forced On or Off.

Setting up the export-surplus trigger

The export surplus trigger needs a live signed grid power sensor — positive when importing, negative when exporting — configured as grid_power_sensor under Grid Lens → Configure. Without it that one trigger simply never fires; the other two still work.

By default the two live triggers only count export as wasted when the feed-in price is zero. Set a Minimum Export Price (on the dashboard, in cents/kWh) to raise that bar — e.g. at 5c, a load set to run greedily will soak up surplus any time you'd otherwise be exporting below 5c. The same figure also drives Forecast surplus: if the plan shows a whole afternoon of, say, 3c export, a greedy load with Forecast surplus enabled will start now, off the battery, rather than wait for that spill. Leave it at 0 to keep the strict "only when feed-in is zero" behaviour on all three triggers.

Setting up the forecast-surplus trigger

The forecast surplus trigger needs your battery SOC sensor, a live signed battery charge/discharge power sensor — positive when charging, negative when discharging — and your battery capacity (kWh), the same battery details Grid Lens already uses to plan your battery. The capacity figure backs the check that your battery can absorb the trigger's full draw before it starts refilling, not just supply it for an instant. Without all three configured and readable, this trigger simply never fires; the other two still work.

If you have already set up the Power Flow card, you have told Grid Lens this entity once and it is filled in for you — the card's grid_power_entity is the same reading with the same sign convention, so the setup form offers it back rather than asking twice. Otherwise the field starts blank: the other energy sensors come from your Home Assistant Energy dashboard, but that dashboard only records cumulative energy and has no live power reading to borrow.

If it is blank and Greedy Consumption is on, the Power Flow page's device panel (or the Deferrable Loads card) says so — the appliance's greedy line reads “export is being wasted, but no grid power sensor is set” rather than pretending it is still waiting for surplus.

Note this is a power (W) sensor, not one of the cumulative kWh sensors from your Energy dashboard.

Grid Lens keeps a running Greedy Consumption energy sensor per appliance, tracked from the moment you enable it (there's no way to know retroactively what ran opportunistically before that). It's what powers the Plan Comparison page's Exclude Greedy Consumption checkbox — see View the dashboard.

Seeing why it acted

Anything that acts on your house should be able to explain itself. Every automated decision Grid Lens makes is visible on the dashboard:

  • Power Flow page's device panel (or the Deferrable Loads card) — per appliance: whether Grid Lens is controlling it, which greedy trigger is currently holding it on, or why greedy is blocked. When the forecast-surplus trigger is armed, a progress bar shows how close it is to firing.
  • Power Flow card — a badge appears on an appliance while greedy, rather than the plan, is the reason it's running. Hover it for the numbers behind the decision. Each appliance node also has a small hide button (bottom-left corner) if you'd rather it not clutter the diagram — hiding it also drops that device's line from the "Power — measured & forecast" chart and its bar from the Plan Comparison breakdown, but it's still just a display choice: schedule, controls, optimisation and every dollar figure for that device keep working as normal. Turn it back on from that appliance's own "Show In Power Flow" switch under Settings.
  • Power Chart card — free-energy shading. Orange marks periods where the plan expects to spill energy it can't sell; teal marks free import windows. Diagonal stripes on a device's own line mark stretches it was actually running because of Greedy Consumption rather than the plan. Hover a band for the detail. A deferrable load with its own battery also gets a dashed predicted SOC line on the right-hand 0–100% axis, in that device's colour; if its charge ceiling is cutting the plan short, a faint flat line marks the ceiling and the hover tooltip names how much charge was held back.
  • Price Chart card — alongside your plan's buy and sell rates, each half-hour's money: what it cost rises from the bottom of the chart, what your feed-in earned hangs from the top, both on the same scale so you can see at a glance whether the selling covered the buying. Tick marks on the right-hand edge give you the scale without cluttering the chart with dollar figures — hover any half-hour for the exact cost, credit and kWh. The legend totals the day so far. Bars for time that has already passed are solid and come from your metered import and export priced on your own plan — not a projection; bars to the right of "now" are faint, because those are still the optimiser's plan for the rest of the day.
  • Entity attributes — every Grid Lens switch exposes its full decision state for use in your own automations and templates.

API key

The free plan requires no API key — Grid Lens registers your installation automatically and grants access to model your current plan.

A Pro subscription ($1/month) gives you an API key that unlocks all available plans. Enter it under Grid Lens → Configure → API key & connection.

If you remove and re-add the integration, setup will tell you the installation is already registered and ask for your existing key. We only store a hashed copy, so we can't show it to you again — keep it somewhere safe, or email support@gridlens.au from your registered address for a replacement.

Troubleshooting

Integration not appearing after install

Ensure you fully restarted Home Assistant (not just reloaded). Custom integrations require a full restart to register.

Sensor not found during setup

Make sure your energy sensors appear in the Energy dashboard first. Grid Lens reads from the same sensor list.

Optimiser returns no results

Grid Lens needs at least 24 hours of sensor history to run the LP optimiser. If you've just set it up, check back the following day.

Enable debug logging

Add to your configuration.yaml:

logger:
  logs:
    custom_components.grid_lens: debug

Then check Settings → System → Logs for grid_lens entries.

Still stuck? Email support@gridlens.au.