New list options pv_forecast_entities and pv_forecast_tomorrow_entities
(same shape as pv_entities); the single-entity keys are unchanged.
- Each member is read in its own unit (Wh/kWh/MWh) in one gather and the
day is summed. Hourly splits are merged when every member has one, else
the total goes on the bell.
- A member missing, unavailable, stale, non-energy or bad makes that
day's forecast unusable (no partial sum). A caution row names it by
position; the action log names the entity once per change.
- Single key and list both set for one day: refused at start.
- A one-member list behaves exactly like the single key (test_opt17.py);
the single-key path is byte-identical to e36565f over 24 scenarios.
- Supervisor shape measured: tools/supervisor_shape_probe.py section J.
DECISIONS/OPT-17-several-forecast-entities.md has the rules.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
322 lines
20 KiB
YAML
322 lines
20 KiB
YAML
# Home Assistant add-on translations - ENGLISH (UX-01)
|
|
#
|
|
# ⚠️ WHAT THIS FILE IS FOR, AND WHAT HOME ASSISTANT ACTUALLY DOES WITH IT.
|
|
# Without a `translations/` directory the Configuration tab renders the raw
|
|
# option KEYS - `unit_sign_disagree_w`, `saturation_cycles`, `integrator_max_w`.
|
|
# The frontend keeps a field when `e.name in options || e.required`, and all 72
|
|
# keys are in `options:` (59 of them are `required` as well), so ALL SEVENTY-TWO are
|
|
# rendered, always, in `schema:` order, with no description. This file is what
|
|
# turns that into sentences.
|
|
#
|
|
# HOW IT IS READ, measured on the Supervisor image this site runs
|
|
# (ghcr.io/home-assistant/amd64-hassio-supervisor:2026.08.0):
|
|
#
|
|
# * `supervisor/store/data.py:_read_app_translations()` reads every
|
|
# `.yaml`/`.yml`/`.json` in this directory, keyed by FILE STEM (so this file
|
|
# is the `en` translation), and validates each through
|
|
# `SCHEMA_APP_TRANSLATIONS`: `configuration: {str: {name (required),
|
|
# description, fields}}` plus `network: {str: str}`. ⚠️ A FILE THAT FAILS
|
|
# THAT SCHEMA IS DROPPED WITH A LOG WARNING AND NOTHING ELSE - the add-on
|
|
# goes on rendering raw keys and nobody is told twice. tools/
|
|
# supervisor_shape_probe.py section F is what says it loaded.
|
|
# * The frontend resolves each label as
|
|
# `translations[<user's language>]?...name || translations["en"]?...name ||
|
|
# schema.name`, and the helper text the same way with `description`. ⚠️ THE
|
|
# FALLBACK IS PER KEY, so a key missing from nl.yaml degrades to this file,
|
|
# while a key present but wrong does not degrade at all.
|
|
#
|
|
# ⚠️ ORDER IS NOT SET HERE. `App.schema_ui` is `UiOptions(...)(data["schema"])`,
|
|
# so the Configuration tab renders in the order of config.yaml's `schema:`
|
|
# block. The order below only mirrors it so the two files read alike.
|
|
#
|
|
# ⚠️ ADD-ON OPTIONS ARE A FLAT LIST. There is no section-header primitive, no
|
|
# per-option "advanced" flag, no units on the input and no sliders, so grouping
|
|
# is approximated by ORDER plus the `Group · ` prefix in each label. Do not
|
|
# promise the operator visual sections; there are none.
|
|
#
|
|
# Names and descriptions follow STYLE.md (UX-08): a short label with its unit,
|
|
# and one or two plain sentences. A measured or derived value says "leave it
|
|
# unchanged", and where it came from is in DOCS.md under "For installers:
|
|
# where the numbers come from".
|
|
configuration:
|
|
setpoint_entity:
|
|
name: "Hardware · Inverter setpoint entity"
|
|
description: "The ESPHome number entity the add-on writes the inverter's power to. Leave it empty when you fill in the inverter list."
|
|
soc_entity:
|
|
name: "Hardware · Battery level entity (%)"
|
|
description: "The sensor with the battery level in percent. Use the control board's own reading."
|
|
batt_entity:
|
|
name: "Hardware · Battery power entity (W)"
|
|
description: "The sensor with this inverter's battery power. Positive must mean the battery is giving power."
|
|
batt_invert:
|
|
name: "Hardware · Battery power sign is reversed"
|
|
description: "Switch this on only if your battery power sensor shows giving power as a negative number."
|
|
inverters:
|
|
name: "Hardware · Inverter list"
|
|
description: "Leave it empty if you have one inverter. With two or more, add one entry per inverter, which replaces the inverter settings above."
|
|
fields:
|
|
name:
|
|
name: "Name"
|
|
description: "A short, unique name for this inverter, for example inverter-a."
|
|
setpoint_entity:
|
|
name: "Setpoint entity"
|
|
description: "This inverter's own ESPHome setpoint entity. Two entries may not use the same one."
|
|
max_w:
|
|
name: "Inverter rating (W)"
|
|
description: "The most power the add-on may ask of this inverter. The site total is the sum of the list."
|
|
bms_soc_floor:
|
|
name: "Battery cut-out level (%)"
|
|
description: "The level at which this battery's own management system stops giving power. Read it off the battery that is installed."
|
|
soc_entity:
|
|
name: "Battery level entity (%) (optional)"
|
|
description: "This battery's own level sensor. Leave it empty if this inverter has none."
|
|
batt_entity:
|
|
name: "Battery power entity (W) (optional)"
|
|
description: "This inverter's own battery power sensor. Leave it empty if it has none."
|
|
batt_invert:
|
|
name: "Battery power sign is reversed (optional)"
|
|
description: "Switch this on if this inverter's sensor shows giving power as a negative number."
|
|
capacity_kwh:
|
|
name: "Usable battery capacity (kWh) (optional)"
|
|
description: "This battery's usable capacity from its datasheet. Fill it in on every inverter or on none. The add-on then shares the work by the energy each battery has left."
|
|
estop_fitted:
|
|
name: "Hardware · RS485 emergency stop is fitted"
|
|
description: "Switch this on if the emergency stop is installed. It only changes a warning on the status page."
|
|
battery_modes_enabled:
|
|
name: "Hardware · Battery modes"
|
|
description: "Give each battery an on and off switch and a mode, set on the Batteries screen."
|
|
pv_forecast_entity:
|
|
name: "Hardware · Solar forecast, today (kWh)"
|
|
description: "Optional. A forecast sensor with today's remaining solar energy, such as Forecast.Solar or Solcast. A battery then buys only what the sun will not give."
|
|
pv_forecast_tomorrow_entity:
|
|
name: "Hardware · Solar forecast, tomorrow (kWh)"
|
|
description: "Optional. The same forecast for tomorrow. It helps plan a cheap hour before midnight."
|
|
pv_forecast_entities:
|
|
name: "Hardware · Several solar forecasts, today (kWh)"
|
|
description: "Optional. One row per forecast sensor, such as one per inverter, used instead of the single one above. They are added up."
|
|
pv_forecast_tomorrow_entities:
|
|
name: "Hardware · Several solar forecasts, tomorrow (kWh)"
|
|
description: "Optional. The same list for tomorrow. If one sensor has no reading, that day's forecast is not used."
|
|
solar_trust_pct:
|
|
name: "Hardware · Trust in the forecast (%)"
|
|
description: "Forecasts are often too sunny. At 70 % the add-on plans with 7 of every 10 kWh forecast."
|
|
pv_entity:
|
|
name: "Hardware · Solar production entity (W)"
|
|
description: "Optional. Your solar inverter's power sensor, positive while producing. The add-on records it and does not use it for control."
|
|
pv_entities:
|
|
name: "Hardware · Solar production entities, per inverter (W)"
|
|
description: "Optional. Use one row per solar inverter instead of “Solar production entity” when you have several. If one stops reporting, no total is recorded."
|
|
pv_invert_entities:
|
|
name: "Hardware · Reversed-sign solar entities"
|
|
description: "Optional. Add each solar entity above that reads negative while producing, spelled the same way. Its sign is flipped before adding up."
|
|
meter_source:
|
|
name: "Meter · Where the meter reading comes from"
|
|
description: "How the add-on reads your meter. 'off' uses “Grid power entity” below, and only homewizard_local can spot a stuck meter."
|
|
meter_entity:
|
|
name: "Meter · Grid power entity (W)"
|
|
description: "Used when the meter source is 'off'. Positive must mean drawing from the grid."
|
|
meter_invert:
|
|
name: "Meter · Grid power sign is reversed"
|
|
description: "Switch this on if your grid sensor shows drawing from the grid as a negative number."
|
|
meter_phases:
|
|
name: "Meter · Number of phases (1 or 3)"
|
|
description: "Must match your grid connection. Meter readings with a different number of phases are rejected."
|
|
p1_host:
|
|
name: "Meter · HomeWizard P1 address"
|
|
description: "For homewizard_local only. The meter's address on your network, as host or host:port."
|
|
meter_poll_s:
|
|
name: "Meter · Time between meter reads (s)"
|
|
description: "For homewizard_local only. The meter updates every 5 s, so lower gains nothing. Keep it well below “Reading too old after”."
|
|
meter_max_age_s:
|
|
name: "Meter · Reading too old after (s)"
|
|
description: "After this a meter reading counts as missing. The “Missing inputs time limit” starts only after this one runs out."
|
|
meter_mqtt_topic:
|
|
name: "Meter · MQTT topic"
|
|
description: "For mqtt_p1 only. The topic your meter readings are published on."
|
|
p1_import_entity:
|
|
name: "Meter · Grid import entity (W)"
|
|
description: "The sensor for power drawn from the grid, never negative. The add-on works out the net value itself."
|
|
p1_export_entity:
|
|
name: "Meter · Grid export entity (W)"
|
|
description: "The sensor for power fed into the grid, never negative. It pairs with “Grid import entity”."
|
|
p1_net_entity:
|
|
name: "Meter · Signed net power entity (W)"
|
|
description: "For ha_signed only. One sensor that is positive when drawing from the grid and negative when feeding in."
|
|
p1_phase_import_entities:
|
|
name: "Meter · Import entities per phase (L1-L3)"
|
|
description: "Optional, in L1, L2, L3 order. Needed for the peak limit on a three-phase connection, one entry per phase."
|
|
p1_phase_export_entities:
|
|
name: "Meter · Export entities per phase (L1-L3)"
|
|
description: "Optional, in L1, L2, L3 order, next to the import entities per phase. One entry per phase."
|
|
p1_phase_net_entities:
|
|
name: "Meter · Net entities per phase (L1-L3)"
|
|
description: "For ha_signed only. Optional, in L1, L2, L3 order, signed like “Signed net power entity”, one entry per phase."
|
|
max_w:
|
|
name: "Limits · Inverter rating (W)"
|
|
description: "Your own number: the most power the add-on may ever ask of the inverter. Start low and raise it after commissioning."
|
|
bms_soc_floor:
|
|
name: "Limits · Battery cut-out level (%)"
|
|
description: "The level where the battery's own management system stops giving power. Read it off your battery rather than copying a figure."
|
|
peak_cap_w:
|
|
name: "Limits · Peak limit (W)"
|
|
description: "Your own number: the 15-minute average power the add-on keeps the grid under. Take it from your grid contract."
|
|
peak_margin_w:
|
|
name: "Limits · Margin below the peak limit (W)"
|
|
description: "The add-on aims this much below the peak limit, so a 15-minute period that ends a little high still stays under it."
|
|
peak_forecast_entity:
|
|
name: "Limits · 15-minute demand forecast entity (W)"
|
|
description: "Optional. A forecast of this 15-minute period's average power. Leave it empty and there is no peak limit."
|
|
peak_soc_floor:
|
|
name: "Limits · Peak reserve (%)"
|
|
description: "Peak limiting will not draw the battery below this level, but ordinary use can. Derived value, leave it unchanged."
|
|
price_provider:
|
|
name: "Tariff · Dynamic price source"
|
|
description: "Where prices come from. Choosing a source starts the price fetch, even with trading off."
|
|
price_markup_eur_kwh:
|
|
name: "Tariff · Supplier markup (EUR/kWh)"
|
|
description: "Your supplier's margin. It is added only when the price source does not already include it."
|
|
price_taxes_eur_kwh:
|
|
name: "Tariff · Distribution, levies and VAT (EUR/kWh)"
|
|
description: "Grid costs, levies and VAT per kWh, preset for Flanders. Check it against your own grid operator's rates."
|
|
export_price_eur_kwh:
|
|
name: "Tariff · Injection price (EUR/kWh)"
|
|
description: "What you are paid per kWh fed into the grid, all in. It may be negative."
|
|
static_profile:
|
|
name: "Tariff · Fixed or day/night tariff"
|
|
description: "Your fixed or day/night contract on one line, prices all in, as the documentation shows. Fill it in even on a dynamic contract, as the fallback."
|
|
price_taxes_profile:
|
|
name: "Tariff · Day/night levies and VAT"
|
|
description: "Leave it empty unless your grid operator charges a different day and night rate, as in Wallonia and Brussels. Set this or the flat figure above, not both."
|
|
price_formula:
|
|
name: "Tariff · Your own tariff formula"
|
|
description: "For custom_formula only. Type the numbers from your supplier's tariff card on one line, as the documentation shows. The add-on checks them against the card."
|
|
price_export_formula:
|
|
name: "Tariff · Your own injection formula"
|
|
description: "Optional. The injection formula from your tariff card, in the same shape as your own tariff formula. Leave it empty to use the flat injection price."
|
|
price_csv_path:
|
|
name: "Tariff · Price CSV file"
|
|
description: "For manual_csv only. Where in /share the add-on reads your price file."
|
|
price_feed_url:
|
|
name: "Tariff · Price feed URL override"
|
|
description: "Leave it empty to use the source's own feed. An override is sent exactly as typed and often returns only one day."
|
|
price_horizon_h:
|
|
name: "Tariff · Price look-ahead (hours)"
|
|
description: "How many hours of prices to ask the source for."
|
|
price_timeout_s:
|
|
name: "Tariff · Price request timeout (s)"
|
|
description: "How long one request to the price source may take before it is given up."
|
|
price_now_entity:
|
|
name: "Tariff · Current price entity (older)"
|
|
description: "The older way to get a price, used only to charge in a cheap window during maintenance. Do not combine it with a dynamic price source."
|
|
price_avg_entity:
|
|
name: "Tariff · Average price entity (older)"
|
|
description: "The average the current price is compared with. Use it only with the current price entity, not with a dynamic price source."
|
|
arbitrage_enabled:
|
|
name: "Tariff · Trade on the price spread"
|
|
description: "Charge in the cheapest hour and draw the battery down in the dearest, when the spread covers the cost. Turning it off does not turn the price feed off."
|
|
cycle_cost_threshold_eur:
|
|
name: "Tariff · Battery cycle cost (EUR/kWh)"
|
|
description: "What one full battery cycle costs per kWh. A smaller price spread is not traded, and the value is a product choice, not a measured one."
|
|
arbitrage_soc_floor:
|
|
name: "Tariff · Trading keeps at least (%)"
|
|
description: "Price trading will not draw the battery below this level. It is separate from the maintenance settings."
|
|
arbitrage_soc_ceiling:
|
|
name: "Tariff · Trading charges at most (%)"
|
|
description: "Price trading will not charge the battery above this level."
|
|
maintenance_enabled:
|
|
name: "Maintenance · Run the monthly battery cycle"
|
|
description: "Once a month, empty the battery deeply, charge it full and hold it there, so its level reading stays accurate. Off by default."
|
|
maintenance_interval_days:
|
|
name: "Maintenance · Minimum days between cycles"
|
|
description: "The shortest gap between two maintenance cycles."
|
|
maintenance_start_hour:
|
|
name: "Maintenance · Start hour (local time)"
|
|
description: "The hour on your local clock, 0 to 23, when a due cycle starts. 19 means 19:00."
|
|
maintenance_discharge_w:
|
|
name: "Maintenance · Draw-down rate (W)"
|
|
description: "How fast the cycle empties the battery. Above “Inverter rating” it is cut back to the rating, and the cycle just takes longer."
|
|
maintenance_charge_w:
|
|
name: "Maintenance · Recharge rate (W)"
|
|
description: "How fast the cycle recharges the battery. It must be at or below “Inverter rating”, or the add-on will not start."
|
|
maintenance_soc_floor:
|
|
name: "Maintenance · Draw down to (%)"
|
|
description: "The level the monthly cycle empties the battery to. It is not the “Peak reserve”, and the two differ on purpose."
|
|
maintenance_soc_target:
|
|
name: "Maintenance · Recharge up to (%)"
|
|
description: "The level the recharge aims for before the hold starts."
|
|
maintenance_hold_min:
|
|
name: "Maintenance · Hold at full for (minutes)"
|
|
description: "How long the battery stays full so its cells can balance."
|
|
sign_disagree_w:
|
|
name: "Safety · Wrong-direction threshold (W)"
|
|
description: "Part of the safety stop for an inverter pushing the wrong way. It counts only when command and meter reading both exceed this. Measured value, leave it unchanged."
|
|
sign_disagree_s:
|
|
name: "Safety · Wrong-direction time (s)"
|
|
description: "How long a wrong direction may last before a safety stop sets every inverter to 0 W. Measured value, leave it unchanged."
|
|
unit_sign_disagree_w:
|
|
name: "Safety · Per-inverter wrong-direction threshold (W)"
|
|
description: "For two or more inverters: the wrong-direction threshold for each inverter. Derived value, leave it unchanged."
|
|
unit_sign_disagree_s:
|
|
name: "Safety · Per-inverter wrong-direction time (s)"
|
|
description: "For two or more inverters: how long one inverter may push the wrong way before it is set to 0 W. Derived value, leave it unchanged."
|
|
site_sign_disagree_w:
|
|
name: "Safety · Site wrong-direction threshold (W)"
|
|
description: "For two or more inverters: the wrong-direction threshold for the whole site. Measured value, leave it unchanged."
|
|
site_sign_disagree_s:
|
|
name: "Safety · Site wrong-direction time (s)"
|
|
description: "For two or more inverters: how long the whole site may push the wrong way before a safety stop. Derived value, leave it unchanged."
|
|
meter_freeze_s:
|
|
name: "Safety · Stuck meter alarm after (s)"
|
|
description: "An alarm when the meter repeats one reading this long while the command is at full power, with homewizard_local only. Measured value, leave it unchanged."
|
|
circulation_w:
|
|
name: "Safety · Opposing inverters threshold (W)"
|
|
description: "For two or more inverters: how much power one may push against another before it counts. Measured value, leave it unchanged."
|
|
circulation_hold_s:
|
|
name: "Safety · Opposing inverters time (s)"
|
|
description: "For two or more inverters: how long they may push against each other before a safety stop. Derived value, leave it unchanged."
|
|
delivery_hold_s:
|
|
name: "Safety · Not delivering alarm after (s)"
|
|
description: "For two or more inverters: how long one may fall short of its share before an alarm, which changes nothing. Derived value, leave it unchanged."
|
|
shadow_mode:
|
|
name: "Safety · Shadow mode"
|
|
description: "The add-on makes every decision but keeps every inverter at 0 W. 'auto' does this while control is stopped, 'on' always, 'off' never."
|
|
auto_start:
|
|
name: "Advanced · Start control on boot"
|
|
description: "Off by default. Leave it off until the site is commissioned, so someone presses Start after each restart."
|
|
gain:
|
|
name: "Advanced · Control gain"
|
|
description: "How much of the remaining error control corrects each cycle. Measured on real hardware, do not raise it."
|
|
slew_w:
|
|
name: "Advanced · Largest change per cycle (W)"
|
|
description: "How far the command may move in one cycle. 0 follows “Inverter rating” and is recommended."
|
|
deadband_w:
|
|
name: "Advanced · Ignore errors below (W)"
|
|
description: "Errors smaller than this are ignored. Keep it small, since any resting point inside it holds."
|
|
target_grid_w:
|
|
name: "Advanced · Meter resting point (W)"
|
|
description: "What the meter should show when nothing happens. A slight export avoids paying for tiny imports all day."
|
|
step_w:
|
|
name: "Advanced · Command rounding (W)"
|
|
description: "The command is rounded to a multiple of this, so noise does not change it every cycle."
|
|
saturation_w:
|
|
name: "Advanced · At-limit shortfall (W)"
|
|
description: "When an inverter delivers this much less than asked, it counts as at its limit. The per-inverter wrong-direction threshold is half of this."
|
|
saturation_cycles:
|
|
name: "Advanced · Cycles at limit before freezing"
|
|
description: "How many cycles in a row at the limit before control stops building up error. Do not set it to 1."
|
|
integrator_max_w:
|
|
name: "Advanced · Catch-up limit (W)"
|
|
description: "Limits how hard control keeps pushing while the battery falls behind. 0 means “Inverter rating”. Do not raise it above the rating."
|
|
heartbeat_s:
|
|
name: "Advanced · Command refresh interval (s)"
|
|
description: "How often the command is sent again even when unchanged. Keep it well under the control board's own 30 s limit."
|
|
stale_input_s:
|
|
name: "Advanced · Missing inputs time limit (s)"
|
|
description: "How long inputs may be missing before every inverter is set to 0 W. With a P1 meter it starts after “Reading too old after”."
|
|
cycle_floor_s:
|
|
name: "Advanced · Longest time between cycles (s)"
|
|
description: "A deadline between control cycles that a healthy meter never reaches. Raise it only for a meter slower than about 10 s."
|
|
log_level:
|
|
name: "Advanced · Log level"
|
|
description: "How much detail the add-on writes to its log. 'debug' and 'trace' are for finding a problem."
|