UX-08 2c review: unit settings anchor to inverters, plainer texts
- messages.setting() for one inverter in the list reads “Inverter rating” for inverter-b (inverters.max_w), so the config panel files per-unit reasons under `inverters`, where the value is changed. - The tariff card and plausibility reasons name “Distribution, levies and VAT” (price_taxes_eur_kwh) again. - The wrong-direction reasons say "safety stop", the sign_disagree_w option says what it protects, and the roster, price-entity, integrator_max_w and capacity_kwh texts read more plainly. - NL: stuurprint -> stuurmodule, "De piekbeperking". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -292,7 +292,8 @@ _LEGS = {
|
||||
neg_factor="Put the minus sign on the offset, not on the factor",
|
||||
card_required=True,
|
||||
card_note="The add-on needs it to check your two numbers",
|
||||
card_causes="that network charges are not in the offset",
|
||||
card_causes=("that network charges are in “Distribution, levies and VAT” "
|
||||
"(price_taxes_eur_kwh), not in the offset"),
|
||||
),
|
||||
EXPORT_FORMULA_OPTION: _Leg(
|
||||
option=EXPORT_FORMULA_OPTION,
|
||||
@@ -678,10 +679,8 @@ def parse_export_formula(value):
|
||||
def card_refusal(spec: FormulaSpec, delta: float) -> str:
|
||||
"""The sentence an operator reads when their formula misses its own card.
|
||||
|
||||
⚠️ IT NAMES THE DISCREPANCY AND THE SIX WAYS IT HAPPENS. "Invalid
|
||||
configuration" would be true and useless: every one of these errors looks
|
||||
exactly like a working tariff from the status page, which is why the check
|
||||
exists at all.
|
||||
It names both numbers and what to check. The usual causes are in DOCS.md,
|
||||
because each of these errors looks like a working tariff on the status page.
|
||||
"""
|
||||
got = in_card_units(spec, spec.card_index_eur_per_mwh)
|
||||
leg = _LEGS[spec.option]
|
||||
@@ -744,9 +743,9 @@ def implausible_all_in(spec: FormulaSpec, taxes_eur_kwh: float):
|
||||
return None
|
||||
return (
|
||||
f"{spec.option} gives {energy:.5f} EUR/kWh for energy and "
|
||||
f"{all_in:.5f} EUR/kWh in total on its own card, outside the "
|
||||
f"plausible band of {PLAUSIBLE_LO_EUR_KWH}-{PLAUSIBLE_HI_EUR_KWH} "
|
||||
f"EUR/kWh. Check \"units\" against the unit beside your formula.")
|
||||
f"{all_in:.5f} EUR/kWh with “Distribution, levies and VAT” "
|
||||
f"(price_taxes_eur_kwh), outside the plausible band of "
|
||||
f"{PLAUSIBLE_LO_EUR_KWH}-{PLAUSIBLE_HI_EUR_KWH} EUR/kWh. Check \"units\" against the unit beside your formula.")
|
||||
|
||||
|
||||
def implausible_injection(spec: FormulaSpec):
|
||||
|
||||
@@ -844,5 +844,9 @@ LABELS = {
|
||||
|
||||
|
||||
def setting(key: str, unit: str = "") -> str:
|
||||
"""`max_w` -> `“Inverter rating” (max_w)`, plus ` for inverter-b` in a list."""
|
||||
return f"“{LABELS[key]}” ({key})" + (f" for {unit}" if unit else "")
|
||||
"""`max_w` -> `“Inverter rating” (max_w)`. For one inverter in a list it is
|
||||
`“Inverter rating” for inverter-b (inverters.max_w)`, so the config panel
|
||||
also shows the reason beside `inverters`, where that value is changed."""
|
||||
if unit:
|
||||
return f"“{LABELS[key]}” for {unit} (inverters.{key})"
|
||||
return f"“{LABELS[key]}” ({key})"
|
||||
|
||||
@@ -703,8 +703,8 @@ def _roster_problems(opts: dict) -> list[str]:
|
||||
if entries and flat_sp:
|
||||
problems.append(
|
||||
f"{S('setpoint_entity')} is set to {flat_sp}, but the "
|
||||
f"{S('inverters')} has {len(entries)} entries. Move that inverter "
|
||||
"into the list and clear this setting.")
|
||||
f"{S('inverters')} is also filled in. Move that inverter into the "
|
||||
"list and clear this setting.")
|
||||
return problems
|
||||
|
||||
|
||||
@@ -924,8 +924,8 @@ def validate_startup_config(opts: dict, dev_min=None, dev_max=None) -> list[str]
|
||||
where = _unit_label(opts, min(caps_ix, key=lambda p: p[1])[0])
|
||||
problems.append(
|
||||
f"{S('sign_disagree_w')} is {sign_w:.0f} W, but the "
|
||||
f"{S('max_w', where)} is {weakest:.0f} W, so this check can never "
|
||||
f"trip. Lower it below {weakest:.0f} W, or raise the rating.")
|
||||
f"{S('max_w', where)} is {weakest:.0f} W, so this safety stop can "
|
||||
f"never trip. Lower it below {weakest:.0f} W, or raise the rating.")
|
||||
|
||||
# ⚠️ AND THE SAME RULE FOR SAFETY-30's PER-UNIT THRESHOLD, WHICH IS A
|
||||
# SEPARATE COMPARISON AND THEREFORE A SEPARATE WAY TO DISARM. It grades a
|
||||
@@ -978,8 +978,8 @@ def validate_startup_config(opts: dict, dev_min=None, dev_max=None) -> list[str]
|
||||
elif weakest is not None and weakest > 0 and unit_sign_w >= weakest:
|
||||
problems.append(
|
||||
f"{S('unit_sign_disagree_w')} is {unit_sign_w:.0f} W, but the "
|
||||
f"{S('max_w', unit_where)} is {weakest:.0f} W, so this check can "
|
||||
f"never trip. Lower it below {weakest:.0f} W, or raise the "
|
||||
f"{S('max_w', unit_where)} is {weakest:.0f} W, so this safety stop "
|
||||
f"can never trip. Lower it below {weakest:.0f} W, or raise the "
|
||||
"rating.")
|
||||
|
||||
# --- 6. a maintenance charge the ceiling can actually accommodate --------
|
||||
@@ -1301,9 +1301,8 @@ def _price_problems(opts: dict) -> list[str]:
|
||||
# day/night tariff has no way to see that it lost.
|
||||
if ha_price and str(opts.get("static_profile", "") or "").strip():
|
||||
problems.append(
|
||||
f"{S('static_profile')} and {_labels(ha_price)} are both set, and "
|
||||
"only the Home Assistant price entities would count. Clear one of "
|
||||
"the two.")
|
||||
f"{S('static_profile')} is set, but {_labels(ha_price)} would win "
|
||||
"over it. Clear the one you do not use.")
|
||||
|
||||
# ⚠️ THE PROFILE ITSELF, PARSED AT STARTUP RATHER THAN AT 02:00. A profile
|
||||
# that does not tile the day has hours with no price, and the only ways to
|
||||
|
||||
Reference in New Issue
Block a user