Sungrow PV Inverter and ESS Implementation - #3935
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #3935 +/- ##
=============================================
- Coverage 58.34% 55.46% -2.88%
- Complexity 19469 19533 +64
=============================================
Files 3306 3861 +555
Lines 161114 178070 +16956
Branches 11953 14818 +2865
=============================================
+ Hits 93993 98743 +4750
- Misses 63425 75440 +12015
- Partials 3696 3887 +191 🚀 New features to boost your workflow:
|
sfeilmeier
left a comment
There was a problem hiding this comment.
See my remarks. Same applies to other similar files.
Who can work on these topics?
| String ess_id() default "ess0"; | ||
|
|
||
| @AttributeDefinition(name = "ESS target filter", description = "This is auto-generated by 'ESS-ID'.") | ||
| String ess_target() default "(enabled=true)"; |
There was a problem hiding this comment.
Please replace with ReferenceConfigurationPlugin
| } | ||
|
|
||
| private void mapChannelValues() { | ||
| this.ess.getTotalDcPowerChannel().onSetNextValue(value -> { |
There was a problem hiding this comment.
Why do you not map those Registers directly?
There was a problem hiding this comment.
So the alternative would be to make this a ModbusComponent, read the registers here and leave them out in the ESS implementation? This would mean that you send more modbus tasks per second but you can remove some channels from the ESS, right?
I have no strong opinion which is better, but this was the first thing that came into my mind. I just had a look at the GoodWe implementations and saw that the single string chargers have their own modbus protocol, while the two string chargers don't.
Now, as I write, one more options comes into my mind. If the charger is referenced in the ESS and not the other way round, one could do something like the following in the modbus protocol:
m(new UnsignedDoubleWordElement(5016)).build() //
.onUpdateCallback(value -> this.charger._setActualPower(value)), //Is that what you have in mind?
There was a problem hiding this comment.
Ok, I did not realize this is actually copying from ess component. Then it's ok. Only flaw is, that you would have to remove the listener on deactivate, otherwise the garbage collector will not be able to cleanup.
| * | ||
| * @param value the next value | ||
| */ | ||
| public default void _setGridMode(GridMode value) { |
There was a problem hiding this comment.
No, it was replaced with ChannelUtils.setValue() by purpose. Please reset to develop.
There was a problem hiding this comment.
Okay, I see. I was wondering why this method disappeared. For what reason do you use ChannelUtils.setValue()?
The same then for ManagedSymmetricEss._setAllowedChargePower() I guess? But why is ManagedSymmetricEss._setAllowedDischargePower() still there?
| @Reference | ||
| private ConfigurationAdmin cm; | ||
|
|
||
| @Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY) |
There was a problem hiding this comment.
If you use GenerateTargetsFromReferences, you have to set the target property here - see documentation: https://github.com/OpenEMS/openems/blob/develop/io.openems.core.referencetarget/readme.adoc
| this.config = config; | ||
| super.activate(context, config.id(), config.alias(), config.enabled()); | ||
|
|
||
| if (OpenemsComponent.updateReferenceFilter(this.cm, this.servicePid(), "ess", config.ess_id())) { |
There was a problem hiding this comment.
Also this is obsolete then
| } | ||
|
|
||
| private void mapChannelValues() { | ||
| this.ess.getTotalDcPowerChannel().onSetNextValue(value -> { |
There was a problem hiding this comment.
Ok, I did not realize this is actually copying from ess component. Then it's ok. Only flaw is, that you would have to remove the listener on deactivate, otherwise the garbage collector will not be able to cleanup.
|
|
||
| @ObjectClassDefinition(// | ||
| name = "ESS Sungrow", // | ||
| description = "Implements the Sungrow SH10RT Hybrid Ess") |
There was a problem hiding this comment.
Do you know how different the protocols of Sungrow devices are? Should we probably rename the Factory-ID to something like Ess.Sungrow.Hybrid.* to have a namespace for future implementations?
| "Modbus", config.modbus_id())) { | ||
| return; | ||
| } | ||
| this.getActivePowerChannel().onSetNextValue(value -> { // |
There was a problem hiding this comment.
ElectricityMeter .calculatePhasesFromActivePower() does exactly this
| @@ -0,0 +1,25 @@ | |||
| package io.openems.edge.sungrow.dccharger; | |||
|
|
|||
| import org.junit.Test; | |||
There was a problem hiding this comment.
JUnit4 is deprecated. Please use Juniper
| new ComponentTest(new SungrowDcChargerImpl()) // | ||
| .addReference("cm", new DummyConfigurationAdmin()) // | ||
| .addReference("ess", new EssSungrowImpl()) // | ||
| .activate(MyConfig.create() // |
There was a problem hiding this comment.
I can only recommend having one test with strict-mode for Modbus devices.
Updated version of Sungrow implementation. Replaces #2528
This version is used on a handful of productive systems run by opernikus.