forked from OpenEMS/openems
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ESS Standby-Controller (OpenEMS#1158)
Regularly checks the functionality of an ESS once per week while being in Standby mode. Use-Case:: In projects with Hochlastzeitfenster (HLZF) the storage system might not be used for some weeks or months. In these periods it is required to make a regular check of the system and to calibrate the battery. This controller automates this function. Scheduling:: The controller is supposed to be configured to run with less priority than "LimitTotalDischarge", "BatteryHandling",... and higher priority than "HLZF", "Balancing", "Peak-Shaving",...
- Loading branch information
1 parent
59db904
commit 5c9b781
Showing
22 changed files
with
1,088 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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-1.8"/> | ||
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/bin_test/ | ||
/generated/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.controller.ess.standby</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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
Bundle-Name: OpenEMS Edge Controller ESS Standby | ||
Bundle-Vendor: FENECON GmbH | ||
Bundle-License: https://opensource.org/licenses/EPL-2.0 | ||
Bundle-Version: 1.0.0.${tstamp} | ||
|
||
-buildpath: \ | ||
${buildpath},\ | ||
io.openems.common,\ | ||
io.openems.edge.common,\ | ||
io.openems.edge.controller.api,\ | ||
io.openems.edge.ess.api,\ | ||
|
||
-testpath: \ | ||
${testpath} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
= ESS Standby | ||
|
||
Regularly checks the functionality of an ESS once per week while being in Standby mode. | ||
|
||
Use-Case:: | ||
In projects with Hochlastzeitfenster (HLZF) the storage system might not be used for some weeks or months. In these periods it is required to make a regular check of the system and to calibrate the battery. This controller automates this function. | ||
|
||
Scheduling:: | ||
The controller is supposed to be configured to run with less priority than "LimitTotalDischarge", "BatteryHandling",... and higher priority than "HLZF", "Balancing", "Peak-Shaving",... | ||
|
||
https://github.com/OpenEMS/openems/tree/develop/io.openems.edge.controller.ess.standby[Source Code icon:github[]] |
36 changes: 36 additions & 0 deletions
36
...penems.edge.controller.ess.standby/src/io/openems/edge/controller/ess/standby/Config.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package io.openems.edge.controller.ess.standby; | ||
|
||
import java.time.DayOfWeek; | ||
|
||
import org.osgi.service.metatype.annotations.AttributeDefinition; | ||
import org.osgi.service.metatype.annotations.ObjectClassDefinition; | ||
|
||
@ObjectClassDefinition(// | ||
name = "Controller ESS Standby", // | ||
description = "Puts a energy storage system in standby mode while regularly checking the functionality once per week.") | ||
public @interface Config { | ||
|
||
@AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") | ||
String id() default "ctrlEssStandby0"; | ||
|
||
@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 = "Startdate", description = "for example: 30.12.1998") | ||
String startDate(); | ||
|
||
@AttributeDefinition(name = "Enddate", description = "for example: 31.12.1998") | ||
String endDate(); | ||
|
||
@AttributeDefinition(name = "Day of week", description = "On which weekday should the regular check run?") | ||
DayOfWeek dayOfWeek(); | ||
|
||
String webconsole_configurationFactory_nameHint() default "Controller ESS Standby [{id}]"; | ||
|
||
} |
26 changes: 26 additions & 0 deletions
26
....controller.ess.standby/src/io/openems/edge/controller/ess/standby/StandbyController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package io.openems.edge.controller.ess.standby; | ||
|
||
import io.openems.edge.common.channel.Doc; | ||
import io.openems.edge.controller.api.Controller; | ||
import io.openems.edge.controller.ess.standby.statemachine.StateMachine.State; | ||
|
||
public interface StandbyController extends Controller { | ||
|
||
public enum ChannelId implements io.openems.edge.common.channel.ChannelId { | ||
STATE_MACHINE(Doc.of(State.values()) // | ||
.text("Current State of State-Machine")), // | ||
; | ||
|
||
private final Doc doc; | ||
|
||
private ChannelId(Doc doc) { | ||
this.doc = doc; | ||
} | ||
|
||
@Override | ||
public Doc doc() { | ||
return this.doc; | ||
} | ||
} | ||
|
||
} |
119 changes: 119 additions & 0 deletions
119
...troller.ess.standby/src/io/openems/edge/controller/ess/standby/StandbyControllerImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package io.openems.edge.controller.ess.standby; | ||
|
||
import java.time.LocalDate; | ||
import java.time.format.DateTimeFormatter; | ||
|
||
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.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.common.sum.GridMode; | ||
import io.openems.edge.common.sum.Sum; | ||
import io.openems.edge.controller.api.Controller; | ||
import io.openems.edge.controller.ess.standby.statemachine.Context; | ||
import io.openems.edge.controller.ess.standby.statemachine.StateMachine; | ||
import io.openems.edge.controller.ess.standby.statemachine.StateMachine.State; | ||
import io.openems.edge.ess.api.ManagedSymmetricEss; | ||
|
||
@Designate(ocd = Config.class, factory = true) | ||
@Component(// | ||
name = "Controller.Ess.Standby", // | ||
immediate = true, // | ||
configurationPolicy = ConfigurationPolicy.REQUIRE // | ||
) | ||
public class StandbyControllerImpl extends AbstractOpenemsComponent | ||
implements StandbyController, Controller, OpenemsComponent { | ||
|
||
private static final String DATE_FORMAT = "dd.MM.yyyy"; | ||
|
||
private final Logger log = LoggerFactory.getLogger(StandbyControllerImpl.class); | ||
|
||
public StandbyControllerImpl() { | ||
super(// | ||
OpenemsComponent.ChannelId.values(), // | ||
Controller.ChannelId.values(), // | ||
StandbyController.ChannelId.values() // | ||
); | ||
} | ||
|
||
@Reference | ||
protected ComponentManager componentManager; | ||
|
||
@Reference | ||
protected Sum sum; | ||
|
||
/** | ||
* Manages the {@link State}s of the StateMachine. | ||
*/ | ||
private final StateMachine stateMachine = new StateMachine(State.UNDEFINED); | ||
|
||
private Config config; | ||
private LocalDate configuredStartDate; | ||
private LocalDate configuredEndDate; | ||
|
||
@Activate | ||
void activate(ComponentContext context, Config config) { | ||
super.activate(context, config.id(), config.alias(), config.enabled()); | ||
|
||
this.config = config; | ||
this.configuredStartDate = convertDate(config.startDate()); | ||
this.configuredEndDate = convertDate(config.endDate()); | ||
} | ||
|
||
@Deactivate | ||
protected void deactivate() { | ||
super.deactivate(); | ||
} | ||
|
||
@Override | ||
public void run() throws OpenemsNamedException { | ||
ManagedSymmetricEss ess = this.componentManager.getComponent(this.config.ess_id()); | ||
|
||
/* | ||
* Check that we are On-Grid (and warn on undefined Grid-Mode) | ||
*/ | ||
GridMode gridMode = ess.getGridMode(); | ||
if (gridMode.isUndefined()) { | ||
this.logWarn(this.log, "Grid-Mode is [UNDEFINED]"); | ||
} | ||
switch (gridMode) { | ||
case ON_GRID: | ||
case UNDEFINED: | ||
break; | ||
case OFF_GRID: | ||
return; | ||
} | ||
|
||
// Store the current State | ||
this.channel(StandbyController.ChannelId.STATE_MACHINE).setNextValue(this.stateMachine.getCurrentState()); | ||
|
||
// Prepare Context | ||
Context context = new Context(this, ess, this.sum, this.configuredStartDate, this.configuredEndDate, | ||
this.config.dayOfWeek(), this.componentManager.getClock()); | ||
|
||
// Call the StateMachine | ||
this.stateMachine.run(context); | ||
} | ||
|
||
/** | ||
* Converts a string to a LocalDate. | ||
* | ||
* @param date the date as string in the format "dd.MM.yyyy" (DATE_FORMAT). | ||
* @return the date as {@link LocalDate} | ||
*/ | ||
private static LocalDate convertDate(String date) { | ||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_FORMAT); | ||
LocalDate localDate = LocalDate.parse(date, dateTimeFormatter); | ||
return localDate; | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
...ntroller.ess.standby/src/io/openems/edge/controller/ess/standby/statemachine/Context.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package io.openems.edge.controller.ess.standby.statemachine; | ||
|
||
import java.time.Clock; | ||
import java.time.DayOfWeek; | ||
import java.time.LocalDate; | ||
|
||
import io.openems.edge.common.statemachine.AbstractContext; | ||
import io.openems.edge.common.sum.Sum; | ||
import io.openems.edge.controller.ess.standby.StandbyController; | ||
import io.openems.edge.ess.api.ManagedSymmetricEss; | ||
|
||
public class Context extends AbstractContext<StandbyController> { | ||
|
||
protected final ManagedSymmetricEss ess; | ||
protected final Sum sum; | ||
protected final LocalDate configuredStartDate; | ||
protected final LocalDate configuredEndDate; | ||
protected final DayOfWeek configuredDayOfWeek; | ||
|
||
/** | ||
* The clock. Used to provide a mocked clock for unit tests. | ||
*/ | ||
protected final Clock clock; | ||
|
||
public Context(StandbyController parent, ManagedSymmetricEss ess, Sum sum, LocalDate configuredStartDate, | ||
LocalDate configuredEndDate, DayOfWeek configuredDayOfWeek, Clock clock) { | ||
super(parent); | ||
this.ess = ess; | ||
this.sum = sum; | ||
this.configuredStartDate = configuredStartDate; | ||
this.configuredEndDate = configuredEndDate; | ||
this.configuredDayOfWeek = configuredDayOfWeek; | ||
this.clock = clock; | ||
} | ||
|
||
} |
Oops, something went wrong.