Skip to content

Zaptec Go 2: stop retrying phase switching while APM is active - #33255

Draft
nvie wants to merge 4 commits into
evcc-io:masterfrom
nvie:zaptec-apm-no-retry
Draft

Zaptec Go 2: stop retrying phase switching while APM is active#33255
nvie wants to merge 4 commits into
evcc-io:masterfrom
nvie:zaptec-apm-no-retry

Conversation

@nvie

@nvie nvie commented Aug 28, 2026

Copy link
Copy Markdown

This PR stops evcc from retrying a phase switch that the Zaptec API has already told us can never succeed. Fixes #33253, and supersedes #33254.

This means instead of trying to keep making requests to api.zaptec.com and flooding the logs every 30 seconds, this now shows up like this, once — only the first time it happens:

screenshot of logs

After that, retrying this will no longer be attempted (until after a restart), so it will no longer be hammering api.zaptec.com every 30 seconds.

By the way, a HTTP 527 looked like the generic "installation update rejected" code, which could be returned for more things than just APM-related errors, so only a rejection whose error message mentions "APM" is treated as permanent — anything else is passed on and still retried exactly as before.

github-actions Bot and others added 2 commits August 28, 2026 08:50
When an installation uses Zaptec's Adaptive Power Management, phase
switching via installationUpdate() permanently fails with HTTP 500 /
Code 527 ("Cannot update installation when using APM"). Map this to
api.ErrNotAvailable so the loadpoint treats it as a permanent
condition instead of retrying every control cycle.

@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 reviewed your changes and they look great!

Sourcery assessment

Approved.


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.

@github-actions github-actions Bot added bug Something isn't working devices Specific device support labels Aug 28, 2026
@andig

andig commented Aug 29, 2026

Copy link
Copy Markdown
Member

I'd like to keep the errors. If user doesn't see the message when it happens he may not see it at all once its rotated out of the log buffer. This maybe annoying, but so is the charger in the first place.

@andig andig removed the bug Something isn't working label Aug 29, 2026
@andig

andig commented Aug 29, 2026

Copy link
Copy Markdown
Member

If user doesn't see the error in the first place he'll wonder why phase switching doesn't happen...

@andig

andig commented Aug 30, 2026

Copy link
Copy Markdown
Member

In other words: if the condition exists when starting we should not decorate phase switching. Once it occurs I‘d prefer raising the error for clarity. Does that make sense?

@andig
andig marked this pull request as draft August 30, 2026 07:41
@nvie

nvie commented Aug 30, 2026

Copy link
Copy Markdown
Author

Controlled phase switching will never be possible when you use a Zaptec Go 2 with load balancing (via Zaptec Sense P1), that’s how I understand it.

The current implementation however keeps fighting for control to perform a phase switch anyway every 30 seconds and getting this error message. But that is futile: it leads to many errors and noisy logs. (I personally think noisy logs are dangerous because users start to ignore logs and also miss other errors more easily.)

But fundamentally, I think it’s about making evcc understand that phase switching isnt allowed for this configuration of the Zaptec, so it won’t be attempted in the first place.

So whether phase switching is allowed could maybe be modeled as a capability on the charger configuration in evcc itself that a user either configures themselves or that evcc detects upon setup?

This PR kind of did this auto-detection on-demand but maybe it was too magical to detect this from a known error message. It was the easiest shot for me in an unfamiliar code base.

Maybe modeling it as a capability on a charger is clearer for the end user. Once evcc knows phase switching isnt allowed, it should no longer attempt it and there would be no error at all, not even the first attempt?

If you like that approach better, I’m happy to update the PR to go in that direction.

@andig

andig commented Aug 30, 2026

Copy link
Copy Markdown
Member

So all that needs be done is identify APM on startup?

@nvie

nvie commented Aug 30, 2026

Copy link
Copy Markdown
Author

Yes I think so. I just don’t know if it’s possible to cleanly detect it without a side effect (like actually switching phases). I don’t know if an API for it exists.

Maybe a toggle the user configures is the simplest approach?

@andig

andig commented Aug 30, 2026

Copy link
Copy Markdown
Member

Typically thats bool phases1p3p that users can choose to enable. That's a breaking change then...

@nvie

nvie commented Aug 30, 2026

Copy link
Copy Markdown
Author

Ideally it's only a breaking change for Zaptec users with APM, but since it didn't work anyway I don't think it's really a breaking change.

Happy to see if I can dig in a bit this afternoon and see if I can come up with something knowing all this.

nvie added 2 commits August 30, 2026 11:46
Previously, APM being active was only discovered when an installation
update was attempted and rejected with a 527 error, requiring runtime
state (`apmActive`) to suppress further attempts. This meant the phase
switcher was advertised even though it could never succeed.

Now `EnabledFeatures` is read from the installation at init time, and if
the APM feature bit is set the phase switcher is simply not registered
at all. The runtime guard and the error-response parsing are no longer
needed.
@nvie

nvie commented Aug 30, 2026

Copy link
Copy Markdown
Author

@andig Updated the PR to detect it at startup instead.

Turns out Zaptec's OpenAPI spec has a feature bitmask on the installation, and 4 = PowerManagement_Apm (see enabledFeatures / schema Features in https://api.zaptec.com/swagger/v1/swagger.json). On my installation enabledFeatures is indeed exactly 4, so APM is detectable up front without probing or matching on error strings. If the bit is set we don't decorate PhaseSwitcher at all, and there's a single WARN at startup saying why. The 527 handling has been removed. If it ever does occur at runtime it's raised as an error, as you asked.

Some things I'm genuinely unsure about, I don't know this codebase well:

  • Is this the shape you had in mind, or did you want the detection to live somewhere more central?
  • I gated on c.version != zaptec.ZaptecGo1_Pro rather than == zaptec.ZaptecGo2, so a future Zaptec Go generation won't run into the same problem again.
  • Affected users lose the "auto-switching" option in the UI with no explanation there; only the startup WARN says why. I tried showing the reason in the UI, but it seemed a lot harder to wire up and wanted to check with you first if it was really needed.
  • Backward compatibility: existing APM users with phasesConfigured: 0 will fall back to 3p at startup (core/loadpoint.go:292), which I think is fine? The stored 0 isn't overwritten, so it returns to automatic if APM is ever disabled and evcc restarted. Looks good to you?

Worth noting for anyone reading later: the charger still switches phases by itself under APM (it drops to 1p when available current on a phase falls below the installation's switch threshold). evcc just follows the measured phases now instead of trying to actively control it itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

devices Specific device support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Zaptec Go 2: should phase switching return api.ErrNotAvailable when installation uses APM?

2 participants