Skip to content

Commit

Permalink
Add 'CumulatedActiveTime' Channel for Controllers with Relay (#677) (#…
Browse files Browse the repository at this point in the history
…2230)

Co-authored-by: Sagar Venu <[email protected]>
  • Loading branch information
sfeilmeier and venu-sagar authored Jun 17, 2023
1 parent c8b6186 commit 13d98bb
Show file tree
Hide file tree
Showing 15 changed files with 192 additions and 34 deletions.
3 changes: 2 additions & 1 deletion io.openems.edge.controller.channelthreshold/bnd.bnd
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Bundle-Version: 1.0.0.${tstamp}
${buildpath},\
io.openems.common,\
io.openems.edge.common,\
io.openems.edge.controller.api
io.openems.edge.controller.api,\
io.openems.edge.timedata.api,\

-testpath: \
${testpath}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package io.openems.edge.controller.channelthreshold;

import static io.openems.common.channel.PersistencePriority.HIGH;
import static io.openems.common.channel.Unit.CUMULATED_SECONDS;
import static io.openems.common.types.OpenemsType.LONG;

import io.openems.edge.common.channel.Doc;
import io.openems.edge.common.component.OpenemsComponent;
import io.openems.edge.controller.api.Controller;
Expand All @@ -8,7 +12,11 @@ public interface ControllerChannelThreshold extends Controller, OpenemsComponent

public enum ChannelId implements io.openems.edge.common.channel.ChannelId {
STATE_MACHINE(Doc.of(State.values()) //
.text("Current State of State-Machine"));
.text("Current State of State-Machine")),

CUMULATED_ACTIVE_TIME(Doc.of(LONG)//
.unit(CUMULATED_SECONDS) //
.persistencePriority(HIGH));

private final Doc doc;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
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.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -21,6 +24,9 @@
import io.openems.edge.common.component.OpenemsComponent;
import io.openems.edge.common.type.TypeUtils;
import io.openems.edge.controller.api.Controller;
import io.openems.edge.timedata.api.Timedata;
import io.openems.edge.timedata.api.TimedataProvider;
import io.openems.edge.timedata.api.utils.CalculateActiveTime;

@Designate(ocd = Config.class, factory = true)
@Component(//
Expand All @@ -29,9 +35,11 @@
configurationPolicy = ConfigurationPolicy.REQUIRE //
)
public class ControllerChannelThresholdImpl extends AbstractOpenemsComponent
implements ControllerChannelThreshold, Controller, OpenemsComponent {
implements ControllerChannelThreshold, Controller, OpenemsComponent, TimedataProvider {

private final Logger log = LoggerFactory.getLogger(ControllerChannelThresholdImpl.class);
private final CalculateActiveTime calculateCumulatedActiveTime = new CalculateActiveTime(this,
ControllerChannelThreshold.ChannelId.CUMULATED_ACTIVE_TIME);

@Reference
private ComponentManager componentManager;
Expand All @@ -50,6 +58,9 @@ public class ControllerChannelThresholdImpl extends AbstractOpenemsComponent
/** Should the hysteresis be applied on passing low threshold?. */
private boolean applyLowHysteresis = true;

@Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL)
private volatile Timedata timedata = null;

public ControllerChannelThresholdImpl() {
super(//
OpenemsComponent.ChannelId.values(), //
Expand Down Expand Up @@ -237,24 +248,36 @@ private void off() throws IllegalArgumentException, OpenemsNamedException {
}

/**
* Helper function to switch an output if it was not switched before.
* Helper function to switch an output if it was not switched before; Updates
* the cumulated active time channel.
*
* @param value true to switch ON, false to switch ON; is inverted if
* @param value true to switch ON, false to switch OFF; is inverted if
* 'invertOutput' config is set
* @throws OpenemsNamedException on error
* @throws IllegalArgumentException on error
*/
private void setOutput(boolean value) throws IllegalArgumentException, OpenemsNamedException {
var outputValue = value ^ this.invertOutput;

// Update the cumulated active time.
this.calculateCumulatedActiveTime.update(outputValue);

try {
WriteChannel<Boolean> outputChannel = this.componentManager.getChannel(this.outputChannelAddress);
var currentValueOpt = outputChannel.value().asOptional();
if (!currentValueOpt.isPresent() || currentValueOpt.get() != (value ^ this.invertOutput)) {
this.logInfo(this.log, "Set output [" + outputChannel.address() + "] "
+ (value ^ this.invertOutput ? "ON" : "OFF") + ".");
outputChannel.setNextWriteValue(value ^ this.invertOutput);
if (!currentValueOpt.isPresent() || currentValueOpt.get() != outputValue) {
this.logInfo(this.log,
"Set output [" + outputChannel.address() + "] " + (outputValue ? "ON" : "OFF") + ".");
outputChannel.setNextWriteValue(outputValue);
}

} catch (OpenemsException e) {
this.logError(this.log, "Unable to set output: [" + this.outputChannelAddress + "] " + e.getMessage());
}
}

@Override
public Timedata getTimedata() {
return this.timedata;
}
}
3 changes: 2 additions & 1 deletion io.openems.edge.controller.chp.soc/bnd.bnd
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Bundle-Version: 1.0.0.${tstamp}
io.openems.edge.common,\
io.openems.edge.controller.api,\
io.openems.edge.ess.api,\
io.openems.edge.io.api
io.openems.edge.io.api,\
io.openems.edge.timedata.api,\

-testpath: \
${testpath}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package io.openems.edge.controller.chp.soc;

import static io.openems.common.channel.PersistencePriority.HIGH;
import static io.openems.common.channel.Unit.CUMULATED_SECONDS;
import static io.openems.common.types.OpenemsType.LONG;

import io.openems.edge.common.channel.Doc;
import io.openems.edge.common.component.OpenemsComponent;
import io.openems.edge.controller.api.Controller;
Expand All @@ -11,7 +15,10 @@ public enum ChannelId implements io.openems.edge.common.channel.ChannelId {
.initialValue(Mode.AUTOMATIC) //
.text("Configured Mode")), //
STATE_MACHINE(Doc.of(State.values()) //
.text("Current State of State-Machine"));
.text("Current State of State-Machine")),
CUMULATED_ACTIVE_TIME(Doc.of(LONG)//
.unit(CUMULATED_SECONDS) //
.persistencePriority(HIGH));

private final Doc doc;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
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.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -21,6 +24,9 @@
import io.openems.edge.common.component.OpenemsComponent;
import io.openems.edge.common.type.TypeUtils;
import io.openems.edge.controller.api.Controller;
import io.openems.edge.timedata.api.Timedata;
import io.openems.edge.timedata.api.TimedataProvider;
import io.openems.edge.timedata.api.utils.CalculateActiveTime;

@Designate(ocd = Config.class, factory = true)
@Component(//
Expand All @@ -29,13 +35,18 @@
configurationPolicy = ConfigurationPolicy.REQUIRE //
)
public class ControllerChpSocImpl extends AbstractOpenemsComponent
implements ControllerChpSoc, Controller, OpenemsComponent {
implements ControllerChpSoc, Controller, OpenemsComponent, TimedataProvider {

private final Logger log = LoggerFactory.getLogger(ControllerChpSocImpl.class);
private final CalculateActiveTime cumulatedActiveTime = new CalculateActiveTime(this,
ControllerChpSoc.ChannelId.CUMULATED_ACTIVE_TIME);

@Reference
private ComponentManager componentManager;

@Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL)
private volatile Timedata timedata = null;

private ChannelAddress inputChannelAddress;
private ChannelAddress outputChannelAddress;
private int lowThreshold = 0;
Expand Down Expand Up @@ -174,13 +185,17 @@ private boolean changeState(State nextState) {
}

/**
* Helper function to switch an output if it was not switched before.
* Helper function to switch an output if it was not switched before; Updates
* the cumulated active time channel.
*
* @param value true to switch ON, false to switch OFF;
* @throws OpenemsNamedException on error
* @throws IllegalArgumentException on error
*/
private void setOutput(Boolean value) throws IllegalArgumentException, OpenemsNamedException {
// Update the cumulated time
this.cumulatedActiveTime.update(value);

try {
WriteChannel<Boolean> outputChannel = this.componentManager.getChannel(this.outputChannelAddress);
var currentValueOpt = outputChannel.value().asOptional();
Expand All @@ -206,4 +221,9 @@ private boolean changeMode(Mode nextMode) {
}
return false;
}

@Override
public Timedata getTimedata() {
return this.timedata;
}
}
3 changes: 2 additions & 1 deletion io.openems.edge.controller.ess.fixactivepower/bnd.bnd
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Bundle-Version: 1.0.0.${tstamp}
io.openems.edge.common,\
io.openems.edge.controller.api,\
io.openems.edge.ess.api,\

io.openems.edge.timedata.api,\

-testpath: \
${testpath}
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package io.openems.edge.controller.ess.fixactivepower;

import static io.openems.common.channel.PersistencePriority.HIGH;
import static io.openems.common.channel.Unit.CUMULATED_SECONDS;
import static io.openems.common.types.OpenemsType.LONG;

import io.openems.edge.common.channel.Doc;
import io.openems.edge.common.component.OpenemsComponent;
import io.openems.edge.controller.api.Controller;

public interface ControllerEssFixActivePower extends Controller, OpenemsComponent {

public enum ChannelId implements io.openems.edge.common.channel.ChannelId {
;
CUMULATED_ACTIVE_TIME(Doc.of(LONG)//
.unit(CUMULATED_SECONDS) //
.persistencePriority(HIGH));

private final Doc doc;

private ChannelId(Doc doc) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import io.openems.edge.ess.api.ManagedSymmetricEss;
import io.openems.edge.ess.api.PowerConstraint;
import io.openems.edge.ess.power.api.Pwr;
import io.openems.edge.timedata.api.Timedata;
import io.openems.edge.timedata.api.TimedataProvider;
import io.openems.edge.timedata.api.utils.CalculateActiveTime;

@Designate(ocd = Config.class, factory = true)
@Component(//
Expand All @@ -29,7 +32,10 @@
configurationPolicy = ConfigurationPolicy.REQUIRE //
)
public class ControllerEssFixActivePowerImpl extends AbstractOpenemsComponent
implements ControllerEssFixActivePower, Controller, OpenemsComponent {
implements ControllerEssFixActivePower, Controller, OpenemsComponent, TimedataProvider {

private final CalculateActiveTime calculateCumulatedActiveTime = new CalculateActiveTime(this,
ControllerEssFixActivePower.ChannelId.CUMULATED_ACTIVE_TIME);

@Reference
private ConfigurationAdmin cm;
Expand All @@ -39,6 +45,9 @@ public class ControllerEssFixActivePowerImpl extends AbstractOpenemsComponent

private Config config;

@Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL)
private volatile Timedata timedata = null;

public ControllerEssFixActivePowerImpl() {
super(//
OpenemsComponent.ChannelId.values(), //
Expand Down Expand Up @@ -76,17 +85,25 @@ protected void deactivate() {

@Override
public void run() throws OpenemsNamedException {
switch (this.config.mode()) {
case MANUAL_ON:
// Apply Active-Power Set-Point
var acPower = getAcPower(this.ess, this.config.hybridEssMode(), this.config.power());
PowerConstraint.apply(this.ess, this.id(), //
this.config.phase(), Pwr.ACTIVE, this.config.relationship(), acPower);
break;

case MANUAL_OFF:
// Do nothing
break;
var isActive = false;
try {
isActive = switch (this.config.mode()) {
case MANUAL_ON -> {
// Apply Active-Power Set-Point
var acPower = getAcPower(this.ess, this.config.hybridEssMode(), this.config.power());
PowerConstraint.apply(this.ess, this.id(), //
this.config.phase(), Pwr.ACTIVE, this.config.relationship(), acPower);
yield true; // is active
}

case MANUAL_OFF -> {
// Do nothing
yield false; // is not active
}
};

} finally {
this.calculateCumulatedActiveTime.update(isActive);
}
}

Expand Down Expand Up @@ -115,4 +132,9 @@ protected static Integer getAcPower(ManagedSymmetricEss ess, HybridEssMode hybri

return null; /* should never happen */
}

@Override
public Timedata getTimedata() {
return this.timedata;
}
}
3 changes: 2 additions & 1 deletion io.openems.edge.controller.io.channelsinglethreshold/bnd.bnd
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Bundle-Version: 1.0.0.${tstamp}
io.openems.edge.common,\
io.openems.edge.controller.api,\
io.openems.edge.ess.api,\
io.openems.edge.io.api
io.openems.edge.io.api,\
io.openems.edge.timedata.api,\

-testpath: \
${testpath}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package io.openems.edge.controller.io.channelsinglethreshold;

import static io.openems.common.channel.PersistencePriority.HIGH;
import static io.openems.common.channel.Unit.CUMULATED_SECONDS;
import static io.openems.common.types.OpenemsType.LONG;

import io.openems.common.channel.Level;
import io.openems.edge.common.channel.Doc;
import io.openems.edge.common.channel.StateChannel;
Expand All @@ -11,7 +15,12 @@ public interface ControllerIoChannelSingleThreshold extends Controller, OpenemsC

public enum ChannelId implements io.openems.edge.common.channel.ChannelId {
AWAITING_HYSTERESIS(Doc.of(Level.INFO) //
.text("Would change State, but hystesis is active")); //
.text("Would change State, but hystesis is active")),

CUMULATED_ACTIVE_TIME(Doc.of(LONG)//
.unit(CUMULATED_SECONDS) //
.persistencePriority(HIGH)) //
; //

private final Doc doc;

Expand Down
Loading

0 comments on commit 13d98bb

Please sign in to comment.