Manage Energy Dashboard Preferences
ha_manage_energy_prefsRead, update, or add energy sources, device consumption entries, and cost tariffs for the Home Assistant Energy Dashboard.
Instructions
Manage the Home Assistant Energy Dashboard preferences.
The Energy Dashboard configuration (grid/solar/battery/gas/water energy
sources, individual device consumption sensors for electricity and
water, cost tariffs) is stored in .storage/energy and not otherwise
reachable via REST, services, or helper flows — this tool is the only
way for agents to inspect or modify it.
WHEN TO USE:
mode='get' / 'set': inspect or replace the full Energy Dashboard config. Use 'set' for bulk edits or anything touching multiple top-level keys at once.
mode='add_device' / 'remove_device': add or remove a single device-consumption entry. The tool performs a fresh read-modify-write internally; the caller does NOT manage config_hash. Use
water=Trueto target the water meter list instead of electricity.mode='add_source': append a single entry to
energy_sources(grid, solar, battery, gas, or water). Same atomic read-modify-write semantics.
WHEN NOT TO USE:
To create the underlying statistics themselves — they must already exist as HA entities before being referenced here; create them via the relevant integration's config flow first.
CAVEATS:
energy/save_prefshas per-key FULL-REPLACE semantics. Passing{"device_consumption": [<one entry>]}deletes every other device the user had configured — silently, with no error. mode='set' requires a freshconfig_hashfor optimistic locking; convenience modes hide this entirely.config_hashaccepts both a singlestr(full-blob lock) and adict[_PrefsKey, str]keyed by top-level keys (per-key lock, taken from theconfig_hash_per_keyfield of the mode='get' response). The per-key form lets an agent submit only the top- level key it wants to change — set-equality betweenconfigkeys and dict keys is enforced, and any key outside the canonical set (typo, etc.) on either side is rejected withVALIDATION_FAILEDrather than silently dropped (so an empty submission cannot succeed as a no-op). A per-key submission still fully replaces that key's value as the save endpoint requires. Mismatch on any locked key returnsRESOURCE_LOCKEDwith the offending keys in the response's top-levelmismatched_keys(create_error_responseflattens thecontextdict onto the response root).dry_run=Trueskips the hash check entirely for both forms; the per-key form is therefore silently accepted on dry runs even if its keys would mismatch the current state.A local shape check runs before every write; malformed payloads are rejected with a
shape_errorslist.After a successful write, the tool calls
energy/validateand returns any residual issues aspost_save_validation_errorsin the response. These reflect semantic problems (missing stats, unit mismatches) that shape checks can't catch; the save persists regardless — correct the config and write again if needed.The underlying save endpoint is admin-only. Non-admin tokens will receive an authorization error from Home Assistant.
Convenience modes are NOT idempotent: 'add_device' on an existing
stat_consumptionreturns RESOURCE_ALREADY_EXISTS; 'remove_device' on a missing entry returns RESOURCE_NOT_FOUND. 'add_source' rejects duplicates by(type, stat_energy_from)for solar/battery/gas/water (RESOURCE_ALREADY_EXISTS); grid entries are appended without a duplicate check (multiple grid variants are legitimate, and grid has no single canonical uniqueness key) — the caller is responsible for de-duplicating grid sources.Convenience modes do NOT bypass the local shape check on dry_run:
dry_run=Truestill raisesRESOURCE_ALREADY_EXISTS(duplicate add_device / add_source),RESOURCE_NOT_FOUND(missing remove_device), orVALIDATION_FAILED(post-mutator shape error) when the proposed mutation is not applicable. The mutator and shape check both run before the dry-run short-circuit.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | Operation mode. Primitives: 'get' reads the current prefs; 'set' writes a full prefs payload (per-top-level-key full-replace). Convenience modes: 'add_device' / 'remove_device' / 'add_source' perform a single read-modify-write atomically — no config_hash from the caller, the tool fetches it fresh internally. | |
| name | No | Optional display name for mode='add_device'. Only used when adding a new device entry; ignored otherwise. | |
| water | No | If True, mode='add_device' / 'remove_device' targets 'device_consumption_water' instead of 'device_consumption'. Default False. | |
| config | No | Full prefs payload for mode='set'. Must contain the top-level keys you intend to replace: 'energy_sources', 'device_consumption', 'device_consumption_water'. Any top-level key present in this payload REPLACES the existing list entirely; any omitted key is preserved. Call with mode='get' first, mutate the returned config, then pass the whole object back. Ignored by convenience modes. | |
| source | No | Single energy_sources entry for mode='add_source'. Must contain 'type' (one of grid|solar|battery|gas|water) and the type-specific required fields (e.g. solar/battery/gas/water require 'stat_energy_from'). Every source type also accepts an optional 'name' (display label in the energy graphs); battery additionally accepts 'stat_soc' (state-of-charge statistic). Note: HA Core's voluptuous schema for grid sources requires the full field set (cost_adjustment_day, stat_energy_to, stat_cost, entity_energy_price, number_energy_price, entity_energy_price_export, number_energy_price_export, stat_compensation) — the local shape check is narrower, so a minimal {'type': 'grid'} passes locally but surfaces in post_save_validation_errors after writing. Pass the unused fields as None to satisfy the server. Required for mode='add_source'; ignored otherwise. | |
| dry_run | No | If True, no write is performed. For mode='set': runs a local shape check on the proposed config AND calls the server's energy/validate against the CURRENT persisted state (Home Assistant's validate endpoint cannot validate an unsubmitted payload). For convenience modes: simulates the mutation against a fresh read and reports what would change without writing — but still raises RESOURCE_ALREADY_EXISTS (duplicate add_device, or duplicate add_source for solar/battery/gas/water), RESOURCE_NOT_FOUND (missing remove_device), or VALIDATION_FAILED (post-mutator shape error) when the proposed mutation is not applicable. Default False. | |
| config_hash | No | Hash from a previous mode='get' call. REQUIRED for mode='set' unless dry_run=True. Two forms: str (full-blob lock) or dict (per-key lock, taken from the config_hash_per_key field of mode='get'). Pass the dict form as a native object, NOT a JSON-encoded string — a stringified dict is treated as a full-blob token and will report RESOURCE_LOCKED; clients that can only send strings should use the str full-blob form. See the tool docstring for fail-closed semantics. Ignored by convenience modes. | |
| included_in_stat | No | Optional 'parent' statistic for mode='add_device'. Set this to a statistic that already INCLUDES this device's consumption (e.g., a whole-home or circuit-level meter that this device feeds into). The Energy Dashboard will subtract this device's reading from the parent so the parent's contribution is not double-counted. Ignored otherwise. | |
| stat_consumption | No | Statistic entity_id for mode='add_device' / 'remove_device' (e.g. 'sensor.fridge_energy'). Required for those modes; ignored otherwise. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||