Skip to content

Config UI: allow disabling devices#29455

Open
andig wants to merge 12 commits intomasterfrom
feat/disable
Open

Config UI: allow disabling devices#29455
andig wants to merge 12 commits intomasterfrom
feat/disable

Conversation

@andig
Copy link
Copy Markdown
Member

@andig andig commented Apr 27, 2026

Fix #21144, refs #14496

TODO

Out of scope

  • refactor read/write device payload (see todo comment in code)

Video

disable.webm

Screenshots

disable button in device modal
disable btn

confirm
confirm disable

disabled device in overview
disabled card

enable notice
confirm enable

@andig andig added enhancement New feature or request prio Priority labels Apr 27, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In configureLoadpoints, when conf.Disable is true the instance remains nil but is still wrapped in NewConfigurableDevice; consider ensuring all consumers guard against a nil loadpoint.API or creating a small disabled stub implementation to avoid potential nil dereferences.
  • In configurableInstance, the disabled path leaves instance as the zero value of T without returning an error; consider making the disabled behavior explicit (e.g., early return or a dedicated disabled state) so callers don’t have to implicitly rely on a zero-value instance.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `configureLoadpoints`, when `conf.Disable` is true the `instance` remains `nil` but is still wrapped in `NewConfigurableDevice`; consider ensuring all consumers guard against a nil `loadpoint.API` or creating a small disabled stub implementation to avoid potential nil dereferences.
- In `configurableInstance`, the disabled path leaves `instance` as the zero value of `T` without returning an error; consider making the disabled behavior explicit (e.g., early return or a dedicated disabled state) so callers don’t have to implicitly rely on a zero-value instance.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread core/site.go Outdated
Comment thread core/site.go Outdated
@naltatis
Copy link
Copy Markdown
Member

@marq24 this PR might not be sufficient for exposing this functionality via HA yet. Its part of our internal/undocumented /api/config/* endpoints and requires a full device read to change the value (GET > PUT) with a payload transformation (see todo above). We'll add api keys with #29431 and do a refactoring of the payload structure after this PR has landed. Then I'd consider it stable enough to expose and document this API for external use.

@naltatis
Copy link
Copy Markdown
Member

@andig UI works. Only did shallow functional testing (disabling a pv meter, ...) and ran into startup errors and situations where I got stuck (not even fatal mode). I'll suggest you try this. I'll add structured e2e tests later to cover all use-cases.

@marq24
Copy link
Copy Markdown
Contributor

marq24 commented Apr 28, 2026

@marq24 this PR might not be sufficient for exposing this functionality via HA yet. Its part of our internal/undocumented /api/config/* endpoints and requires a full device read...

So just to check, if I understood this correctly - even when there will be documented, the functionality will have it's home in the api/config context - which requires authorization (credentials)...

Then HA users must use REST-API Integration in order to manipulate this [since the current HA integration only use API endpoints that are accessible without credentials] - so this new feature will then not be directly available in HA then [I just will create an appropriate documentation like this one here: https://github.com/marq24/ha-evcc#accessing-your-vehicle-soc--range-when-the-vehicle-is-not-connected-to-a-loadpoint

@naltatis
Copy link
Copy Markdown
Member

Yes, disable flag will be part of device configuration and requires a restart after change. Both endpoints need authentication.

@andig
Copy link
Copy Markdown
Member Author

andig commented Apr 29, 2026

@naltatis loadpoints can't be disabled yet?

@andig
Copy link
Copy Markdown
Member Author

andig commented Apr 29, 2026

Und: das UI scheint bei noch alle /status abzufragen:

Request failed with status code 400.
instance db:10 not initialized.
GET http://localhost:7070/api/config/devices/meter/db:10/status

@andig
Copy link
Copy Markdown
Member Author

andig commented Apr 29, 2026

Just broke it (again), but not sure why this breaks. Maybe we need to do the meter nil checks later- but why?

@naltatis
Copy link
Copy Markdown
Member

but not sure why this breaks.

mixed up error handling. should be fixed now.

@naltatis
Copy link
Copy Markdown
Member

naltatis commented Apr 29, 2026

loadpoints can't be disabled yet?

I'm unsure if we should put the disable logic in loadpoint at all or maybe leave it at device level (charger, optional meter) and just let lp initialization check if it has a functioning/non-disabled charger.

Benefit: this is exactly what we have to do for handling broken devices on startup anyways.

Drawback: user has to click one level deeper to the charger. If important it could easily be solved UI-only (show disable button on loadpoint which actually changes the associated charger disable state).

Since loadpoint-charger is a 1:1 relationship I'd suggest to not implement both and use the charger as the source of truth here.

@andig
Copy link
Copy Markdown
Member Author

andig commented Apr 29, 2026

I'd prefer loadpoint- otherwise we'd need backend logic to silently deactivate the loadpoint because its charger no longer exists. If LP is deactivated, charger and lp meter can remain active but won't be used.

@marq24
Copy link
Copy Markdown
Contributor

marq24 commented Apr 29, 2026

allow me to add my opinion here (my 'train of though' coming from the wish to 'temporary disable the ability of evcc to control my charger', since I want/must pass over the control to the Tibber backend, so that I can receive Grid rewards).

@naltatis when LP and a charger device have a 1:1 relation in evcc, then disable the charger will also disable the loadpoint - right? (I assume a LP without an functional/operational charger has then also no functionality). From my personal enduser-experince I don't make any logical difference between a loadpoint (and the charger behind it)... To my best knowledge as a user I don't see 'charger devices' anywhere - I just see the corresponding loadpoint in the UI.

So when you place the toggle at device level, you need to remind every single user "Yes, you want to disable the loadpoint- but technically you must disable the charger device". I understand that a LP object has different attributes/methods then a charger-device [but I doubt, that the common user will mind this difference]

@andig
Copy link
Copy Markdown
Member Author

andig commented Apr 29, 2026

Plus: LP is the top level object as far as ui is concerned! Would need to think about what happens with broken meters/chargers for disabled loadpoints- they would still be initialized and consume startup time but ultimately not leads to an error. May be acceptable.

@naltatis
Copy link
Copy Markdown
Member

If LP is deactivated, charger and lp meter can remain active but won't be used.

What do you mean with this? If I'm using a mobile charger (NRGKick use case) and disable a loadpoint, I'd expect that evcc does not try to initialize the charger and eventually fail.

@naltatis
Copy link
Copy Markdown
Member

naltatis commented Apr 29, 2026

Plus: LP is the top level object as far as ui is concerned!

That's only half true. The values you see in the loadpoint card are the sum of charger and meter status. Loadpoint does not have a status.

@andig
Copy link
Copy Markdown
Member Author

andig commented Apr 29, 2026

That's only half true.

Sure- but it is from editing perspective. The loadpoint card is what you open.

I'd expect that evcc does not try to initialize the charger

See above: they would still be initialized and consume startup time

and eventually fail.

See above: but ultimately not leads to an error

@andig
Copy link
Copy Markdown
Member Author

andig commented Apr 30, 2026

See above: they would still be initialized and consume startup time

We could also- when loadpoint gets disabled- have backend logic that disables associated objects, i.e. charger and potential charge meter?

Wdyt?

@naltatis
Copy link
Copy Markdown
Member

I've added disable persistence logic to the loadpoint endpoints. This is not pretty but gets the job (load/save) done.
UI is adjusted to show Enable/Disable controls in loadpoint modal and disable state in lp card. The actual server-side logic is incomplete. Disabled LPs will disappear after restart and throw due to missing nil checks. @andig can you look at this?

We could also- when loadpoint gets disabled- have backend logic that disables associated objects, i.e. charger and potential charge meter?

Yes we should. Currently these lead to fatal startup errors - independent if the device is referenced or not.

@andig
Copy link
Copy Markdown
Member Author

andig commented May 7, 2026

@copilot resolve the merge conflicts in this pull request

Co-authored-by: andig <184815+andig@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented May 7, 2026

@copilot resolve the merge conflicts in this pull request

Resolved and pushed in 14a0dfe. I merged origin/master into this branch and resolved the conflicts in cmd/setup.go and i18n/en.json + i18n/de.json so the PR now merges cleanly. No UI changes were made in this conflict-resolution commit.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 224.0.0.251
    • Triggering command: REDACTED, pid is -1 (packet block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot finished work on behalf of andig May 7, 2026 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request prio Priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Config UI: Geräte deaktivieren

4 participants