Automatically route your PV surplus to household devices.
Zero YAML. Battery-aware. Forecast-smart. Price-aware.
AURUM (Latin: Gold) turns your solar surplus into gold: it automatically distributes excess PV power to household devices — priority-based, battery-aware, and fully configurable through the Home Assistant UI.
No coding required. Install via HACS, add your grid sensor, configure devices through the UI — done.
Live dashboard with battery gauge, device states, runtimes, and diagnostics
| Feature | Description |
|---|---|
| Built-in Dashboard | A self-adapting AURUM sidebar panel ships with the integration — no YAML, no extra cards. Add or remove a device and it updates automatically |
| PV Surplus Steering | Turns devices on/off based on available excess power |
| Battery Priority | Optional: only genuine grid export counts as surplus, so the battery charges first |
| Battery-Aware | Respects battery SOC with configurable target and minimum thresholds |
| Run Conditions | Optional per-device prerequisite (a sensor below/above a limit — e.g. water heater only while the tank is below 55 °C) |
| PV Power Gate | Optional per-device threshold: run on raw PV generation above a limit (with healthy SOC), bypassing the budget cap |
| Daily Reset Hour | Per-device reset hour for runtime counters — align a cheap-grid device to the solar day |
| Priority-Based | Higher priority devices get power first |
| Startup Detection | Detects washing machine / dishwasher program start, pauses until PV surplus is available, resumes automatically |
| PV Forecast Budget | Uses Solcast or Open-Meteo forecast to limit device runtime so the battery reliably reaches target SOC |
| Price-Aware Scheduling | Devices can run on cheap grid power (Tibber, Nordpool, aWATTar, EPEX Spot) — even without PV surplus |
| Per-Device SOC Threshold | Each device can have its own minimum battery level |
| Energy Tracking | Per-device kWh/day tracking, compatible with HA Energy Dashboard |
| Push Notifications | Optional mobile push when devices are turned on/off |
| Manual Override & Must-run-today | Auto-created switches per device for manual control and deadline forcing |
| Hysteresis & Debounce | Prevents rapid switching with configurable margins |
| State Persistence | Device runtimes, energy counters and budget safety factor survive restarts |
| HA Diagnostics | Download a full JSON snapshot for bug reports |
| No Vendor Lock-In | Works with any grid meter, any battery, any smart plug, any price sensor |
- Home Assistant 2024.1.0+
- A grid power sensor (W, signed: positive = import, negative = export) — e.g. Shelly 3EM, Kostal, SMA, Fronius
- Smart switches for your devices — e.g. Shelly Plug, Tasmota, Zigbee plugs
- Optional: Battery SOC sensor, PV power sensor, Solcast or Open-Meteo forecast
- Open HACS in Home Assistant
- Search for AURUM and click Download
- Restart Home Assistant
Until HACS PR #6653 is merged, AURUM isn't in the HACS default store yet. As a fallback: HACS → ⋮ → Custom repositories → add
https://github.com/cm-makes/aurum-haas Integration, then continue with step 2.
- Copy
custom_components/aurum/to yourconfig/custom_components/directory - Restart Home Assistant
- Go to Settings > Integrations > Add Integration > AURUM
- Energy & Battery: Select your grid power sensor (and optionally PV, battery SOC, battery charge/discharge power, PV forecast)
- Battery settings: Set capacity, target SOC, minimum SOC, and update interval
- After setup: Go to AURUM > Configure to add devices
Setup wizard — connect your energy sensors in two steps
In the integration options (Configure), click Add a device and fill in:
| Setting | Description |
|---|---|
| Name | Display name (e.g. "Washing Machine") |
| Switch entity | The switch that controls the device |
| Power sensor | Optional: Real-time power measurement |
| Nominal power | Expected power draw in watts |
| Priority | 1–100, higher = turned on first |
| SOC threshold | Device only runs when battery is above this level |
| Startup detection | Enable for appliances with programs (washers, dishwashers). AURUM keeps the plug on in standby, detects when you press Start, pauses immediately, and resumes when PV surplus is sufficient. If a deadline is set and PV never arrives, AURUM starts on grid power as a fallback. |
| Interruptible | If disabled, AURUM will not turn the device off mid-cycle |
| Deadline | Time by which the device must have run (e.g. 18:00) |
| Estimated runtime | Expected runtime in minutes (used for deadline scheduling) |
| Run condition sensor | Optional prerequisite: a sensor that must be below / above a limit for the device to run (e.g. water heater only while sensor.boiler_temp is below 55). Blocks all start paths; an unavailable sensor fails open. |
| Daily reset hour | Hour (0–23) when this device's runtime counter resets. 0 = midnight (default). Set to 9 so a cheap-grid device runs on solar first during the day and only tops up its runtime from cheap grid overnight. |
| PV power threshold | Optional: run whenever actual PV generation is ≥ this many watts and battery SOC ≥ the device's SOC threshold, bypassing the daily budget cap. Expresses "run whenever PV ≥ 1000 W and battery ≥ 25 %" — useful when the surplus/budget logic reserves solar for the battery and a device (e.g. a pool pump) wouldn't otherwise start. Requires a PV power sensor. 0 = disabled (default). Also available as a live number.aurum_{slug}_pv_power_threshold entity and a dashboard control. |
Battery priority (in Configure → Energy & Battery) is a global toggle: when enabled, only genuine grid export counts as surplus for devices, so the battery charges first. Off (default) keeps the previous behaviour where battery-charging power may be diverted to devices.
Device configuration — all settings via UI, no YAML needed
AURUM can limit device runtimes based on how much PV energy is forecast for the rest of the day, so the battery reliably reaches its target SOC.
In Configure > Energy & Battery:
| Field | What to enter |
|---|---|
pv_forecast_entity |
Sensor with remaining forecast for today in kWh (e.g. Solcast "Prognose verbleibende Leistung heute") |
pv_forecast_today_entity |
Sensor with hourly forecast data as attribute (e.g. Solcast "Forecast Today" with forecast attribute) |
If your forecast entity only provides a daily total without hourly data, AURUM uses a fallback sunset estimate (19:00) for budget calculations.
AURUM can run devices on cheap grid power — even without PV surplus. Works with any electricity price sensor (Tibber, Nordpool, aWATTar, EPEX Spot, etc.).
Step 1: Connect price sensors
In Configure > Energy & Battery, set one or more of these:
| Field | What to enter | Example |
|---|---|---|
price_entity |
Current electricity price in ct/kWh | sensor.tibber_aktueller_strompreis |
price_level_entity |
Price level enum (very_cheap/cheap/normal/expensive/very_expensive) | sensor.tibber_aktuelles_preisniveau |
cheap_period_entity |
Binary sensor ON during cheap periods | binary_sensor.tibber_bestpreis_zeitraum |
cheap_period_starts_in_entity |
Minutes until next cheap period (for dashboard countdown) | sensor.tibber_bestpreis_startet_in |
All fields are optional. You only need one price source — AURUM checks them in order: max_price threshold → cheap period → price level.
Step 2: Configure devices
Edit a device and set:
| Setting | Description |
|---|---|
| Price mode | Solar only (default) or Solar + cheap grid |
| Maximum price | Grid power only below this price (ct/kWh). Set to 0 to use price level / cheap period instead. |
How it works:
A device with cheap_grid mode turns on when any of these is true:
- PV surplus is sufficient (normal solar logic)
max_priceis set and current price ≤ thresholdcheap_period_entityis ON (best price window active)price_level_entityisvery_cheaporcheap
Debounce timers still apply to prevent flapping on price edges.
Works with:
- Tibber Prices — provides best price periods, countdown, price levels
- Nordpool — price sensor + price level
- aWATTar — hourly price data
- EPEX Spot — day-ahead prices
- Any sensor providing ct/kWh or price levels
Running on a 10 kWp system with 5 kWh battery, managing IR heaters, a washing machine, and a dishwasher — with typical spring sun, AURUM achieves near-100% self-consumption and minimal grid import during daylight hours. On cheap-tariff nights (Tibber), the heaters pre-heat rooms using low-cost grid power.
Every 15 seconds:
1. Read grid power -> calculate excess (negative grid = export = surplus)
2. Check battery SOC -> determine mode (normal / low_soc / charging)
3. Optional: Calculate PV budget from forecast
4. Optional: Read electricity price -> determine if cheap period active
5. For each device (by priority):
- Cheap grid mode + price OK? -> Turn ON (even without surplus)
- Enough surplus + SOC OK + budget available? -> Turn ON
- Surplus gone or SOC low? -> Turn OFF (respecting min-on-time)
6. Startup Detection: If a washing machine starts -> protect the cycle
7. Track energy (Wh) and runtime per device
| Mode | Condition | Effect |
|---|---|---|
| normal | SOC >= target | All devices allowed |
| low_soc | min < SOC < target | Devices run if surplus is sufficient; per-device SOC thresholds apply |
| charging | SOC <= min | All devices off (battery protection) |
| Situation | AURUM behavior |
|---|---|
| Override switch ON | AURUM ignores the device completely — no turn-on, no turn-off |
| Device physically on, override switch OFF | AURUM applies normal turn-off logic (e.g. battery protection) |
| AURUM turned the device on | Full management — turns off when surplus drops |
| Entity | Type | Description |
|---|---|---|
sensor.aurum_excess_power |
Sensor | Available surplus (W) |
sensor.aurum_grid_power |
Sensor | Grid power (W, positive = import) |
sensor.aurum_pv_power |
Sensor | PV production (W) |
sensor.aurum_house_consumption |
Sensor | House consumption (W) |
sensor.aurum_battery_soc |
Sensor | Battery SOC (%) |
sensor.aurum_battery_mode |
Sensor | Current mode (normal/low_soc/charging) |
sensor.aurum_battery_charge |
Sensor | Battery charge power (W) |
sensor.aurum_battery_discharge |
Sensor | Battery discharge power (W) |
sensor.aurum_electricity_price |
Sensor | Current electricity price (ct/kWh) with price_level, cheap_period, cheap_period_starts_in_min attributes |
sensor.aurum_forecast_remaining |
Sensor | PV forecast remaining today (kWh) |
sensor.aurum_budget |
Sensor | Device power budget (W) |
sensor.aurum_safety_factor |
Sensor | Budget safety factor (%) |
sensor.aurum_energy_today |
Sensor | Total energy all devices today (Wh) |
sensor.aurum_current_decision |
Sensor | What AURUM is doing right now, and why — see The Advisor |
sensor.aurum_cycle |
Sensor | Update cycle counter (diagnostic) |
number.aurum_target_soc |
Number | Target SOC slider |
number.aurum_min_soc |
Number | Minimum SOC slider |
| Entity | Type | Description |
|---|---|---|
sensor.aurum_{slug} |
Sensor | Device state (on/off/manual_override/running/standby/waiting/done). For cheap_grid devices: includes scheduling_reason, cheap_period, starts_in attributes |
sensor.aurum_{slug}_power |
Sensor | Current power draw (W) |
sensor.aurum_{slug}_runtime |
Sensor | Runtime today (min) |
sensor.aurum_{slug}_energy_today |
Sensor | Energy consumed today (Wh, TOTAL_INCREASING — HA Energy Dashboard compatible) |
binary_sensor.aurum_{slug}_active |
Binary | Is device active? |
number.aurum_{slug}_soc_threshold |
Number | SOC threshold slider |
switch.aurum_{slug}_override |
Switch | Manual override (AURUM hands off) |
switch.aurum_{slug}_muss_heute |
Switch | Force device on today |
switch.aurum_{slug}_disable |
Switch | Force-off: removes the device from control and keeps it off |
{slug}is the device name lowercased with spaces replaced by underscores (e.g. "Washing Machine" ->washing_machine).
AURUM ships with its own dashboard panel — nothing to install or configure. After setup, an AURUM entry (☀️) appears in the Home Assistant sidebar. It renders live from AURUM's own entities and adapts automatically: add or remove a device in the options and its card appears or disappears.
It shows a decision banner up top (what AURUM is doing right now — see The Advisor), overview chips (PV, grid import/export, battery SOC, surplus, budget, house consumption, remaining forecast, cheap-grid flag) and one card per device with a PV | Manual | Off mode selector, a Must-run-today toggle, a translated reason line ("→ solar surplus", "→ waiting for program start"), and the SOC-threshold, max-price, PV-power-threshold and deadline controls. It follows your HA theme and is localized (English by default, German when the HA UI is set to German).
The sidebar entry is sorted alphabetically — if your sidebar is long, scroll down or pin it to the top via Profile → Edit sidebar.
Optional (legacy): a manual Mushroom-based dashboard is still available as example_dashboard.yaml for users who prefer a Lovelace dashboard (requires Mushroom Cards via HACS).
sensor.aurum_current_decision answers the most common question about any
automatic optimizer: "Why is AURUM (not) running my device right now?"
Zero configuration — it's always active.
| Code | Meaning |
|---|---|
running_solar |
At least one device is running on PV surplus |
running_cheap_grid |
Running because electricity is cheap |
running |
Running for another reason (manual override, deadline) |
waiting |
Devices configured, none running — waiting for surplus |
battery_charging |
Battery below your min_soc reserve — devices paused |
startup |
Sensor warm-up after a restart (~90 s) |
idle |
No devices configured |
The devices attribute lists every device with a machine-readable reason:
| Reason | Meaning |
|---|---|
solar_surplus |
Running on PV surplus |
solar_pv |
Running via the raw-PV gate (pv_power_threshold) |
cheap_grid |
Running on cheap grid power |
manual_override |
You took over — AURUM hands off |
forced_deadline |
Deadline start (must finish today) |
runtime_done / program_done |
Done for today |
program_standby |
Waiting for you to start a program (washer/dishwasher) |
program_paused |
Program paused, waiting for surplus to resume |
battery_charging |
Battery below reserve |
below_soc_threshold |
Battery below this device's SOC threshold |
condition_not_met |
Run condition blocks it (e.g. boiler already hot) |
disabled |
Force-off switch is on |
waiting_surplus |
Not enough surplus right now |
Reason codes in attributes are untranslated by design (HA only translates entity states). The AURUM panel shows them translated; in your own cards you see the codes.
type: markdown
content: >
## {{ states('sensor.aurum_current_decision') }}
{% for d in state_attr('sensor.aurum_current_decision', 'devices') %}
- **{{ d.name }}**: {{ d.state }} → {{ d.reason }}
{% endfor %}# Push notification when the battery drops below reserve
trigger:
- platform: state
entity_id: sensor.aurum_current_decision
to: battery_charging
# Condition: has the washing machine finished its program today?
condition: >
{{ state_attr('sensor.aurum_current_decision', 'devices')
| selectattr('slug', 'eq', 'washing_machine')
| map(attribute='reason') | first == 'program_done' }}The attributes deliberately contain no fast-changing numbers (no watts, no timestamps), so the sensor produces clean state history and won't bloat your recorder database. Live power values live in the dedicated numeric sensors.
Download a full JSON snapshot of AURUM's internal state for troubleshooting:
Settings > Devices & Services > AURUM > Download Diagnostics
The file contains: energy values, battery state, budget info, device states, override switch states, and coordinator health.
- Price-aware scheduling (Tibber, Nordpool, aWATTar, EPEX Spot)
- Per-device energy tracking (kWh/day)
- Push notifications (mobile app)
- Built-in dashboard panel (auto-adapting AURUM sidebar view)
- Battery-priority surplus mode
- Per-device run conditions (sensor prerequisite)
- Per-device daily reset hour
- Cost tracking (import/export/autarky per device)
- Multi-battery support
If AURUM saves you energy and money, consider supporting its development:
Your support helps keep this project alive and growing.
Most setup issues fall into one of these patterns. Before opening an issue, check whether your symptom matches.
Grid sign convention is wrong. AURUM expects: positive grid power = drawing from grid, negative = feeding in. Many inverters report this the other way around (or only positive values).
Quick test: with PV producing more than house consumption, your grid sensor should read negative. If it's positive while you're exporting, create a Template sensor that flips the sign:
template:
- sensor:
- name: "Grid Power Signed"
unit_of_measurement: "W"
device_class: power
state_class: measurement
state: "{{ -1 * states('sensor.your_grid_sensor') | float(0) }}"Then point AURUM at sensor.grid_power_signed.
Two possible causes:
- Battery SOC sensor below
min_soc— checksensor.aurum_battery_socvs. the Battery reserve slider. If SOC is reported as e.g.42but you expected42%, you're fine. If it's0.42, your sensor reports a fraction — AURUM's config flow now catches this at setup, but old configs won't be re-validated. Replace with a Template sensor that multiplies by 100. - No battery configured, but
min_soc> 0 — without a battery SOC sensor, AURUM treats SOC as 0 and goes straight into charging mode. Leave the battery SOC empty and setmin_socto 0.
You probably have a battery but didn't configure Battery charge power and Battery discharge power. Without these, AURUM can't tell how much PV power is "hidden" in battery charging, so it underestimates the real surplus available for devices. Both sensors live in your inverter/BMS integration (Solax, SMA, Fronius, Kostal usually expose them).
Open the device entity and check:
- Priority — lower-priority devices wait while higher-priority ones get power first
- SOC threshold — device won't run if battery is below this level (during
low_socmode) - Hysteresis ON — AURUM needs
nominal_power + hysteresis_onof surplus before turning on, to avoid flapping - Debounce ON — surplus must stay sufficient for this many seconds before AURUM commits
For diagnostic detail, look at the device entity's scheduling_reason attribute.
Increase hysteresis_off (tolerate larger surplus dips before turning off) and debounce_off (let the device ride through short clouds). Defaults are 100W / 600s — for shaded sites, try 200W / 900s.
Download diagnostics (Settings → Devices & Services → AURUM → ⋮ → Download diagnostics) and open an issue with that file attached. It contains every value the maintainer needs to debug.
Got a question, an idea, or want to show off your setup? Use GitHub Discussions — it's the fastest way to get help and talk to other users.
| Ask a question | Setup help, configuration, troubleshooting |
| Share an idea | Feature ideas — discuss before opening a formal request |
| Show and tell | Dashboards, setups, energy results |
| Report a bug | Something broken? Open an issue |
Contributions are welcome! See CONTRIBUTING.md for guidelines.
MIT License — see LICENSE
See CHANGELOG.md for version history.
