From 92ec5875d9ce36f22ead4955026c0f89da51d66e Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Wed, 16 Mar 2022 16:06:41 +0100 Subject: [PATCH] Controller IO HeatingElement: add cumulated active time (#208) Add cummulated time channels & update them depending on the current level. Use this channels in the UI history. Co-authored-by: Sebastian Asen Co-authored-by: Lukas Rieger Co-authored-by: Maximilian Lang Co-authored-by: Stefan Feilmeier --- .../bnd.bnd | 1 + .../controller/io/heatingelement/Config.java | 4 + .../ControllerHeatingElement.java | 60 +++++++++----- .../ControllerHeatingElementImpl.java | 79 +++++++++++++++++-- .../controller/io/heatingelement/Mode.java | 5 -- .../controller/io/heatingelement/Phase.java | 5 -- .../io/heatingelement/PhaseDef.java | 15 ++-- .../io/heatingelement/{ => enums}/Level.java | 2 +- .../io/heatingelement/enums/Mode.java | 5 ++ .../io/heatingelement/enums/Phase.java | 5 ++ .../heatingelement/{ => enums}/WorkMode.java | 3 +- .../io/heatingelement/HeatingElementTest.java | 23 +++--- .../heatingelement/HeatingElementTest2.java | 19 +++-- .../HeatingElementTestManual.java | 13 +-- .../io/heatingelement/MyConfig.java | 8 ++ .../heatingelement/widget.component.ts | 68 ++++------------ 16 files changed, 191 insertions(+), 124 deletions(-) delete mode 100644 io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Mode.java delete mode 100644 io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Phase.java rename io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/{ => enums}/Level.java (94%) create mode 100644 io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/Mode.java create mode 100644 io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/Phase.java rename io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/{ => enums}/WorkMode.java (73%) diff --git a/io.openems.edge.controller.io.heatingelement/bnd.bnd b/io.openems.edge.controller.io.heatingelement/bnd.bnd index c02edf3f0a6..3eb346d67d6 100644 --- a/io.openems.edge.controller.io.heatingelement/bnd.bnd +++ b/io.openems.edge.controller.io.heatingelement/bnd.bnd @@ -10,6 +10,7 @@ Bundle-Version: 1.0.0.${tstamp} io.openems.edge.controller.api,\ io.openems.edge.ess.api,\ io.openems.edge.io.api,\ + io.openems.edge.timedata.api,\ -testpath: \ ${testpath} \ No newline at end of file diff --git a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Config.java b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Config.java index 835adb26a75..3d4f949d249 100644 --- a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Config.java +++ b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Config.java @@ -3,6 +3,10 @@ import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.ObjectClassDefinition; +import io.openems.edge.controller.io.heatingelement.enums.Level; +import io.openems.edge.controller.io.heatingelement.enums.Mode; +import io.openems.edge.controller.io.heatingelement.enums.WorkMode; + @ObjectClassDefinition(// name = "Controller IO Heating Element", // description = "Controls a three-phase heating element via Relays, according to grid active power") diff --git a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/ControllerHeatingElement.java b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/ControllerHeatingElement.java index a6374ee1a91..d46f21f74f9 100644 --- a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/ControllerHeatingElement.java +++ b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/ControllerHeatingElement.java @@ -1,31 +1,53 @@ package io.openems.edge.controller.io.heatingelement; -import io.openems.common.channel.Unit; -import io.openems.common.types.OpenemsType; +import static io.openems.common.channel.PersistencePriority.HIGH; +import static io.openems.common.channel.Unit.CUMULATED_SECONDS; +import static io.openems.common.channel.Unit.SECONDS; +import static io.openems.common.types.OpenemsType.INTEGER; +import static io.openems.common.types.OpenemsType.LONG; + import io.openems.edge.common.channel.Doc; +import io.openems.edge.controller.io.heatingelement.enums.Level; public interface ControllerHeatingElement { public enum ChannelId implements io.openems.edge.common.channel.ChannelId { LEVEL(Doc.of(Level.values()) // .text("Current Level")), - AWAITING_HYSTERESIS(Doc.of(OpenemsType.INTEGER)), // - PHASE1_TIME(Doc.of(OpenemsType.INTEGER)// - .unit(Unit.SECONDS)), // - PHASE2_TIME(Doc.of(OpenemsType.INTEGER)// - .unit(Unit.SECONDS)), // - PHASE3_TIME(Doc.of(OpenemsType.INTEGER)// - .unit(Unit.SECONDS)), // - LEVEL1_TIME(Doc.of(OpenemsType.INTEGER)// - .unit(Unit.SECONDS)), // - LEVEL2_TIME(Doc.of(OpenemsType.INTEGER)// - .unit(Unit.SECONDS)), // - LEVEL3_TIME(Doc.of(OpenemsType.INTEGER)// - .unit(Unit.SECONDS)), // - TOTAL_PHASE_TIME(Doc.of(OpenemsType.INTEGER)// - .unit(Unit.SECONDS)), // - FORCE_START_AT_SECONDS_OF_DAY(Doc.of(OpenemsType.INTEGER)// - .unit(Unit.SECONDS)); // + AWAITING_HYSTERESIS(Doc.of(INTEGER)), // + PHASE1_TIME(Doc.of(INTEGER)// + .unit(SECONDS)), // + PHASE2_TIME(Doc.of(INTEGER)// + .unit(SECONDS)), // + PHASE3_TIME(Doc.of(INTEGER)// + .unit(SECONDS)), // + /* + * LEVELx_TIME was used for old history view. It is left for the analysis of the + * forced duration on a day. + */ + LEVEL1_TIME(Doc.of(INTEGER)// + .unit(SECONDS)), // + LEVEL2_TIME(Doc.of(INTEGER)// + .unit(SECONDS)), // + LEVEL3_TIME(Doc.of(INTEGER)// + .unit(SECONDS)), // + + /* + * Total active Time of each Level. + */ + LEVEL1_CUMULATED_TIME(Doc.of(LONG)// + .unit(CUMULATED_SECONDS) // + .persistencePriority(HIGH)), // + LEVEL2_CUMULATED_TIME(Doc.of(LONG)// + .unit(CUMULATED_SECONDS) // + .persistencePriority(HIGH)), // + LEVEL3_CUMULATED_TIME(Doc.of(LONG)// + .unit(CUMULATED_SECONDS) // + .persistencePriority(HIGH)), // + TOTAL_PHASE_TIME(Doc.of(INTEGER)// + .unit(SECONDS)), // + FORCE_START_AT_SECONDS_OF_DAY(Doc.of(INTEGER)// + .unit(SECONDS)); // private final Doc doc; diff --git a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/ControllerHeatingElementImpl.java b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/ControllerHeatingElementImpl.java index 1d9814e8015..efbeee5e3cd 100644 --- a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/ControllerHeatingElementImpl.java +++ b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/ControllerHeatingElementImpl.java @@ -11,6 +11,9 @@ 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.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; @@ -24,6 +27,12 @@ import io.openems.edge.common.component.OpenemsComponent; import io.openems.edge.common.sum.Sum; import io.openems.edge.controller.api.Controller; +import io.openems.edge.controller.io.heatingelement.enums.Level; +import io.openems.edge.controller.io.heatingelement.enums.Phase; +import io.openems.edge.controller.io.heatingelement.enums.WorkMode; +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(name = "Controller.IO.HeatingElement", // @@ -31,14 +40,33 @@ configurationPolicy = ConfigurationPolicy.REQUIRE // ) public class ControllerHeatingElementImpl extends AbstractOpenemsComponent - implements ControllerHeatingElement, Controller, OpenemsComponent { + implements ControllerHeatingElement, Controller, OpenemsComponent, TimedataProvider { private final Logger log = LoggerFactory.getLogger(ControllerHeatingElementImpl.class); + /** + * Definitions for each phase. + */ private final PhaseDef phase1; private final PhaseDef phase2; private final PhaseDef phase3; + /** + * Cumulated active time for each level. + */ + private final CalculateActiveTime totalTimeLevel1 = new CalculateActiveTime(this, + ControllerHeatingElement.ChannelId.LEVEL1_CUMULATED_TIME); + private final CalculateActiveTime totalTimeLevel2 = new CalculateActiveTime(this, + ControllerHeatingElement.ChannelId.LEVEL2_CUMULATED_TIME); + private final CalculateActiveTime totalTimeLevel3 = new CalculateActiveTime(this, + ControllerHeatingElement.ChannelId.LEVEL3_CUMULATED_TIME); + + // Current Level + private Level currentLevel = Level.UNDEFINED; + + // Last Level change time, used for the hysteresis + private LocalDateTime lastLevelChange = LocalDateTime.MIN; + private Config config; /** @@ -52,6 +80,9 @@ public class ControllerHeatingElementImpl extends AbstractOpenemsComponent @Reference protected Sum sum; + @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL) + private volatile Timedata timedata = null; + public ControllerHeatingElementImpl() throws OpenemsNamedException { super(// OpenemsComponent.ChannelId.values(), // @@ -118,6 +149,8 @@ public void run() throws OpenemsNamedException { this.channel(ControllerHeatingElement.ChannelId.LEVEL1_TIME).setNextValue(phase1Time - phase2Time); this.channel(ControllerHeatingElement.ChannelId.LEVEL2_TIME).setNextValue(phase2Time - phase3Time); this.channel(ControllerHeatingElement.ChannelId.LEVEL3_TIME).setNextValue(phase3Time); + + this.updateCumulatedActiveTime(); } /** @@ -195,7 +228,6 @@ protected void modeAutomatic() throws IllegalArgumentException, OpenemsNamedExce // Apply Level this.applyLevel(targetLevel); - } /** @@ -212,6 +244,7 @@ protected void modeAutomatic() throws IllegalArgumentException, OpenemsNamedExce *
  • in {@link WorkMode#NONE}: always return 0 * * + * @param config the component {@link Config} * @return the minimum total phase time [s] */ private static long calculateMinimumTotalPhaseTime(Config config) { @@ -276,6 +309,7 @@ private LocalTime calculateLatestForceHeatingStartTime() { public void applyLevel(Level level) throws IllegalArgumentException, OpenemsNamedException { // Update Channel this.channel(ControllerHeatingElement.ChannelId.LEVEL).setNextValue(level); + this.currentLevel = level; // Set phases accordingly switch (level) { @@ -330,9 +364,6 @@ private Level applyHysteresis(Level targetLevel) { return this.currentLevel; } - private Level currentLevel = Level.UNDEFINED; - private LocalDateTime lastLevelChange = LocalDateTime.MIN; - /** * Gets the configured Power-per-Phase in [W]. * @@ -345,9 +376,8 @@ protected int getPowerPerPhase() { /** * Helper function to switch an output if it was not switched before. * - * @param value The boolean value which must set on the output - * channel address. - * @param outputChannelAddress The address of the channel. + * @param phase {@link Phase} + * @param value The boolean value which must set on the output channel address. * @throws OpenemsNamedException on error. * @throws IllegalArgumentException on error. */ @@ -380,4 +410,37 @@ private ChannelAddress getChannelAddressForPhase(Phase phase) throws OpenemsName assert true; // can never happen return null; } + + /** + * Update the total time of the level depending on the current level. + */ + private void updateCumulatedActiveTime() { + var level1Active = false; + var level2Active = false; + var level3Active = false; + + switch (this.currentLevel) { + case LEVEL_0: + case UNDEFINED: + break; + case LEVEL_1: + level1Active = true; + break; + case LEVEL_2: + level2Active = true; + break; + case LEVEL_3: + level3Active = true; + break; + } + + this.totalTimeLevel1.update(level1Active); + this.totalTimeLevel2.update(level2Active); + this.totalTimeLevel3.update(level3Active); + } + + @Override + public Timedata getTimedata() { + return this.timedata; + } } \ No newline at end of file diff --git a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Mode.java b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Mode.java deleted file mode 100644 index 34309d28d8a..00000000000 --- a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Mode.java +++ /dev/null @@ -1,5 +0,0 @@ -package io.openems.edge.controller.io.heatingelement; - -public enum Mode { - MANUAL_ON, MANUAL_OFF, AUTOMATIC; -} diff --git a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Phase.java b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Phase.java deleted file mode 100644 index 19098ed6ce5..00000000000 --- a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Phase.java +++ /dev/null @@ -1,5 +0,0 @@ -package io.openems.edge.controller.io.heatingelement; - -public enum Phase { - L1, L2, L3 -} diff --git a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/PhaseDef.java b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/PhaseDef.java index d60733f25ab..40be10ff764 100644 --- a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/PhaseDef.java +++ b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/PhaseDef.java @@ -5,6 +5,7 @@ import java.time.LocalTime; import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.controller.io.heatingelement.enums.Phase; /** * PhaseDef represents one Phase of the Heating Element. @@ -23,7 +24,7 @@ public class PhaseDef { * keeps the total summed up Duration of the current day; it is updated on * switchOff() and reset after midnight by getTotalDuration(). */ - private Duration duration = Duration.ZERO; + private Duration dailyDuration = Duration.ZERO; /** * Keeps the current day to detect changes in day. @@ -43,8 +44,6 @@ public PhaseDef(ControllerHeatingElementImpl parent, Phase phase) { /** * Switch the output ON. * - * @param outputChannelAddress address of the channel which must set to ON - * * @throws OpenemsNamedException on error. * @throws IllegalArgumentException on error. */ @@ -59,14 +58,12 @@ protected void switchOn() throws IllegalArgumentException, OpenemsNamedException /** * Switch the output OFF. * - * @param outputChannelAddress address of the channel which must set to OFF. - * * @throws OpenemsNamedException on error. * @throws IllegalArgumentException on error. */ protected void switchOff() throws IllegalArgumentException, OpenemsNamedException { if (this.lastSwitchOn != null) { - this.duration = this.getTotalDuration(); + this.dailyDuration = this.getTotalDuration(); this.lastSwitchOn = null; } @@ -85,7 +82,7 @@ public Duration getTotalDuration() { if (!this.currentDay.equals(today)) { // Always reset Duration this.currentDay = today; - this.duration = Duration.ZERO; + this.dailyDuration = Duration.ZERO; if (this.lastSwitchOn != null) { this.lastSwitchOn = LocalTime.MIN; } @@ -94,8 +91,8 @@ public Duration getTotalDuration() { // Calculate and return the Duration if (this.lastSwitchOn != null) { var now = LocalTime.now(this.parent.componentManager.getClock()); - return this.duration.plus(Duration.between(this.lastSwitchOn, now)); + return this.dailyDuration.plus(Duration.between(this.lastSwitchOn, now)); } - return this.duration; + return this.dailyDuration; } } diff --git a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Level.java b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/Level.java similarity index 94% rename from io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Level.java rename to io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/Level.java index ecc7eaa0358..6f2445f2767 100644 --- a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/Level.java +++ b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/Level.java @@ -1,4 +1,4 @@ -package io.openems.edge.controller.io.heatingelement; +package io.openems.edge.controller.io.heatingelement.enums; import io.openems.common.types.OptionsEnum; diff --git a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/Mode.java b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/Mode.java new file mode 100644 index 00000000000..94d9da39384 --- /dev/null +++ b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/Mode.java @@ -0,0 +1,5 @@ +package io.openems.edge.controller.io.heatingelement.enums; + +public enum Mode { + MANUAL_ON, MANUAL_OFF, AUTOMATIC; +} diff --git a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/Phase.java b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/Phase.java new file mode 100644 index 00000000000..4ee1a5ce357 --- /dev/null +++ b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/Phase.java @@ -0,0 +1,5 @@ +package io.openems.edge.controller.io.heatingelement.enums; + +public enum Phase { + L1, L2, L3 +} diff --git a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/WorkMode.java b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/WorkMode.java similarity index 73% rename from io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/WorkMode.java rename to io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/WorkMode.java index 0725cd89c9e..f03735c50dd 100644 --- a/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/WorkMode.java +++ b/io.openems.edge.controller.io.heatingelement/src/io/openems/edge/controller/io/heatingelement/enums/WorkMode.java @@ -1,5 +1,4 @@ - -package io.openems.edge.controller.io.heatingelement; +package io.openems.edge.controller.io.heatingelement.enums; public enum WorkMode { /** diff --git a/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTest.java b/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTest.java index de130ce35f7..be6d1def228 100644 --- a/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTest.java +++ b/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTest.java @@ -11,23 +11,26 @@ import io.openems.edge.common.test.AbstractComponentTest.TestCase; import io.openems.edge.common.test.DummyComponentManager; import io.openems.edge.common.test.TimeLeapClock; +import io.openems.edge.controller.io.heatingelement.enums.Level; +import io.openems.edge.controller.io.heatingelement.enums.Mode; +import io.openems.edge.controller.io.heatingelement.enums.WorkMode; import io.openems.edge.controller.test.ControllerTest; import io.openems.edge.io.test.DummyInputOutput; public class HeatingElementTest { - private final static String CTRL_ID = "ctrl0"; - private final static String IO_ID = "io0"; + private static final String CTRL_ID = "ctrl0"; + private static final String IO_ID = "io0"; - private final static ChannelAddress SUM_GRID_ACTIVE_POWER = new ChannelAddress("_sum", "GridActivePower"); + private static final ChannelAddress SUM_GRID_ACTIVE_POWER = new ChannelAddress("_sum", "GridActivePower"); - private final static ChannelAddress IO_OUTPUT1 = new ChannelAddress(IO_ID, "InputOutput1"); - private final static ChannelAddress IO_OUTPUT2 = new ChannelAddress(IO_ID, "InputOutput2"); - private final static ChannelAddress IO_OUTPUT3 = new ChannelAddress(IO_ID, "InputOutput3"); + private static final ChannelAddress IO_OUTPUT1 = new ChannelAddress(IO_ID, "InputOutput1"); + private static final ChannelAddress IO_OUTPUT2 = new ChannelAddress(IO_ID, "InputOutput2"); + private static final ChannelAddress IO_OUTPUT3 = new ChannelAddress(IO_ID, "InputOutput3"); - private final static ChannelAddress CTRL_PHASE1TIME = new ChannelAddress(CTRL_ID, "Phase1Time"); - private final static ChannelAddress CTRL_PHASE2TIME = new ChannelAddress(CTRL_ID, "Phase2Time"); - private final static ChannelAddress CTRL_PHASE3TIME = new ChannelAddress(CTRL_ID, "Phase3Time"); + private static final ChannelAddress CTRL_PHASE1TIME = new ChannelAddress(CTRL_ID, "Phase1Time"); + private static final ChannelAddress CTRL_PHASE2TIME = new ChannelAddress(CTRL_ID, "Phase2Time"); + private static final ChannelAddress CTRL_PHASE3TIME = new ChannelAddress(CTRL_ID, "Phase3Time"); @Test public void test() throws Exception { @@ -51,7 +54,7 @@ public void test() throws Exception { .setMinimumSwitchingTime(60) // .build()) // .next(new TestCase() // - // Grid active power : 0, Excess power : 0, + // Grid active power : 0, Excess power : 0, // from -> UNDEFINED --to--> LEVEL_0, no of relais = 0 .input(SUM_GRID_ACTIVE_POWER, 0) // .output(IO_OUTPUT1, false) // diff --git a/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTest2.java b/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTest2.java index a421000f7f3..480b1e0cb52 100644 --- a/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTest2.java +++ b/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTest2.java @@ -11,23 +11,26 @@ import io.openems.edge.common.test.AbstractComponentTest.TestCase; import io.openems.edge.common.test.DummyComponentManager; import io.openems.edge.common.test.TimeLeapClock; +import io.openems.edge.controller.io.heatingelement.enums.Level; +import io.openems.edge.controller.io.heatingelement.enums.Mode; +import io.openems.edge.controller.io.heatingelement.enums.WorkMode; import io.openems.edge.controller.test.ControllerTest; import io.openems.edge.io.test.DummyInputOutput; public class HeatingElementTest2 { - private final static String CTRL_ID = "ctrl0"; - private final static String IO_ID = "io0"; + private static final String CTRL_ID = "ctrl0"; + private static final String IO_ID = "io0"; - private final static ChannelAddress SUM_GRID_ACTIVE_POWER = new ChannelAddress("_sum", "GridActivePower"); + private static final ChannelAddress SUM_GRID_ACTIVE_POWER = new ChannelAddress("_sum", "GridActivePower"); - private final static ChannelAddress IO_OUTPUT1 = new ChannelAddress(IO_ID, "InputOutput1"); - private final static ChannelAddress IO_OUTPUT2 = new ChannelAddress(IO_ID, "InputOutput2"); - private final static ChannelAddress IO_OUTPUT3 = new ChannelAddress(IO_ID, "InputOutput3"); + private static final ChannelAddress IO_OUTPUT1 = new ChannelAddress(IO_ID, "InputOutput1"); + private static final ChannelAddress IO_OUTPUT2 = new ChannelAddress(IO_ID, "InputOutput2"); + private static final ChannelAddress IO_OUTPUT3 = new ChannelAddress(IO_ID, "InputOutput3"); - private final static ChannelAddress CTRL_FORCE_START_AT_SECONDS_OF_DAY = new ChannelAddress(CTRL_ID, + private static final ChannelAddress CTRL_FORCE_START_AT_SECONDS_OF_DAY = new ChannelAddress(CTRL_ID, "ForceStartAtSecondsOfDay"); - private final static ChannelAddress CTRL_TOTAL_PHASE_TIME = new ChannelAddress(CTRL_ID, "TotalPhaseTime"); + private static final ChannelAddress CTRL_TOTAL_PHASE_TIME = new ChannelAddress(CTRL_ID, "TotalPhaseTime"); @Test public void test() throws Exception { diff --git a/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTestManual.java b/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTestManual.java index d9d7fd1751f..d86327f40dc 100644 --- a/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTestManual.java +++ b/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/HeatingElementTestManual.java @@ -11,17 +11,20 @@ import io.openems.edge.common.test.AbstractComponentTest.TestCase; import io.openems.edge.common.test.DummyComponentManager; import io.openems.edge.common.test.TimeLeapClock; +import io.openems.edge.controller.io.heatingelement.enums.Level; +import io.openems.edge.controller.io.heatingelement.enums.Mode; +import io.openems.edge.controller.io.heatingelement.enums.WorkMode; import io.openems.edge.controller.test.ControllerTest; import io.openems.edge.io.test.DummyInputOutput; public class HeatingElementTestManual { - private final static String CTRL_ID = "ctrl0"; - private final static String IO_ID = "io0"; + private static final String CTRL_ID = "ctrl0"; + private static final String IO_ID = "io0"; - private final static ChannelAddress IO_OUTPUT1 = new ChannelAddress(IO_ID, "InputOutput1"); - private final static ChannelAddress IO_OUTPUT2 = new ChannelAddress(IO_ID, "InputOutput2"); - private final static ChannelAddress IO_OUTPUT3 = new ChannelAddress(IO_ID, "InputOutput3"); + private static final ChannelAddress IO_OUTPUT1 = new ChannelAddress(IO_ID, "InputOutput1"); + private static final ChannelAddress IO_OUTPUT2 = new ChannelAddress(IO_ID, "InputOutput2"); + private static final ChannelAddress IO_OUTPUT3 = new ChannelAddress(IO_ID, "InputOutput3"); private static ControllerTest prepareTest(Mode mode, Level level) throws OpenemsNamedException, Exception { return new ControllerTest(new ControllerHeatingElementImpl()) // diff --git a/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/MyConfig.java b/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/MyConfig.java index 93f923cbcba..e78230d41b9 100644 --- a/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/MyConfig.java +++ b/io.openems.edge.controller.io.heatingelement/test/io/openems/edge/controller/io/heatingelement/MyConfig.java @@ -1,6 +1,9 @@ package io.openems.edge.controller.io.heatingelement; import io.openems.edge.common.test.AbstractComponentConfig; +import io.openems.edge.controller.io.heatingelement.enums.Level; +import io.openems.edge.controller.io.heatingelement.enums.Mode; +import io.openems.edge.controller.io.heatingelement.enums.WorkMode; @SuppressWarnings("all") public class MyConfig extends AbstractComponentConfig implements Config { @@ -82,6 +85,11 @@ public MyConfig build() { } } + /** + * Create a Config builder. + * + * @return a {@link Builder} + */ public static Builder create() { return new Builder(); } diff --git a/ui/src/app/edge/history/heatingelement/widget.component.ts b/ui/src/app/edge/history/heatingelement/widget.component.ts index d86551b7bce..1d4caf876f1 100644 --- a/ui/src/app/edge/history/heatingelement/widget.component.ts +++ b/ui/src/app/edge/history/heatingelement/widget.component.ts @@ -18,9 +18,9 @@ export class HeatingelementWidgetComponent extends AbstractHistoryWidget impleme public component: EdgeConfig.Component = null; - public activeTimeOverPeriodLevel1: number = null; - public activeTimeOverPeriodLevel2: number = null; - public activeTimeOverPeriodLevel3: number = null; + public activeTimeOverPeriodLevel1: number | null = null; + public activeTimeOverPeriodLevel2: number | null = null; + public activeTimeOverPeriodLevel3: number | null = null; public edge: Edge = null; @@ -48,63 +48,27 @@ export class HeatingelementWidgetComponent extends AbstractHistoryWidget impleme this.updateValues(); }; + public getCumulativeValue(channeladdress: string, response: QueryHistoricTimeseriesDataResponse) { + let array = response.result.data[channeladdress]; + let firstValue = array.find(el => el != null) ?? 0; + let lastValue = array.slice().reverse().find(el => el != null) ?? 0; + return lastValue - firstValue + } + protected updateValues() { this.queryHistoricTimeseriesData(this.service.historyPeriod.from, this.service.historyPeriod.to).then(response => { - let result = (response as QueryHistoricTimeseriesDataResponse).result; - - let level1Time = result.data[this.componentId + '/Level1Time']; - let level2Time = result.data[this.componentId + '/Level2Time']; - let level3Time = result.data[this.componentId + '/Level3Time']; - - let lastValueLevel1 = null; - let lastValueLevel2 = null; - let lastValueLevel3 = null; - - let sumLevel1 = 0; - let sumLevel2 = 0; - let sumLevel3 = 0; - - for (let value of level1Time.slice().reverse()) { - if (value == null) { - continue; - } - if (lastValueLevel1 == null || value > lastValueLevel1) { - sumLevel1 += value; - } - lastValueLevel1 = value; - } - this.activeTimeOverPeriodLevel1 = sumLevel1; - - for (let value of level2Time.slice().reverse()) { - if (value == null) { - continue; - } - if (lastValueLevel2 == null || value > lastValueLevel2) { - sumLevel2 += value; - } - lastValueLevel2 = value; - } - this.activeTimeOverPeriodLevel2 = sumLevel2; - - for (let value of level3Time.slice().reverse()) { - if (value == null) { - continue; - } - if (lastValueLevel3 == null || value > lastValueLevel3) { - sumLevel3 += value; - } - lastValueLevel3 = value; - } - this.activeTimeOverPeriodLevel3 = sumLevel3; + this.activeTimeOverPeriodLevel1 = this.getCumulativeValue(this.componentId + '/Level1CumulatedTime', response); + this.activeTimeOverPeriodLevel2 = this.getCumulativeValue(this.componentId + '/Level2CumulatedTime', response); + this.activeTimeOverPeriodLevel3 = this.getCumulativeValue(this.componentId + '/Level3CumulatedTime', response); }); }; protected getChannelAddresses(edge: Edge, config: EdgeConfig): Promise { return new Promise((resolve) => { let channeladdresses = [ - new ChannelAddress(this.componentId, 'Level1Time'), - new ChannelAddress(this.componentId, 'Level2Time'), - new ChannelAddress(this.componentId, 'Level3Time'), + new ChannelAddress(this.componentId, 'Level1CumulatedTime'), + new ChannelAddress(this.componentId, 'Level2CumulatedTime'), + new ChannelAddress(this.componentId, 'Level3CumulatedTime') ]; resolve(channeladdresses); });