Skip to content

Huawei SUN2000: add curtail#28549

Merged
andig merged 16 commits into
evcc-io:masterfrom
CiNcH83:huawei_curtailment
May 19, 2026
Merged

Huawei SUN2000: add curtail#28549
andig merged 16 commits into
evcc-io:masterfrom
CiNcH83:huawei_curtailment

Conversation

@CiNcH83
Copy link
Copy Markdown
Contributor

@CiNcH83 CiNcH83 commented Mar 25, 2026

a.k.a. zero feed-in / § 9 EEG

Huawei API

Active power control register definition

Testing

image (curtailed to 30% of the maximum inverter power)

Open Questions

  • Why not pass through the limited power value received from the FNN controlbox and write it to register 47416 (Maximum Feed Grid Power (kW))?

TODOs

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 curtailMeter.Curtailed, you return val < m.nominalLimit even when curtailedG returns an error; consider short‑circuiting and returning false, err on error to avoid exposing a potentially misleading curtailed state when the underlying read failed.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `curtailMeter.Curtailed`, you return `val < m.nominalLimit` even when `curtailedG` returns an error; consider short‑circuiting and returning `false, err` on error to avoid exposing a potentially misleading curtailed state when the underlying read failed.

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.

@CiNcH83 CiNcH83 marked this pull request as draft March 25, 2026 15:16
@github-actions github-actions Bot added the stale Outdated and ready to close label Apr 7, 2026
@github-actions github-actions Bot closed this Apr 12, 2026
@TW2A
Copy link
Copy Markdown

TW2A commented Apr 13, 2026

Any updates on this?

@CiNcH83
Copy link
Copy Markdown
Contributor Author

CiNcH83 commented Apr 15, 2026

Currently on hold until the topic receives more love...

@andig
Copy link
Copy Markdown
Member

andig commented May 2, 2026

Never saw this PR. Whats missing?

@andig andig reopened this May 2, 2026
@andig andig added devices Specific device support and removed stale Outdated and ready to close labels May 2, 2026
@andig
Copy link
Copy Markdown
Member

andig commented May 2, 2026

Ah I see. ATM we only have static curtailment limit, i.e. curtail to 0. There are no urgent plans to change this.

@premultiply do we need to change that?

@CiNcH83
Copy link
Copy Markdown
Contributor Author

CiNcH83 commented May 2, 2026

See initial posting. Curtailment via templating hasn‘t yet been merged.

@andig
Copy link
Copy Markdown
Member

andig commented May 2, 2026

Yeah- that's because that PR is not scoped.

@github-actions github-actions Bot added the stale Outdated and ready to close label May 12, 2026
@github-actions github-actions Bot closed this May 17, 2026
@andig
Copy link
Copy Markdown
Member

andig commented May 17, 2026

Curtailment has been merged

@andig andig reopened this May 17, 2026
@github-actions github-actions Bot removed the stale Outdated and ready to close label May 17, 2026
@CiNcH83
Copy link
Copy Markdown
Contributor Author

CiNcH83 commented May 17, 2026

OK. Will check today.

@CiNcH83 CiNcH83 force-pushed the huawei_curtailment branch 3 times, most recently from a962576 to 6dcd527 Compare May 17, 2026 09:26
@CiNcH83
Copy link
Copy Markdown
Contributor Author

CiNcH83 commented May 17, 2026

Done.

There are still open questions from my side though, see initial posting.

@andig
Copy link
Copy Markdown
Member

andig commented May 17, 2026

It would also be possible to set the Active power control mode programmatically via register 47415, see #19715 (comment). But it is kind of redundant to do it on every call!?

Whats the question?

Why not pass through the limited power value received from the FNN controlbox and write it to register 47416 (Maximum Feed Grid Power (kW))?

Because the current API doesn't allow that.

Does maxacpower have to become mandatory? It is required to calculate percentage from received limited power.

What received limited power?

Comment thread templates/definition/meter/huawei-sun2000-hybrid.yaml
@CiNcH83
Copy link
Copy Markdown
Contributor Author

CiNcH83 commented May 17, 2026

Whats the question?

Shall I set the mode as well?

Register: 47415
Description: Active power control mode
Unit: N/A
Gain: 1
Data type: UINT16
Access: RW
Scope: 0: Unlimited (default); 1: DI active scheduling; 5: Zero power grid connection; 6: Power-limited grid connection (kW); 7: Power-limited grid connection (%)

Mode 7 can either be set via Huawei FusionSolar portal (UI, see screenhot initial post) or via Modbus. It is more of a static configuration setting IMHO which is why I don't set it via template (Modbus) but instead added a note to the docu.

What received limited power?

It may not be necessary at the moment because only 0 and 100% is supported. But what if we want to set something in between? We'll need the wattage passed via FNN controlbox to be converted to % of the maximum inverter power, no?

@CiNcH83 CiNcH83 force-pushed the huawei_curtailment branch from 7b3d816 to e032796 Compare May 18, 2026 10:33
@CiNcH83
Copy link
Copy Markdown
Contributor Author

CiNcH83 commented May 18, 2026

I updated and cleaned up the branch. I am still getting the error:

[main  ] FATAL 2026/05/18 12:41:11 meter [sun2000] cannot create meter 'sun2000': cannot create meter type 'template:huawei-sun2000': cannot create meter type 'custom': curtail: strconv.ParseBool: parsing "7": invalid syntax

So do I need the type stuff? I backed the changes up here so we can still cherrypick what is needed...

@CiNcH83
Copy link
Copy Markdown
Contributor Author

CiNcH83 commented May 18, 2026

  curtailed:
    source: modbus
    {{- include "modbus" . | indent 2 }}
    register:
      address: 47415 # Active power control mode (0=no curtailment, 1=external DI scheduling, 5=zero feed-in, 6=curtail kW, 7=curtail %)
      type: holding
      decode: uint16

Do we need a int2bool for that? Or does this happen implicitly (0=no curtailment/curtailed=false, everything else equates to curtailed=true)? Or is it better to only check for 0 and 7 which is what the template sets?

@CiNcH83 CiNcH83 changed the title Huawei: add curtailment api Huawei: add curtail May 18, 2026
@CiNcH83 CiNcH83 changed the title Huawei: add curtail Huawei SUN2000: add curtail May 18, 2026
@CiNcH83
Copy link
Copy Markdown
Contributor Author

CiNcH83 commented May 18, 2026

OK. Looks to be working:
image

I set it to 30%. So scaling works. Also curtailed works properly:

image

@CiNcH83 CiNcH83 marked this pull request as ready for review May 18, 2026 20:17
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:

  • The new BoolSetter handling for constPlugin with typ == "int" always calls set(0), which both ignores the incoming boolean value and overwrites the configured integer, so it likely won’t apply the intended curtailment percentage; consider either mapping true/false to meaningful integer values or using a different mechanism that preserves the configured Value.
  • curtailpercent defaults to 0 and is directly written (scaled) to register 47418, which effectively enforces 0% feed-in when curtailment is enabled; if that’s not intended, consider using a sentinel (e.g. unset/nil) or explicit validation to distinguish “no curtailment configured” from “explicit 0% feed-in”.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `BoolSetter` handling for `constPlugin` with `typ == "int"` always calls `set(0)`, which both ignores the incoming boolean value and overwrites the configured integer, so it likely won’t apply the intended curtailment percentage; consider either mapping `true/false` to meaningful integer values or using a different mechanism that preserves the configured `Value`.
- `curtailpercent` defaults to `0` and is directly written (scaled) to register `47418`, which effectively enforces 0% feed-in when curtailment is enabled; if that’s not intended, consider using a sentinel (e.g. unset/nil) or explicit validation to distinguish “no curtailment configured” from “explicit 0% feed-in”.

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.

@CiNcH83
Copy link
Copy Markdown
Contributor Author

CiNcH83 commented May 19, 2026

It is probably important for evcc not to perform a curtail(false) if there has not been a curtail(true) before, so only if the system has either been manually curtailed (evcc CLI) or via FNN controlbox. Otherwise evcc will wipe static 60/70% curtailment configurations...

Comment thread plugin/const.go Outdated
type constPlugin struct {
ctx context.Context
str string
typ string
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

the const changes need be reverted, was a bad idea

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The template does not work with the reverted const changes!

[main  ] FATAL 2026/05/19 18:38:46 meter [sun2000] cannot create meter 'sun2000': cannot create meter type 'template:huawei-sun2000': cannot create meter type 'custom': curtail: strconv.ParseBool: parsing "7": invalid syntax

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As commented on the other pr: use convert to switch to int setter.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Can't figure this out. Could use some more help.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You need convert with bool2int, same as the other PR

Comment thread templates/definition/meter/huawei-sun2000-hybrid.yaml Outdated
CiNcH83 and others added 2 commits May 19, 2026 18:18
Co-authored-by: andig <cpuidle@gmail.com>
This reverts commit 91949d8.
@andig andig enabled auto-merge (squash) May 19, 2026 16:28
@andig andig merged commit ef12393 into evcc-io:master May 19, 2026
7 checks passed
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.

3 participants