Skip to content

Commit 59c6f62

Browse files
[Edge] EnergyScheduler: Add generations counter
- EnergyScheduler: Add channel which tracks the number of generations per quarter Reviewed-by: Stefan Feilmeier <[email protected]> Co-authored-by: Leonhard Anderle <[email protected]> Co-committed-by: Leonhard Anderle <[email protected]>
1 parent babf993 commit 59c6f62

File tree

9 files changed

+59
-19
lines changed

9 files changed

+59
-19
lines changed

io.openems.edge.energy.api/src/io/openems/edge/energy/api/EnergyScheduler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ public interface EnergyScheduler extends OpenemsComponent {
1616
public static final String SINGLETON_COMPONENT_ID = "_energy";
1717

1818
public enum ChannelId implements io.openems.edge.common.channel.ChannelId {
19-
SIMULATIONS_PER_QUARTER(Doc.of(OpenemsType.INTEGER));
19+
SIMULATIONS_PER_QUARTER(Doc.of(OpenemsType.INTEGER)), //
20+
GENERATIONS_PER_QUARTER(Doc.of(OpenemsType.INTEGER)), //
21+
;
2022

2123
private final Doc doc;
2224

io.openems.edge.energy/src/io/openems/edge/energy/EnergySchedulerImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ public EnergySchedulerImpl() {
150150
.setTimeOfUseTariff(this.timeOfUseTariff) //
151151
.build();
152152
}, //
153-
this.channel(EnergyScheduler.ChannelId.SIMULATIONS_PER_QUARTER));
153+
this.channel(EnergyScheduler.ChannelId.SIMULATIONS_PER_QUARTER), //
154+
this.channel(EnergyScheduler.ChannelId.GENERATIONS_PER_QUARTER));
154155
}
155156

156157
@Activate

io.openems.edge.energy/src/io/openems/edge/energy/optimizer/Optimizer.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public class Optimizer {
4949
private final Supplier<LogVerbosity> logVerbosity;
5050
private final Supplier<GlobalOptimizationContext> gocSupplier;
5151
private final Channel<Integer> simulationsPerQuarterChannel;
52+
private final Channel<Integer> generationsPerQuarterChannel;
5253

5354
private final AtomicReference<Simulator> simulator = new AtomicReference<>(null);
5455
private final AtomicReference<SimulationResult> simulationResult = new AtomicReference<>(EMPTY_SIMULATION_RESULT);
@@ -60,10 +61,12 @@ public class Optimizer {
6061
public Optimizer(//
6162
Supplier<LogVerbosity> logVerbosity, //
6263
Supplier<GlobalOptimizationContext> gocSupplier, //
63-
Channel<Integer> simulationsPerQuarterChannel) {
64+
Channel<Integer> simulationsPerQuarterChannel, //
65+
Channel<Integer> generationsPerQuarterChannel) {
6466
this.logVerbosity = logVerbosity;
6567
this.gocSupplier = gocSupplier;
6668
this.simulationsPerQuarterChannel = simulationsPerQuarterChannel;
69+
this.generationsPerQuarterChannel = generationsPerQuarterChannel;
6770
initializeRandomRegistryForProduction();
6871
}
6972

@@ -238,6 +241,7 @@ protected void applySimulationResult(SimulationResult simulationResult) {
238241
Optional.ofNullable(this.simulator.get()).ifPresent(s -> {
239242
logSimulationResult(s, simulationResult);
240243
this.simulationsPerQuarterChannel.setNextValue(s.getTotalNumberOfSimulations());
244+
this.generationsPerQuarterChannel.setNextValue(s.getTotalNumberOfGenerations());
241245
});
242246

243247
this.simulationResult.set(simulationResult);
@@ -292,6 +296,7 @@ public String debugLog() {
292296
b.append("ScheduledPeriods:").append(currentResult.periods().size());
293297
}
294298
b.append("|SimulationsPerQuarter:").append(this.simulationsPerQuarterChannel.value());
299+
b.append("|GenerationsPerQuarter:").append(this.generationsPerQuarterChannel.value());
295300
Optional.ofNullable(this.simulator.get()).ifPresent(simulator -> {
296301
b.append("|Current:").append(simulator.getTotalNumberOfSimulations());
297302
});

io.openems.edge.energy/src/io/openems/edge/energy/optimizer/SimulationResult.java

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ public record SimulationResult(//
3333
? extends EnergyScheduleHandler.WithDifferentModes, //
3434
ImmutableSortedMap<ZonedDateTime, DifferentModes.Period.Transition>> schedules, //
3535
ImmutableSet<? extends EnergyScheduleHandler.WithOnlyOneMode> eshsWithOnlyOneMode, //
36-
int simulationsCounter) {
36+
int simulationsCounter, //
37+
int generationsCounter) {
3738

3839
/**
3940
* A Period in a {@link SimulationResult}. Duration of one period is always one
@@ -65,7 +66,7 @@ public static Period from(GlobalOptimizationContext.Period gocPeriod, ModeCombin
6566
* An empty {@link SimulationResult}.
6667
*/
6768
public static final SimulationResult EMPTY_SIMULATION_RESULT = new SimulationResult(new Fitness(), //
68-
ImmutableSortedMap.of(), ImmutableMap.of(), ImmutableSet.of(), 0);
69+
ImmutableSortedMap.of(), ImmutableMap.of(), ImmutableSet.of(), 0, 0);
6970

7071
/**
7172
* Re-Simulate a {@link Genotype} to create a {@link SimulationResult}.
@@ -74,9 +75,14 @@ public static Period from(GlobalOptimizationContext.Period gocPeriod, ModeCombin
7475
* @param goc the {@link GlobalOptimizationContext}
7576
* @param schedule the schedule as defined by {@link EshCodec}
7677
* @param simulationsCounter the total number of simulations
78+
* @param generationsCounter the total number of generations
7779
* @return the {@link SimulationResult}
7880
*/
79-
private static SimulationResult from(GlobalOptimizationContext goc, int[] schedule, int simulationsCounter) {
81+
private static SimulationResult from(//
82+
GlobalOptimizationContext goc, //
83+
int[] schedule, //
84+
int simulationsCounter, //
85+
int generationsCounter) {
8086
var allPeriods = ImmutableSortedMap.<ZonedDateTime, Period>naturalOrder();
8187
var allEshToModes = new ArrayList<EshToMode>();
8288
var fitness = Simulator.simulate(goc, ModeCombinations.fromGlobalOptimizationContext(goc), schedule,
@@ -105,7 +111,13 @@ private static SimulationResult from(GlobalOptimizationContext goc, int[] schedu
105111
.map(EnergyScheduleHandler.WithOnlyOneMode.class::cast) //
106112
.collect(toImmutableSet());
107113

108-
return new SimulationResult(fitness, allPeriods.build(), schedules, eshsWithOnlyOneMode, simulationsCounter);
114+
return new SimulationResult(//
115+
fitness, //
116+
allPeriods.build(), //
117+
schedules, //
118+
eshsWithOnlyOneMode, //
119+
simulationsCounter, //
120+
generationsCounter);
109121
}
110122

111123
/**
@@ -118,9 +130,14 @@ private static SimulationResult from(GlobalOptimizationContext goc, int[] schedu
118130
* @param goc the {@link GlobalOptimizationContext}
119131
* @param schedule the schedule as defined by {@link EshCodec}
120132
* @param simulationsCounter the total number of simulations
133+
* @param generationsCounter the total number of generations
121134
* @return the {@link SimulationResult}
122135
*/
123-
public static SimulationResult fromQuarters(GlobalOptimizationContext goc, int[] schedule, int simulationsCounter) {
136+
public static SimulationResult fromQuarters(//
137+
GlobalOptimizationContext goc, //
138+
int[] schedule, //
139+
int simulationsCounter, //
140+
int generationsCounter) {
124141
if (goc == null || schedule.length == 0) {
125142
return EMPTY_SIMULATION_RESULT;
126143
}
@@ -149,7 +166,7 @@ public static SimulationResult fromQuarters(GlobalOptimizationContext goc, int[]
149166
// TODO use default index
150167
.toArray();
151168

152-
return from(quarterGoc, quarterSchedule, simulationsCounter);
169+
return from(quarterGoc, quarterSchedule, simulationsCounter, generationsCounter);
153170
}
154171

155172
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
@@ -196,8 +213,10 @@ public String toLogString(String prefix) {
196213
});
197214
b.append("\n");
198215
});
199-
b.append(prefix).append("totalNumberOfSimulations=").append(this.simulationsCounter).append(";fitness=")
200-
.append(this.fitness);
216+
b.append(prefix)//
217+
.append("totalNumberOfSimulations=").append(this.simulationsCounter)//
218+
.append(";totalNumberOfGenerations=").append(this.generationsCounter)//
219+
.append(";fitness=").append(this.fitness);
201220
return b.toString();
202221
}
203222
}

io.openems.edge.energy/src/io/openems/edge/energy/optimizer/Simulator.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.util.concurrent.Executor;
1313
import java.util.concurrent.ForkJoinPool;
1414
import java.util.concurrent.atomic.AtomicInteger;
15+
import java.util.concurrent.atomic.AtomicLong;
1516
import java.util.function.Consumer;
1617
import java.util.function.Function;
1718

@@ -50,6 +51,7 @@ public class Simulator {
5051
public final ModeCombinations modeCombinations;
5152

5253
private final AtomicInteger simulationsCounter = new AtomicInteger(0);
54+
private final AtomicLong generationsCounter = new AtomicLong(0);
5355

5456
public Simulator(GlobalOptimizationContext goc) {
5557
this.goc = goc;
@@ -65,6 +67,10 @@ protected int getTotalNumberOfSimulations() {
6567
return this.simulationsCounter.get();
6668
}
6769

70+
protected int getTotalNumberOfGenerations() {
71+
return (int) this.generationsCounter.get();
72+
}
73+
6874
protected static Fitness simulate(GlobalOptimizationContext goc, ModeCombinations modeCombinations, int[] schedule,
6975
BestScheduleCollector bestScheduleCollector) {
7076
final var gsc = GlobalScheduleContext.from(goc);
@@ -268,11 +274,16 @@ public SimulationResult getBestSchedule(//
268274

269275
// Start the evaluation
270276
var bestGt = stream //
277+
.peek(er -> this.generationsCounter.set(er.generation()))//
271278
.collect(toBestResult(codec));
272279
if (bestGt == null) {
273280
return EMPTY_SIMULATION_RESULT;
274281
}
275-
return SimulationResult.fromQuarters(this.goc, bestGt, this.simulationsCounter.get());
282+
return SimulationResult.fromQuarters(//
283+
this.goc, //
284+
bestGt, //
285+
this.getTotalNumberOfSimulations(), //
286+
this.getTotalNumberOfGenerations());
276287
}
277288

278289
protected static record BestScheduleCollector(//

io.openems.edge.energy/test/io/openems/edge/energy/optimizer/EshCodecTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void testPreviousResult() {
2929
final var simulator = DUMMY_SIMULATOR;
3030
final var goc = simulator.goc;
3131
final var mc = simulator.modeCombinations;
32-
final var previousResult = SimulationResult.fromQuarters(goc, new int[] { 3, 1, 1, 1 }, 0);
32+
final var previousResult = SimulationResult.fromQuarters(goc, new int[] { 3, 1, 1, 1 }, 0, 0);
3333

3434
final var codec = EshCodec.of(goc, mc, previousResult, true);
3535

io.openems.edge.energy/test/io/openems/edge/energy/optimizer/OptimizerTest.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ public class OptimizerTest {
2727
public void testRunQuickOptimization() throws Exception {
2828
var sut = EnergySchedulerImplTest.create(createDummyClock());
2929
var optimizer = getOptimizer(sut);
30-
assertEquals("No Schedule available|SimulationsPerQuarter:UNDEFINED", optimizer.debugLog());
30+
assertEquals("No Schedule available|SimulationsPerQuarter:UNDEFINED|GenerationsPerQuarter:UNDEFINED", optimizer.debugLog());
3131

3232
var simulationResult = optimizer.runQuickOptimization();
3333
optimizer.applySimulationResult(simulationResult);
34-
assertTrue(optimizer.debugLog().startsWith("ScheduledPeriods:96|SimulationsPerQuarter:UNDEFINED|Current:"));
34+
assertTrue(optimizer.debugLog().startsWith("ScheduledPeriods:96|SimulationsPerQuarter:UNDEFINED|GenerationsPerQuarter:UNDEFINED|Current:"));
3535

3636
var sr = optimizer.getSimulationResult();
3737
assertTrue(sr.fitness().getGridBuyCost() < 1100000);
@@ -41,11 +41,13 @@ public void testRunQuickOptimization() throws Exception {
4141
@Test
4242
public void test2() throws InterruptedException, ExecutionException {
4343
var simulator = SimulatorTest.DUMMY_SIMULATOR;
44-
var channel = DummyChannel.of("DummyChannel");
44+
var channel1 = DummyChannel.of("DummyChannel1");
45+
var channel2 = DummyChannel.of("DummyChannel2");
4546
var optimizer = new Optimizer(//
4647
() -> LogVerbosity.NONE, //
4748
() -> simulator.goc, //
48-
channel);
49+
channel1, //
50+
channel2);
4951
var simulationResult = optimizer.runQuickOptimization();
5052
optimizer.applySimulationResult(simulationResult);
5153

io.openems.edge.energy/test/io/openems/edge/energy/optimizer/SimulationResultTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void test() {
3636
m00, m00, m00, m00, m00, m00, m00, m00, m00, m11, m21, //
3737
m00, m00, m00, m00, m00, m00, m00, m00, m00, m00, m00, //
3838
m00, m11, m20 //
39-
}, 0);
39+
}, 0, 0);
4040

4141
assertEquals(1165082.1, result.fitness().getGridBuyCost(), 0.1);
4242
}

io.openems.edge.energy/test/io/openems/edge/energy/optimizer/SimulatorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ protected static enum Esh2State {
7373
public static final Simulator DUMMY_SIMULATOR = new Simulator(GOC);
7474

7575
public static final SimulationResult DUMMY_PREVIOUS_RESULT = SimulationResult.fromQuarters(GOC,
76-
new int[] { 3, 2, 1 }, 0);
76+
new int[] { 3, 2, 1 }, 0, 0);
7777

7878
@Before
7979
public void before() {

0 commit comments

Comments
 (0)