Mixed Cluster between AC-only and hybrid ESS

We are testing an ESS Cluster consisting of

  • one HybridEss (SolarEdge)

  • one AC-coupled battery ESS

The HybridEss follows the same semantics as GoodWe:

  • ACTIVE_POWER = AC hybrid power (PV + battery)

  • DC_DISCHARGE_POWER = battery power

  • applyPower() expects an AC setpoint

The ESS Cluster / PowerDistribution solver appears to operate only on ManagedSymmetricEss semantics and does not seem to distinguish HybridEss from regular ESS.

As a consequence, ACTIVE_POWER has different meanings inside the same cluster:

  • HybridEss → PV + battery

  • AC-coupled ESS → battery only

This can lead to situations where one ESS charges while the other discharges.

Is the intended OpenEMS architecture:

  1. HybridEss should not be combined with AC-coupled ESS in a standard Ess.Cluster?

  2. HybridEss should expose battery power on ACTIVE_POWER when used in a cluster?

  3. PowerDistribution should become HybridEss-aware and use DC_DISCHARGE_POWER internally?

Has anybody already solved this use case?

regards,
Klinki

Hi Klinki,

I developed a PreferDcPower optimizer that is specifically designed for HybridEss systems and also supports a mixed ESS-Cluster consisting of both HybridEss and AC-coupled ESS.

You might find the discussion and implementation useful for your use case:

Maybe this already solves (or at least addresses) the issue you’re seeing.

Hi MrT,
Thanks for the information!
Yes, I came across that thread as well. Since the combination of Cluster + OptimizedCharge + Scheduler V2 doesn’t really work properly, I also switched back to V1. So I’m going to give your module a try. In theory, it should solve my problem and allow me to finally use your SolarEdge implementation. I’ll report back.
How far along are you with adapting it to V2?

regards,
klinki

Hi Klinki,

sorry for the late response.

I haven’t put any effort into migrating the implementation from V1 to V2 yet. As far as I understand, though, the migration should be fairly straightforward. My understanding is that the basic logic can remain the same, while the way the calculated values are passed to the optimizer needs to be adapted to the V2 architecture.

What I haven’t fully understood yet is how exactly V2 expects these calculated values to be provided. However, I also haven’t spent much time looking into the V2 optimizer architecture so far.

If you already have a better understanding of how the V2 optimizer architecture works and how the values need to be passed, I’d be happy to support the migration to V2.

You mentioned that you wanted to test the current implementation — did you get a chance to do so? Any feedback would be appreciated.

Best regards,
MrT