Skip to content

Config UI: allow disabling devices - #29455

Merged
naltatis merged 27 commits into
masterfrom
feat/disable
Aug 11, 2026
Merged

Config UI: allow disabling devices#29455
naltatis merged 27 commits into
masterfrom
feat/disable

Conversation

@andig

@andig andig commented Apr 27, 2026

Copy link
Copy Markdown
Member

Fix #21144, refs #14496

TODO

  • fix init loop to not use nil devices @andig
  • ui @naltatis
  • disable loadpoints @naltatis
  • fix status lookup @naltatis
  • do tariffs
  • test mobile @naltatis
  • add e2e tests @naltatis
  • fix issues when starting with a disabled loadpoint @andig
  • disable subdevices (meter, charger) on loadpoint disable @andig
  • allow boot (non fatal) with a disabled loadpoint and broken sub-devices @andig
  • fix boot with disabled grid meter @andig
  • fix editing disabled loadpoint @andig @naltatis

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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

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

marq24 commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

@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

andig commented Apr 29, 2026

Copy link
Copy Markdown
Member Author

@naltatis loadpoints can't be disabled yet?

@andig

andig commented Apr 29, 2026

Copy link
Copy Markdown
Member Author

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

andig commented Apr 29, 2026

Copy link
Copy Markdown
Member Author

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

naltatis commented Apr 29, 2026

Copy link
Copy Markdown
Member

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

andig commented Apr 29, 2026

Copy link
Copy Markdown
Member Author

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

marq24 commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

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

andig commented Apr 29, 2026

Copy link
Copy Markdown
Member Author

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

naltatis commented Apr 29, 2026

Copy link
Copy Markdown
Member

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.

@naltatis

Copy link
Copy Markdown
Member

27f33b4 addresses the remaining boot and subdevice items:

  • disabling a loadpoint also persists the disable flag on its charger and meter (set at API time, mirrors delete behavior)
  • boot skips disabled devices, so broken subdevices of a disabled loadpoint no longer prevent startup
  • disabled loadpoints keep their slot in state.loadpoints (disabled: true) and their /api/loadpoints/{n} index, lp3 stays 3 when lp2 is disabled
  • main UI hides disabled loadpoints, UI settings show them with a "disabled" badge instead of the show/hide toggle
  • new e2e tests: broken charger boots after disabling its loadpoint, api index stability

# Conflicts:
#	core/site.go
@naltatis

Copy link
Copy Markdown
Member

Disabled loadpoints are published in minimal form, but not shown in UI. Only in display settings as disabled.

Bildschirmfoto 2026-07-13 um 17 43 26 Bildschirmfoto 2026-07-13 um 17 45 19

@naltatis

Copy link
Copy Markdown
Member

@andig added a lot of e2e tests and fixed remaining bug. All subtasks fixed.

@github-actions github-actions Bot added the stale Outdated and ready to close label Jul 21, 2026
@andig andig removed the stale Outdated and ready to close label Jul 23, 2026
@github-actions github-actions Bot added the stale Outdated and ready to close label Jul 30, 2026
@naltatis naltatis removed the stale Outdated and ready to close label Jul 30, 2026
@naltatis

Copy link
Copy Markdown
Member

ping @andig

@github-actions github-actions Bot added the stale Outdated and ready to close label Aug 6, 2026
@andig andig added backlog Things to do later and removed enhancement New feature or request stale Outdated and ready to close labels Aug 9, 2026
@naltatis
naltatis enabled auto-merge (squash) August 11, 2026 13:22
@naltatis
naltatis merged commit 4465100 into master Aug 11, 2026
12 checks passed
@naltatis
naltatis deleted the feat/disable branch August 11, 2026 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backlog Things to do later prio Priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Config UI: Geräte deaktivieren

5 participants