From 45dfaf5f5c8d8b17473629d317f34bde39d5c34e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Wed, 16 Oct 2024 14:36:08 +0200 Subject: [PATCH] Series.lastValue + lastDate --- application.properties | 2 +- src/main/java/de/ph87/data/series/Series.java | 14 +++++++++++++- .../java/de/ph87/data/series/SeriesMode.java | 18 +++++++++++++----- .../de/ph87/data/series/SeriesService.java | 6 ++++-- .../series/consumption/ConsumptionService.java | 9 +++++++-- .../data/series/counter/CounterService.java | 7 ++++++- .../data/series/measure/MeasureService.java | 7 ++++++- 7 files changed, 50 insertions(+), 13 deletions(-) diff --git a/application.properties b/application.properties index ddc3400..8ca9a0a 100644 --- a/application.properties +++ b/application.properties @@ -5,4 +5,4 @@ spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password #- -spring.jpa.hibernate.ddl-auto=create +spring.jpa.hibernate.ddl-auto=update diff --git a/src/main/java/de/ph87/data/series/Series.java b/src/main/java/de/ph87/data/series/Series.java index abbdd8b..86bcc6c 100644 --- a/src/main/java/de/ph87/data/series/Series.java +++ b/src/main/java/de/ph87/data/series/Series.java @@ -5,6 +5,7 @@ import jakarta.annotation.Nullable; import jakarta.persistence.*; import lombok.*; +import java.time.ZonedDateTime; import java.util.HashSet; import java.util.Set; @@ -36,14 +37,25 @@ public class Series { @ToString.Exclude private Period period; + @Setter + @NonNull + @Column(nullable = false) + private ZonedDateTime lastDate; + + @Setter + @Column(nullable = false) + private double lastValue; + @NonNull @ElementCollection private Set aliases = new HashSet<>(); - public Series(@NonNull final String name, @NonNull final SeriesMode mode, @NonNull final String unit) { + public Series(@NonNull final String name, @NonNull final SeriesMode mode, @NonNull final ZonedDateTime date, final double value, String unit) { this.name = name; this.mode = mode; this.unit = unit; + this.lastDate = date; + this.lastValue = value; } } diff --git a/src/main/java/de/ph87/data/series/SeriesMode.java b/src/main/java/de/ph87/data/series/SeriesMode.java index e30801a..e82e1bd 100644 --- a/src/main/java/de/ph87/data/series/SeriesMode.java +++ b/src/main/java/de/ph87/data/series/SeriesMode.java @@ -5,21 +5,29 @@ import lombok.NonNull; import java.util.function.BiFunction; public enum SeriesMode { - MEASURE((first, second) -> second - first), - COUNTER((first, second) -> second - first), - INCREASING((first, second) -> second - first), - DECREASING((first, second) -> first - second), + MEASURE((first, second) -> second - first, (last, value) -> value), + COUNTER((first, second) -> second - first, Double::sum), + INCREASING((first, second) -> second - first, (last, value) -> value), + DECREASING((first, second) -> first - second, (last, value) -> value), ; @NonNull private final BiFunction delta; - SeriesMode(@NonNull final BiFunction delta) { + @NonNull + private final BiFunction add; + + SeriesMode(@NonNull final BiFunction delta, @NonNull final BiFunction add) { this.delta = delta; + this.add = add; } public double getDelta(final double first, final double second) { return delta.apply(first, second); } + public double update(final double series, final double value) { + return add.apply(series, value); + } + } diff --git a/src/main/java/de/ph87/data/series/SeriesService.java b/src/main/java/de/ph87/data/series/SeriesService.java index 01fda83..0cafa4f 100644 --- a/src/main/java/de/ph87/data/series/SeriesService.java +++ b/src/main/java/de/ph87/data/series/SeriesService.java @@ -6,6 +6,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.ZonedDateTime; + @Slf4j @Service @Transactional @@ -15,8 +17,8 @@ public class SeriesService { private final SeriesRepository seriesRepository; @NonNull - public Series getOrCreateByName(@NonNull final String name, @NonNull final SeriesMode mode, @NonNull final String unit) { - final Series series = seriesRepository.findByNameOrAliasesContains(name, name).orElseGet(() -> seriesRepository.save(new Series(name, mode, unit))); + public Series getOrCreateByName(@NonNull final String name, @NonNull final SeriesMode mode, @NonNull final ZonedDateTime date, final double value, @NonNull final String unit) { + final Series series = seriesRepository.findByNameOrAliasesContains(name, name).orElseGet(() -> seriesRepository.save(new Series(name, mode, date, value, unit))); if (series.getMode() != mode) { throw new RuntimeException("'mode' argument for getOrCreateByName does not match 'mode' of existing Series: mode=%s, series=%s".formatted(mode, series)); } diff --git a/src/main/java/de/ph87/data/series/consumption/ConsumptionService.java b/src/main/java/de/ph87/data/series/consumption/ConsumptionService.java index 24ce736..b3b2da3 100644 --- a/src/main/java/de/ph87/data/series/consumption/ConsumptionService.java +++ b/src/main/java/de/ph87/data/series/consumption/ConsumptionService.java @@ -31,10 +31,15 @@ public class ConsumptionService { @EventListener(ConsumptionEvent.class) public void onConsumptionEvent(@NonNull final ConsumptionEvent event) { log.debug("Handling ConsumptionEvent: {}", event); - final Series series = seriesService.getOrCreateByName(event.getName(), event.isIncreasing() ? SeriesMode.INCREASING : SeriesMode.DECREASING, event.getUnit()); + + final Series series = seriesService.getOrCreateByName(event.getName(), event.isIncreasing() ? SeriesMode.INCREASING : SeriesMode.DECREASING, event.getDate(), event.getValue(), event.getUnit()); + series.setLastDate(event.getDate()); + series.setLastValue(series.getMode().update(series.getLastValue(), event.getValue())); + final Period period = periodService.getOrCreatePeriod(series, event); period.setLastDate(event.getDate()); - period.setLastValue(event.getValue()); + period.setLastValue(series.getMode().update(period.getLastValue(), event.getValue())); + for (final Unit unit : Unit.values()) { final ZonedDateTime aligned = unit.align(event.getDate()); final Optional existingOptional = consumptionRepository.findByIdPeriodAndIdUnitAndIdAligned(period, unit, aligned); diff --git a/src/main/java/de/ph87/data/series/counter/CounterService.java b/src/main/java/de/ph87/data/series/counter/CounterService.java index 78a4603..2553b16 100644 --- a/src/main/java/de/ph87/data/series/counter/CounterService.java +++ b/src/main/java/de/ph87/data/series/counter/CounterService.java @@ -24,7 +24,12 @@ public class CounterService { @EventListener(CounterEvent.class) public void onCounterEvent(@NonNull final CounterEvent event) { - final Series series = seriesService.getOrCreateByName(event.getName(), SeriesMode.COUNTER, event.getUnit()); + log.debug("Handling CounterEvent: {}", event); + + final Series series = seriesService.getOrCreateByName(event.getName(), SeriesMode.COUNTER, event.getDate(), event.getCount(), event.getUnit()); + series.setLastDate(event.getDate()); + series.setLastValue(series.getMode().update(series.getLastValue(), event.getCount())); + for (final Unit unit : Unit.values()) { final SeriesIntervalKey id = new SeriesIntervalKey(series, unit, event.getDate()); counterRepository.findById(id) diff --git a/src/main/java/de/ph87/data/series/measure/MeasureService.java b/src/main/java/de/ph87/data/series/measure/MeasureService.java index 27aacca..52f5416 100644 --- a/src/main/java/de/ph87/data/series/measure/MeasureService.java +++ b/src/main/java/de/ph87/data/series/measure/MeasureService.java @@ -24,7 +24,12 @@ public class MeasureService { @EventListener(MeasureEvent.class) public void onMeasureEvent(@NonNull final MeasureEvent event) { - final Series series = seriesService.getOrCreateByName(event.getName(), SeriesMode.MEASURE, event.getUnit()); + log.debug("Handling MeasureEvent: {}", event); + + final Series series = seriesService.getOrCreateByName(event.getName(), SeriesMode.MEASURE, event.getDate(), event.getValue(), event.getUnit()); + series.setLastDate(event.getDate()); + series.setLastValue(series.getMode().update(series.getLastValue(), event.getValue())); + for (final Unit unit : Unit.values()) { final SeriesIntervalKey id = new SeriesIntervalKey(series, unit, event.getDate()); measureRepository.findById(id)