Guten Morgen Steffan,
ich habe vor kurzer Zeit einen neuen Controller zum Laden und Entladen der Batterie in OpenEMS implementiert. Die Implementierung verlief weitestgehend reibungsfrei und wir können den Controller ohne Fehlermeldungen „Bauen“.
Lediglich die „Test-Datein“ (siehe Hierarchie Controller) geben noch Fehler zurück, aber diese können ignoriert werden oder?
———————————————————————————————————————————
Wenn wir die Konfiguration mit dem neuen Controller nun auf unserem Zielsystem ausführen und einen beliebigen Wert für die Leistung einstellen (egal ab größer, kleiner oder gleich null) beginnt der Refu88k zu arbeiten. Nach wenigen Sekunden springt der Umrichter von dem Betriebsbereiten Zustand in einen Fehlerzustand über und gibt folgenden Fehler aus:
„DC-Leistung nicht ausreichend“.
In Terminator lassen wir uns zudem einzelne Werte des Controllers zurück geben. Der Wert „State“ steht dabei auf „Fault“ und es wird der Fehler „Running the Controller failed“ ausgegeben.
Ergebnis: Der Controller funktioniert nicht!
Folgende Controller sind in der Konfiguration aktiviert:
- Battery-Inverter refustore88k
- Baumaco BMS
- Bridge Modbus RTU Serial
- Bridge Modbus TCP
- Controller API REST/JSON
- Controller API Websocket
- Controller Debug Detailed Log
- Controller Debug Log
- Controller ESS Charge Discharge (mein selbst programmierter Controller)
- Core Host
- ESS Generic Managed Symmetric
- Meter Microcare SDM 630
- org.ops4j.pax.logging
- Scheduler All Alphabetically
- Timedata Influx DB
Kannst du mir bei diesem Problem weiter helfen? Ist unsere Konfiguration vielleicht kaputt oder ist der Quellcode für meinen Controller fehlerhaft?
Ich komme an dieser Stelle nicht weiter und hoffe du kannst mir weiterhelfen.
———————————————————————————————————————————
Quellcode Controller:
package io.openems.edge.controller.ess.chargedischarge;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.openems.common.exceptions.OpenemsError.OpenemsNamedException;
import io.openems.edge.common.component.AbstractOpenemsComponent;
import io.openems.edge.common.component.ComponentManager;
import io.openems.edge.common.component.OpenemsComponent;
import io.openems.edge.controller.api.Controller;
import io.openems.edge.controller.ess.chargedischarge.ChargeDischarge;
import io.openems.edge.ess.api.ManagedSymmetricEss;
import io.openems.edge.ess.power.api.Phase;
import io.openems.edge.ess.power.api.Pwr;
@Designate(ocd = Config.class, factory = true)
@Component(//
name = “Controller.Ess.ChargeDischarge”, //
immediate = true, //
configurationPolicy = ConfigurationPolicy.REQUIRE)
public class ChargeDischarge extends AbstractOpenemsComponent implements Controller, OpenemsComponent {
private final Logger log = LoggerFactory.getLogger(ChargeDischarge.class);
@Reference
protected ComponentManager componentManager;
private Config config;
//initialization of variables
int current_power_charge; //current calculated power
int duration; //duration of the local state
int current_target_power; //current target power which is set in AppacheFelixWebInterface
int maxChargePower; //ESS max Charge Power
int maxDischargePower; //ESS max Discharge Power
int current_target_power_charge; //current power which is set
int target_power; //power which is set in Appache Felix
int step; //step by which performance is increased
/*
public enum ChannelId implements io.openems.edge.common.channel.ChannelId {
private final Doc doc;
private ChannelId(Doc doc) { this.doc = doc; }
@Override public Doc doc() { return this.doc; } }
*/
public ChargeDischarge() {
super(//
OpenemsComponent.ChannelId.values(), //
Controller.ChannelId.values()//, //
//ChannelId.values() //
);
}
@Activate
void activate(ComponentContext context, Config config) {
super.activate(context, config.id(), config.alias(), config.enabled());
this.config = config;
//initialization of variables
current_power_charge =0;
duration = 0;
current_target_power = 0;
target_power = 0;
step = this.config.step_size();
maxChargePower = 0;
maxDischargePower = 0;
}
@Deactivate
protected void deactivate() {
super.deactivate();
}
@Modified
void modified(Config config) throws OpenemsNamedException {
this.config = config;
step = this.config.step_size();
}
//print debug-log
@Override
public String debugLog() {
return "Hello World from Controller ChargeDischarge"+ //
" ESS max. Discharge Power " + this.maxDischargePower + //
" ESS max. Charge Power " + this.maxChargePower + //
" current Power " + this.current_power_charge + //
" target Power " + this.target_power + //
" current Target Power " + this.current_target_power + //
"set active Power" + this.current_target_power_charge ; //
}
@Override
public void run() throws OpenemsNamedException {
ManagedSymmetricEss ess = this.componentManager.getComponent(this.config.ess_id());
// get max charge/discharge power
maxDischargePower = ess.getPower().getMaxPower(ess, Phase.ALL, Pwr.ACTIVE);
maxChargePower = ess.getPower().getMinPower(ess, Phase.ALL, Pwr.ACTIVE);
int ctp = this.calculate_current_target_power(step, current_power_charge, maxChargePower, duration, maxDischargePower); //function to calculate_current_target_power
ess.setActivePowerLessOrEquals(ctp); //set the calculated power at the output of the ess
}
private int calculate_current_target_power( int step, int current_power_charge, int maxChargePower, int duration, int maxDischargePower ) throws OpenemsNamedException {
target_power = this.config.target_power();
//1) ensure max ramp steepness
//2) ensure respecting system limit
//3) ensure reaching and holding of target power
//4) ensure duration of target power active
int sign = -1;
if (target_power >= 0)
{
sign = 1;
}
target_power = Math.abs(target_power);
if (current_power_charge < target_power) {
current_power_charge += step; //1)3)calculate the current power for charging
}
if (sign == -1)
{
current_target_power = Math.min(current_power_charge, maxDischargePower);//2)
}
current_target_power = Math.min(current_power_charge, maxChargePower);//2)
if (current_power_charge >= target_power) { //4)
duration = duration +1;
current_target_power = target_power;
}
if (duration == 10) { //4)
duration = 0;
current_target_power = 0;
}
return -current_target_power*sign;
}
}
———————————————————————————————————————————
Quellcode Config Controller:
package io.openems.edge.controller.ess.chargedischarge;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@ObjectClassDefinition(//
name = “Controller Ess Charge Discharge”, //
description = “charges and discharges the battery at a certain SOC”)
@interface Config {
@AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component")
String id() default "ctrlChargeDischarge0";
@AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID")
String alias() default "";
@AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?")
boolean enabled() default true;
@AttributeDefinition(name = "Ess-ID", description = "ID of Ess device.")
String ess_id();
@AttributeDefinition(name = "Charging Power [W]", description = "Power to charge and discharge the battery")
int target_power() default 0;
@AttributeDefinition(name = "Step-size [W]", description = "Step by which performance is continuously increased")
int step_size() default 100;
String webconsole_configurationFactory_nameHint() default "Controller io.openems.controller.ChargeDischarge [{id}]";
}
Für einen besseren Datenaustausch finden Sie hier meine E-Mail Adresse und meine Telefonnummer.
Con.Seifert@fes-aes.de
0375 56605022