Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions io.openems.edge.solaredge.ess/.classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21"/>
<classpathentry kind="src" output="bin" path="src"/>
<classpathentry kind="src" output="bin_test" path="test">
<attributes>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin"/>
</classpath>
2 changes: 2 additions & 0 deletions io.openems.edge.solaredge.ess/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/bin_test/
/generated/
23 changes: 23 additions & 0 deletions io.openems.edge.solaredge.ess/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>io.openems.edge.solaredge.ess</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>bndtools.core.bndbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>bndtools.core.bndnature</nature>
</natures>
</projectDescription>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
eclipse.preferences.version=1
encoding//src/io/openems/edge/solaredge/ess/Config.java=UTF-8
encoding//src/io/openems/edge/solaredge/ess/SolarEdgeEss.java=UTF-8
encoding//src/io/openems/edge/solaredge/ess/SolarEdgeEssImpl.java=UTF-8
encoding//test/io/openems/edge/solaredge/ess/MyConfig.java=UTF-8
encoding//test/io/openems/edge/solaredge/ess/SolarEdgeEssImplTest.java=UTF-8
encoding/<project>=UTF-8
encoding/bnd.bnd=UTF-8
encoding/readme.adoc=UTF-8
11 changes: 11 additions & 0 deletions io.openems.edge.solaredge.ess/.settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=21
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=21
19 changes: 19 additions & 0 deletions io.openems.edge.solaredge.ess/bnd.bnd
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Bundle-Name: OpenEMS Edge SolarEdge ESS
Bundle-Vendor: Timo Schlegel
Bundle-License: https://opensource.org/licenses/EPL-2.0
Bundle-Version: 1.0.0.${tstamp}

-buildpath: \
${buildpath},\
io.openems.common,\
io.openems.edge.battery.api,\
io.openems.edge.batteryinverter.api,\
io.openems.edge.bridge.modbus,\
io.openems.edge.common,\
io.openems.edge.ess.api,\
io.openems.edge.ess.generic;version=snapshot,\
io.openems.edge.timedata.api,\
io.openems.j2mod,\

-testpath: \
${testpath}
15 changes: 15 additions & 0 deletions io.openems.edge.solaredge.ess/readme.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
= SolarEdge Hybrid Inverters

ESS::
- HybridEss
- SymmetricEss
- ManagedSymmetricEss
- AsymmetricEss
- ManagedAsymmetricEss
- SinglePhaseEss
- ManagedSinglePhaseEss

Charger::
- EssDcCharger

https://github.com/OpenEMS/openems/tree/develop/io.openems.edge.solaredge.ess[Source Code icon:github[]]
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package io.openems.edge.solaredge.ess;

import io.openems.edge.common.channel.IntegerReadChannel;
import io.openems.edge.common.component.ClockProvider;
import io.openems.edge.common.type.TypeUtils;
import io.openems.edge.ess.generic.common.AbstractAllowedChargeDischargeHandler;
import io.openems.edge.solaredge.ess.charger.SolarEdgeCharger;

import io.openems.edge.battery.api.Battery;
import io.openems.edge.batteryinverter.api.SymmetricBatteryInverter;

public class AllowedChargeDischargeHandler extends AbstractAllowedChargeDischargeHandler<SolarEdgeEssImpl> {

public AllowedChargeDischargeHandler(SolarEdgeEssImpl parent) {
super(parent);
}

@Override
public void accept(ClockProvider clockProvider, Battery battery, SymmetricBatteryInverter inverter) {
this.accept(clockProvider);
}

/**
* Calculates AllowedChargePower and AllowedDischargePower and sets the
* Channels.
*
* @param clockProvider a {@link ClockProvider}
*/
public void accept(ClockProvider clockProvider) {
IntegerReadChannel bmsMaxChargePowerChannel = parent.channel(SolarEdgeEss.ChannelId.BATTERY1_MAX_CHARGE_CONTINUES_POWER);
IntegerReadChannel bmsMaxDischargePowerChannel = parent.channel(SolarEdgeEss.ChannelId.BATTERY1_MAX_DISCHARGE_CONTINUES_POWER);
var bmsPseudoVoltage = 1;
var bmsChargePseudoImax = bmsMaxChargePowerChannel.getNextValue().orElse(0) / bmsPseudoVoltage;
var bmsDischargePseudoImax = bmsMaxDischargePowerChannel.getNextValue().orElse(0) / bmsPseudoVoltage;
this.calculateAllowedChargeDischargePower(clockProvider, true, bmsChargePseudoImax, bmsDischargePseudoImax, bmsPseudoVoltage);

// Battery limits
var batteryAllowedChargePower = Math.round(this.lastBatteryAllowedChargePower);
var batteryAllowedDischargePower = Math.round(this.lastBatteryAllowedDischargePower);

// PV-Production
Integer pvProduction = 0;
for (SolarEdgeCharger charger : parent.chargers) {
pvProduction = TypeUtils.sum(pvProduction, charger.getActualPowerChannel().getNextValue().orElse(0));
}

// Block battery charging on battery full
if (parent.getSoc().orElse(100) >= 100) {
batteryAllowedChargePower = 0;
}

// Block battery discharging on battery empty
if (parent.getSoc().orElse(0) <= 10) {
batteryAllowedDischargePower = 0;
}

// Calculates Maximum Allowed AC-Charge Power as positive numbers (or negative when force discharge is active)
// Force discharge: pvProduction>batteryAllowedChargePower requires a minimum discharge
var acAllowedChargePower = batteryAllowedChargePower - pvProduction;

// Calculates Maximum Allowed AC-Discharge Power as positive numbers
var acAllowedDischargePower = TypeUtils.min(batteryAllowedDischargePower + pvProduction,parent.getMaxApparentPower().orElse(0));

// Inverter limits
var maxApparentPower = parent.getMaxApparentPower().orElse(0);

// Force Discharge active?
if (acAllowedChargePower < 0) {

// Limit forced DischargePower to maxApparentPower
if (Math.abs(acAllowedChargePower) > maxApparentPower) {
acAllowedChargePower = maxApparentPower * (-1);
}

// Make sure AllowedDischargePower is greater-or-equals absolute AllowedChargePower
acAllowedDischargePower = Math.max(Math.abs(acAllowedChargePower), acAllowedDischargePower);
} else {

// Limit acChargerPower to maxApparentPower
if (acAllowedChargePower > maxApparentPower) {
acAllowedChargePower = maxApparentPower;
}
}

// Apply AllowedChargePower and AllowedDischargePower
this.parent._setAllowedChargePower(acAllowedChargePower * -1 /* invert charge power */);
this.parent._setAllowedDischargePower(acAllowedDischargePower);
}
}
Loading
Loading