From e005f1ef8c44d79a088d94c69b69540e0b47e9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Mon, 24 Feb 2025 11:45:52 +0100 Subject: [PATCH] code clean --- src/main/java/de/ph87/data/Backend.java | 4 +- .../de/ph87/data/message/IMessageHandler.java | 4 +- .../java/de/ph87/data/message/Message.java | 10 +-- .../de/ph87/data/message/MessageService.java | 6 +- .../data/message/handler/EspHomeHandler.java | 53 ++++++----- .../data/message/handler/HeizungHandler.java | 25 +++--- .../data/message/handler/OpenDTUHandler.java | 31 ++++--- .../message/handler/SimpleJsonHandler.java | 25 +++--- .../message/handler/SmartMeterHandler.java | 37 ++++---- .../data/message/receive/mqtt/MqttConfig.java | 16 ++-- .../message/receive/mqtt/MqttReceiver.java | 24 ++--- src/main/java/de/ph87/data/series/Series.java | 20 ++--- .../java/de/ph87/data/series/SeriesDto.java | 20 ++--- .../de/ph87/data/series/SeriesInbound.java | 12 +-- .../de/ph87/data/series/SeriesRepository.java | 4 +- .../de/ph87/data/series/SeriesService.java | 22 ++--- .../java/de/ph87/data/series/entry/Entry.java | 17 ++-- .../data/series/entry/EntryRepository.java | 6 +- .../ph87/data/series/entry/EntryService.java | 6 +- src/main/java/de/ph87/data/unit/Unit.java | 51 ----------- .../ph87/data/unit/UnitListDeserializer.java | 17 ---- src/main/java/de/ph87/data/unit/Value.java | 26 ------ src/main/java/de/ph87/data/value/Value.java | 88 +++++++++++++++++++ 23 files changed, 256 insertions(+), 268 deletions(-) delete mode 100644 src/main/java/de/ph87/data/unit/Unit.java delete mode 100644 src/main/java/de/ph87/data/unit/UnitListDeserializer.java delete mode 100644 src/main/java/de/ph87/data/unit/Value.java create mode 100644 src/main/java/de/ph87/data/value/Value.java diff --git a/src/main/java/de/ph87/data/Backend.java b/src/main/java/de/ph87/data/Backend.java index e1625ca..176c16f 100644 --- a/src/main/java/de/ph87/data/Backend.java +++ b/src/main/java/de/ph87/data/Backend.java @@ -5,9 +5,9 @@ import org.springframework.boot.autoconfigure.*; @SpringBootApplication public class Backend { - + public static void main(String[] args) { SpringApplication.run(Backend.class, args); } - + } \ No newline at end of file diff --git a/src/main/java/de/ph87/data/message/IMessageHandler.java b/src/main/java/de/ph87/data/message/IMessageHandler.java index 6c1201d..976bc69 100644 --- a/src/main/java/de/ph87/data/message/IMessageHandler.java +++ b/src/main/java/de/ph87/data/message/IMessageHandler.java @@ -3,7 +3,7 @@ package de.ph87.data.message; import lombok.*; public interface IMessageHandler { - + void handle(@NonNull final Message message) throws Exception; - + } diff --git a/src/main/java/de/ph87/data/message/Message.java b/src/main/java/de/ph87/data/message/Message.java index c5fc0c5..dd41ed0 100644 --- a/src/main/java/de/ph87/data/message/Message.java +++ b/src/main/java/de/ph87/data/message/Message.java @@ -5,18 +5,18 @@ import lombok.*; @Getter @ToString public class Message { - + public final String topic; - + @ToString.Exclude public final String payload; - + public final String payloadLoggable; - + public Message(final String topic, final String payload) { this.topic = topic; this.payload = payload; this.payloadLoggable = payload.replace("\n", "\\n").replace("\r", "\\r"); } - + } diff --git a/src/main/java/de/ph87/data/message/MessageService.java b/src/main/java/de/ph87/data/message/MessageService.java index 8d7aa63..da37a90 100644 --- a/src/main/java/de/ph87/data/message/MessageService.java +++ b/src/main/java/de/ph87/data/message/MessageService.java @@ -10,9 +10,9 @@ import java.util.*; @Service @RequiredArgsConstructor public class MessageService { - + private final List messageHandlers; - + public void handle(@NonNull final Message message) { messageHandlers.forEach(handler -> { try { @@ -22,5 +22,5 @@ public class MessageService { } }); } - + } diff --git a/src/main/java/de/ph87/data/message/handler/EspHomeHandler.java b/src/main/java/de/ph87/data/message/handler/EspHomeHandler.java index 05a4d60..3c5f06a 100644 --- a/src/main/java/de/ph87/data/message/handler/EspHomeHandler.java +++ b/src/main/java/de/ph87/data/message/handler/EspHomeHandler.java @@ -6,8 +6,7 @@ import com.fasterxml.jackson.databind.annotation.*; import de.ph87.data.message.*; import de.ph87.data.series.*; import de.ph87.data.series.entry.*; -import de.ph87.data.unit.Value; -import de.ph87.data.unit.*; +import de.ph87.data.value.Value; import lombok.*; import lombok.extern.slf4j.*; import org.springframework.stereotype.*; @@ -21,13 +20,13 @@ import java.util.stream.*; @Service @RequiredArgsConstructor public class EspHomeHandler implements IMessageHandler { - + private static final Pattern REGEX = Pattern.compile("^(?\\w+)/sensor/(?\\w+)$"); - + private final ObjectMapper objectMapper; - + private final EntryService entryService; - + @Override public void handle(@NonNull final Message message) throws Exception { final Matcher matcher = REGEX.matcher(message.topic); @@ -37,15 +36,15 @@ public class EspHomeHandler implements IMessageHandler { final String area = matcher.group("area"); final String property = propertyReplace(matcher.group("property")); final String name = "%s/%s".formatted(area, property.replace("_", "/")); - final Unit targetUnit = switch (property) { - case "iaq" -> Unit.IAQ; - case "iaq_co2" -> Unit.IAQ_CO2_EQUIVALENT; - case "iaq_voc" -> Unit.IAQ_VOC_EQUIVALENT; - case "pressure" -> Unit.PRESSURE_HPA; - case "temperature" -> Unit.TEMPERATURE_C; - case "humidity_relative" -> Unit.HUMIDITY_RELATIVE_PERCENT; - case "humidity_absolute" -> Unit.HUMIDITY_ABSOLUTE_GM3; - case "sun" -> Unit.SUN_DC; + final Value.Unit targetUnit = switch (property) { + case "iaq" -> Value.Unit.IAQ; + case "iaq_co2" -> Value.Unit.IAQ_CO2_EQUIVALENT; + case "iaq_voc" -> Value.Unit.IAQ_VOC_EQUIVALENT; + case "pressure" -> Value.Unit.PRESSURE_HPA; + case "temperature" -> Value.Unit.TEMPERATURE_C; + case "humidity_relative" -> Value.Unit.HUMIDITY_RELATIVE_PERCENT; + case "humidity_absolute" -> Value.Unit.HUMIDITY_ABSOLUTE_GM3; + case "sun" -> Value.Unit.SUN_DC; default -> null; }; if (targetUnit == null) { @@ -53,7 +52,7 @@ public class EspHomeHandler implements IMessageHandler { return; } final Inbound inbound = objectMapper.readValue(message.payload, Inbound.class); - final Unit unitFromPayload = inbound.units.stream().filter(ufp -> ufp.base == targetUnit.base).findFirst().orElse(null); + final Value.Unit unitFromPayload = inbound.units.stream().filter(ufp -> ufp.base == targetUnit.base).findFirst().orElse(null); if (unitFromPayload == null) { log.error("Unit mismatch: fromTopic={}, fromPayload=[{}]", targetUnit, inbound.getUnits().stream().map(Enum::name).collect(Collectors.joining(","))); return; @@ -61,7 +60,7 @@ public class EspHomeHandler implements IMessageHandler { final Value value = new Value(inbound.value, unitFromPayload); entryService.receive(new SeriesInbound(name, inbound.date, value.as(targetUnit))); } - + private String propertyReplace(final String property) { if ("iaq_co2_equivalent".equals(property)) { return "iaq_co2"; @@ -71,26 +70,26 @@ public class EspHomeHandler implements IMessageHandler { } return property; } - + @Getter @ToString private static class Inbound { - + @NonNull public final ZonedDateTime date; - + public final double value; - + @NonNull - @JsonDeserialize(using = UnitListDeserializer.class) - public final List units; - - public Inbound(final long timestamp, final double value, @JsonProperty("unit") @NonNull final List units) { + @JsonDeserialize(using = Value.Unit.ListDeserializer.class) + public final List units; + + public Inbound(final long timestamp, final double value, @JsonProperty("unit") @NonNull final List units) { this.date = ZonedDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault()); this.value = value; this.units = units; } - + } - + } diff --git a/src/main/java/de/ph87/data/message/handler/HeizungHandler.java b/src/main/java/de/ph87/data/message/handler/HeizungHandler.java index 89b3c92..ff09b31 100644 --- a/src/main/java/de/ph87/data/message/handler/HeizungHandler.java +++ b/src/main/java/de/ph87/data/message/handler/HeizungHandler.java @@ -4,8 +4,7 @@ import com.fasterxml.jackson.databind.*; import de.ph87.data.message.*; import de.ph87.data.series.*; import de.ph87.data.series.entry.*; -import de.ph87.data.unit.Value; -import de.ph87.data.unit.*; +import de.ph87.data.value.Value; import lombok.*; import lombok.extern.slf4j.*; import org.springframework.stereotype.*; @@ -17,13 +16,13 @@ import java.util.regex.*; @Service @RequiredArgsConstructor public class HeizungHandler implements IMessageHandler { - + private static final Pattern REGEX = Pattern.compile("^aggregation/(?heizung/.+)/temperatur$"); - + private final ObjectMapper objectMapper; - + private final EntryService entryService; - + @Override public void handle(@NonNull final Message message) throws Exception { final Matcher matcher = REGEX.matcher(message.topic); @@ -34,21 +33,21 @@ public class HeizungHandler implements IMessageHandler { final Inbound inbound = objectMapper.readValue(message.payload, Inbound.class); entryService.receive(new SeriesInbound(property, inbound.date, inbound.value)); } - + @Getter @ToString private static class Inbound { - + @NonNull public final ZonedDateTime date; - + public final Value value; - + public Inbound(final long timestamp, final double sum, final int count) { this.date = ZonedDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault()); - this.value = new Value(sum / count, Unit.TEMPERATURE_C); + this.value = new Value(sum / count, Value.Unit.TEMPERATURE_C); } - + } - + } diff --git a/src/main/java/de/ph87/data/message/handler/OpenDTUHandler.java b/src/main/java/de/ph87/data/message/handler/OpenDTUHandler.java index 4030f11..e73430d 100644 --- a/src/main/java/de/ph87/data/message/handler/OpenDTUHandler.java +++ b/src/main/java/de/ph87/data/message/handler/OpenDTUHandler.java @@ -4,8 +4,7 @@ import com.fasterxml.jackson.databind.*; import de.ph87.data.message.*; import de.ph87.data.series.*; import de.ph87.data.series.entry.*; -import de.ph87.data.unit.Value; -import de.ph87.data.unit.*; +import de.ph87.data.value.Value; import lombok.*; import lombok.extern.slf4j.*; import org.springframework.stereotype.*; @@ -16,38 +15,38 @@ import java.time.*; @Service @RequiredArgsConstructor public class OpenDTUHandler implements IMessageHandler { - + private final ObjectMapper objectMapper; - + private final EntryService entryService; - + @Override public void handle(final @NonNull Message message) throws Exception { if (!"openDTU/pv/patrix/json".equals(message.topic)) { return; } final Inbound inbound = objectMapper.readValue(message.payload, Inbound.class); - entryService.receive(new SeriesInbound("electricity/energy/produced", inbound.date, inbound.energy.as(Unit.ENERGY_KWH))); - entryService.receive(new SeriesInbound("electricity/power/produced", inbound.date, inbound.power.as(Unit.POWER_W))); + entryService.receive(new SeriesInbound("electricity/energy/produced", inbound.date, inbound.energy.as(Value.Unit.ENERGY_KWH))); + entryService.receive(new SeriesInbound("electricity/power/produced", inbound.date, inbound.power.as(Value.Unit.POWER_W))); } - + @Getter @ToString private static class Inbound { - + @NonNull public final ZonedDateTime date; - + public final Value energy; - + public final Value power; - + public Inbound(final long timestamp, final double energyProducedKWh, final double powerW) { this.date = ZonedDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault()); - this.energy = new Value(energyProducedKWh, Unit.ENERGY_KWH); - this.power = new Value(powerW, Unit.POWER_W); + this.energy = new Value(energyProducedKWh, Value.Unit.ENERGY_KWH); + this.power = new Value(powerW, Value.Unit.POWER_W); } - + } - + } diff --git a/src/main/java/de/ph87/data/message/handler/SimpleJsonHandler.java b/src/main/java/de/ph87/data/message/handler/SimpleJsonHandler.java index c00325f..b981cf7 100644 --- a/src/main/java/de/ph87/data/message/handler/SimpleJsonHandler.java +++ b/src/main/java/de/ph87/data/message/handler/SimpleJsonHandler.java @@ -4,8 +4,7 @@ import com.fasterxml.jackson.databind.*; import de.ph87.data.message.*; import de.ph87.data.series.*; import de.ph87.data.series.entry.*; -import de.ph87.data.unit.Value; -import de.ph87.data.unit.*; +import de.ph87.data.value.Value; import lombok.*; import lombok.extern.slf4j.*; import org.springframework.stereotype.*; @@ -16,11 +15,11 @@ import java.time.*; @Service @RequiredArgsConstructor public class SimpleJsonHandler implements IMessageHandler { - + private final ObjectMapper objectMapper; - + private final EntryService entryService; - + @Override public void handle(@NonNull final Message message) throws Exception { if (!message.topic.endsWith("/SimpleJson")) { @@ -29,25 +28,25 @@ public class SimpleJsonHandler implements IMessageHandler { final Inbound inbound = objectMapper.readValue(message.payload, Inbound.class); entryService.receive(new SeriesInbound(inbound.name, inbound.date, inbound.value)); } - + @Getter @ToString private static class Inbound { - + @NonNull public final String name; - + @NonNull public final ZonedDateTime date; - + public final Value value; - - public Inbound(@NonNull final String name, final long timestamp, final double value, @NonNull final Unit unit) { + + public Inbound(@NonNull final String name, final long timestamp, final double value, @NonNull final Value.Unit unit) { this.name = name; this.date = ZonedDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault()); this.value = new Value(value, unit); } - + } - + } diff --git a/src/main/java/de/ph87/data/message/handler/SmartMeterHandler.java b/src/main/java/de/ph87/data/message/handler/SmartMeterHandler.java index 01e52d1..0456f7f 100644 --- a/src/main/java/de/ph87/data/message/handler/SmartMeterHandler.java +++ b/src/main/java/de/ph87/data/message/handler/SmartMeterHandler.java @@ -4,8 +4,7 @@ import com.fasterxml.jackson.databind.*; import de.ph87.data.message.*; import de.ph87.data.series.*; import de.ph87.data.series.entry.*; -import de.ph87.data.unit.Value; -import de.ph87.data.unit.*; +import de.ph87.data.value.Value; import lombok.*; import lombok.extern.slf4j.*; import org.springframework.stereotype.*; @@ -16,42 +15,42 @@ import java.time.*; @Service @RequiredArgsConstructor public class SmartMeterHandler implements IMessageHandler { - + private final ObjectMapper objectMapper; - + private final EntryService entryService; - + @Override public void handle(@NonNull final Message message) throws Exception { if (!"electricity/grid/json".equals(message.topic)) { return; } final Inbound inbound = objectMapper.readValue(message.payload, Inbound.class); - entryService.receive(new SeriesInbound("electricity/energy/purchased", inbound.date, inbound.energyPurchased.as(Unit.ENERGY_KWH))); - entryService.receive(new SeriesInbound("electricity/energy/delivered", inbound.date, inbound.energyDelivered.as(Unit.ENERGY_KWH))); - entryService.receive(new SeriesInbound("electricity/power/difference", inbound.date, inbound.powerDifference.as(Unit.POWER_W))); + entryService.receive(new SeriesInbound("electricity/energy/purchased", inbound.date, inbound.energyPurchased.as(Value.Unit.ENERGY_KWH))); + entryService.receive(new SeriesInbound("electricity/energy/delivered", inbound.date, inbound.energyDelivered.as(Value.Unit.ENERGY_KWH))); + entryService.receive(new SeriesInbound("electricity/power/difference", inbound.date, inbound.powerDifference.as(Value.Unit.POWER_W))); } - + @Getter @ToString private static class Inbound { - + @NonNull public final ZonedDateTime date; - + public final Value energyPurchased; - + public final Value energyDelivered; - + public final Value powerDifference; - + public Inbound(final long timestamp, final double purchaseWh, final double deliveryWh, final double powerW) { this.date = ZonedDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault()); - this.energyPurchased = new Value(purchaseWh, Unit.ENERGY_WH); - this.energyDelivered = new Value(deliveryWh, Unit.ENERGY_WH); - this.powerDifference = new Value(powerW, Unit.POWER_W); + this.energyPurchased = new Value(purchaseWh, Value.Unit.ENERGY_WH); + this.energyDelivered = new Value(deliveryWh, Value.Unit.ENERGY_WH); + this.powerDifference = new Value(powerW, Value.Unit.POWER_W); } - + } - + } diff --git a/src/main/java/de/ph87/data/message/receive/mqtt/MqttConfig.java b/src/main/java/de/ph87/data/message/receive/mqtt/MqttConfig.java index fb55d66..86bc6f2 100644 --- a/src/main/java/de/ph87/data/message/receive/mqtt/MqttConfig.java +++ b/src/main/java/de/ph87/data/message/receive/mqtt/MqttConfig.java @@ -8,19 +8,19 @@ import org.springframework.stereotype.*; @Component @ConfigurationProperties(prefix = "de.ph87.data.message.receive.mqtt") public class MqttConfig { - + private String host; - + private int port = 1883; - + private String topic; - + private String clientId; - + private int connectTimeoutSec = 3; - + private long retrySec = 3; - + private int connectKeepAliveSec = 3; - + } diff --git a/src/main/java/de/ph87/data/message/receive/mqtt/MqttReceiver.java b/src/main/java/de/ph87/data/message/receive/mqtt/MqttReceiver.java index 49f38f8..5d8ac56 100644 --- a/src/main/java/de/ph87/data/message/receive/mqtt/MqttReceiver.java +++ b/src/main/java/de/ph87/data/message/receive/mqtt/MqttReceiver.java @@ -17,23 +17,23 @@ import java.util.*; @Service @RequiredArgsConstructor public class MqttReceiver { - + private final MqttConfig config; - + private final MessageService messageService; - + @Nullable private MqttClient client; - + private final Thread thread = new Thread(this::run, "MQTT-WATCH"); - + private boolean stop = false; - + @EventListener(ApplicationStartedEvent.class) public void startup() { thread.start(); } - + @PreDestroy public void preDestroy() { synchronized (thread) { @@ -42,7 +42,7 @@ public class MqttReceiver { log.debug("stopping..."); } } - + private void run() { try { log.debug("started"); @@ -63,7 +63,7 @@ public class MqttReceiver { log.debug("terminated"); } } - + private void _connect() throws InterruptedException { final String clientId; final boolean cleanSession; @@ -97,7 +97,7 @@ public class MqttReceiver { } } } - + private void _disconnect() { if (client != null && client.isConnected()) { try { @@ -107,7 +107,7 @@ public class MqttReceiver { } } } - + private void _receive(final String topic, final MqttMessage mqttMessage) { Thread.currentThread().setName("MQTT-RECEIVE"); final String payload = new String(mqttMessage.getPayload(), StandardCharsets.UTF_8); @@ -115,5 +115,5 @@ public class MqttReceiver { log.debug("received: {}", message); messageService.handle(message); } - + } diff --git a/src/main/java/de/ph87/data/series/Series.java b/src/main/java/de/ph87/data/series/Series.java index ddddb0b..82329b0 100644 --- a/src/main/java/de/ph87/data/series/Series.java +++ b/src/main/java/de/ph87/data/series/Series.java @@ -1,6 +1,6 @@ package de.ph87.data.series; -import de.ph87.data.unit.*; +import de.ph87.data.value.Value; import jakarta.persistence.*; import lombok.*; @@ -9,35 +9,35 @@ import lombok.*; @ToString @NoArgsConstructor public class Series { - + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; - + @Setter @NonNull @Column(nullable = false, unique = true) private String name; - + @Setter @NonNull @Column(nullable = false, unique = true) private String title; - + @Setter @NonNull @Column(nullable = false) @Enumerated(EnumType.STRING) - private Unit unit; - + private Value.Unit unit; + @Setter @Column(nullable = false) private int decimals = 1; - - public Series(@NonNull final String name, @NonNull final Unit unit) { + + public Series(@NonNull final String name, @NonNull final Value.Unit unit) { this.name = name; this.title = name; this.unit = unit; } - + } diff --git a/src/main/java/de/ph87/data/series/SeriesDto.java b/src/main/java/de/ph87/data/series/SeriesDto.java index 27adc5b..e6360c7 100644 --- a/src/main/java/de/ph87/data/series/SeriesDto.java +++ b/src/main/java/de/ph87/data/series/SeriesDto.java @@ -1,23 +1,23 @@ package de.ph87.data.series; -import de.ph87.data.unit.*; +import de.ph87.data.value.Value; import jakarta.annotation.*; import lombok.*; @Getter @ToString public class SeriesDto { - + public final long id; - + public final String name; - + public final String title; - - public final Unit unit; - + + public final Value.Unit unit; + public final int decimals; - + public SeriesDto(@NonNull final Series series) { this.id = series.getId(); this.name = series.getName(); @@ -25,12 +25,12 @@ public class SeriesDto { this.unit = series.getUnit(); this.decimals = series.getDecimals(); } - + public String format(@Nullable final Double value) { if (value == null || Double.isNaN(value)) { return "--- %s".formatted(unit.unit); } return "%%.%df %%s".formatted(decimals).formatted(value, unit.unit); } - + } diff --git a/src/main/java/de/ph87/data/series/SeriesInbound.java b/src/main/java/de/ph87/data/series/SeriesInbound.java index 75f5992..6932929 100644 --- a/src/main/java/de/ph87/data/series/SeriesInbound.java +++ b/src/main/java/de/ph87/data/series/SeriesInbound.java @@ -1,6 +1,6 @@ package de.ph87.data.series; -import de.ph87.data.unit.Value; +import de.ph87.data.value.Value; import lombok.*; import java.time.*; @@ -8,19 +8,19 @@ import java.time.*; @Getter @ToString public class SeriesInbound { - + @NonNull public final String name; - + @NonNull public final ZonedDateTime date; - + public final Value value; - + public SeriesInbound(@NonNull final String name, @NonNull final ZonedDateTime date, final Value value) { this.name = name; this.date = date; this.value = value; } - + } diff --git a/src/main/java/de/ph87/data/series/SeriesRepository.java b/src/main/java/de/ph87/data/series/SeriesRepository.java index 9d693c5..8dab0f6 100644 --- a/src/main/java/de/ph87/data/series/SeriesRepository.java +++ b/src/main/java/de/ph87/data/series/SeriesRepository.java @@ -6,7 +6,7 @@ import org.springframework.data.repository.*; import java.util.*; public interface SeriesRepository extends ListCrudRepository { - + Optional findByName(@NonNull String name); - + } diff --git a/src/main/java/de/ph87/data/series/SeriesService.java b/src/main/java/de/ph87/data/series/SeriesService.java index 19fd229..e99cde9 100644 --- a/src/main/java/de/ph87/data/series/SeriesService.java +++ b/src/main/java/de/ph87/data/series/SeriesService.java @@ -1,7 +1,7 @@ package de.ph87.data.series; import de.ph87.data.*; -import de.ph87.data.unit.*; +import de.ph87.data.value.Value; import lombok.*; import lombok.extern.slf4j.*; import org.springframework.stereotype.*; @@ -14,42 +14,42 @@ import java.util.function.*; @Transactional @RequiredArgsConstructor public class SeriesService { - + private final SeriesRepository seriesRepository; - + @SuppressWarnings("unused") public SeriesDto modify(final long id, @NonNull final Consumer modifier) { final Series series = getById(id); modifier.accept(series); return publish(series, Action.CHANGED); } - + @SuppressWarnings("unused") public void delete(final long id) { final Series series = getById(id); seriesRepository.delete(series); publish(series, Action.DELETED); } - + private Series getById(final long id) { return seriesRepository.findById(id).orElseThrow(); } - + public SeriesDto getDtoById(final long id) { return toDto(getById(id)); } - + private SeriesDto publish(@NonNull final Series series, @NonNull final Action action) { final SeriesDto dto = toDto(series); log.info("Series {}: {}", action, series); return dto; } - + private SeriesDto toDto(@NonNull final Series series) { return new SeriesDto(series); } - - public Series getOrCreate(@NonNull final String name, @NonNull final Unit unit) { + + public Series getOrCreate(@NonNull final String name, @NonNull final Value.Unit unit) { return seriesRepository .findByName(name) .orElseGet(() -> { @@ -58,5 +58,5 @@ public class SeriesService { return series; }); } - + } diff --git a/src/main/java/de/ph87/data/series/entry/Entry.java b/src/main/java/de/ph87/data/series/entry/Entry.java index 340c709..ca667f3 100644 --- a/src/main/java/de/ph87/data/series/entry/Entry.java +++ b/src/main/java/de/ph87/data/series/entry/Entry.java @@ -1,8 +1,7 @@ package de.ph87.data.series.entry; import de.ph87.data.series.*; -import de.ph87.data.unit.Value; -import de.ph87.data.unit.*; +import de.ph87.data.value.Value; import jakarta.persistence.*; import lombok.*; @@ -19,27 +18,27 @@ import java.time.temporal.*; } ) public class Entry { - + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; - + @NonNull @ManyToOne private Series series; - + @NonNull @Column(nullable = false) private ZonedDateTime date; - + @Setter @Column(nullable = false, name = "`value`") private double value; - - public Entry(@NonNull final Series series, @NonNull final ZonedDateTime date, final Value value) throws Unit.NotConvertible { + + public Entry(@NonNull final Series series, @NonNull final ZonedDateTime date, final Value value) throws Value.Unit.NotConvertible { this.series = series; this.date = date.truncatedTo(ChronoUnit.MINUTES); this.value = value.as(series.getUnit()).value; } - + } diff --git a/src/main/java/de/ph87/data/series/entry/EntryRepository.java b/src/main/java/de/ph87/data/series/entry/EntryRepository.java index d4fb1dc..142c43e 100644 --- a/src/main/java/de/ph87/data/series/entry/EntryRepository.java +++ b/src/main/java/de/ph87/data/series/entry/EntryRepository.java @@ -8,9 +8,9 @@ import java.time.*; import java.util.*; public interface EntryRepository extends ListCrudRepository { - + Optional findBySeriesAndDate(@NonNull Series series, @NonNull ZonedDateTime truncated); - + List findAllBySeriesIdAndDateGreaterThanEqualAndDateLessThanEqual(long id, @NonNull ZonedDateTime begin, @NonNull ZonedDateTime end); - + } diff --git a/src/main/java/de/ph87/data/series/entry/EntryService.java b/src/main/java/de/ph87/data/series/entry/EntryService.java index d1d5a46..ad599b9 100644 --- a/src/main/java/de/ph87/data/series/entry/EntryService.java +++ b/src/main/java/de/ph87/data/series/entry/EntryService.java @@ -1,7 +1,7 @@ package de.ph87.data.series.entry; import de.ph87.data.series.*; -import de.ph87.data.unit.*; +import de.ph87.data.value.Value; import lombok.*; import lombok.extern.slf4j.*; import org.springframework.stereotype.*; @@ -20,7 +20,7 @@ public class EntryService { private final SeriesService seriesService; - public void write(@NonNull final Series series, @NonNull final SeriesInbound measure) throws Unit.NotConvertible { + public void write(@NonNull final Series series, @NonNull final SeriesInbound measure) throws Value.Unit.NotConvertible { final ZonedDateTime truncated = measure.date.truncatedTo(ChronoUnit.MINUTES).minusMinutes(measure.date.getMinute() % 5); if (entryRepository.findBySeriesAndDate(series, truncated).isEmpty()) { final Entry created = entryRepository.save(new Entry(series, truncated, measure.value)); @@ -28,7 +28,7 @@ public class EntryService { } } - public void receive(@NonNull final SeriesInbound measure) throws Unit.NotConvertible { + public void receive(@NonNull final SeriesInbound measure) throws Value.Unit.NotConvertible { final Series series = seriesService.getOrCreate(measure.name, measure.value.unit); write(series, measure); } diff --git a/src/main/java/de/ph87/data/unit/Unit.java b/src/main/java/de/ph87/data/unit/Unit.java deleted file mode 100644 index e46ad22..0000000 --- a/src/main/java/de/ph87/data/unit/Unit.java +++ /dev/null @@ -1,51 +0,0 @@ -package de.ph87.data.unit; - -import lombok.*; - -public enum Unit { - TEMPERATURE_C("°C"), - PRESSURE_HPA("hPa"), - HUMIDITY_RELATIVE_PERCENT("%"), - HUMIDITY_ABSOLUTE_MGL("mg/L"), - HUMIDITY_ABSOLUTE_GM3("g/m³", 1, HUMIDITY_ABSOLUTE_MGL), - ILLUMINANCE_LUX("lux"), - RESISTANCE_OHMS("Ω"), - ALTITUDE_M("m"), - POWER_W("W"), - POWER_KW("kW", 1000, POWER_W), - ENERGY_WH("W"), - ENERGY_KWH("kWh", 1000, ENERGY_WH), - IAQ("IAQ"), - IAQ_CO2_EQUIVALENT("ppm"), - IAQ_VOC_EQUIVALENT("ppm"), - SUN_DC("Δ°C"), - UNIT_PERCENT("%"), - ; - - public final String unit; - - public final double factor; - - public final Unit base; - - Unit(@NonNull final String unit) { - this.unit = unit; - this.factor = 1.0; - this.base = this; - } - - Unit(@NonNull final String unit, final double factor, @NonNull final Unit base) { - this.unit = unit; - this.factor = factor; - this.base = base; - } - - public static class NotConvertible extends Exception { - - public NotConvertible(final @NonNull Unit source, final Unit target) { - super("Cannot convert Units: source=%s, target=%s".formatted(source, target)); - } - - } - -} diff --git a/src/main/java/de/ph87/data/unit/UnitListDeserializer.java b/src/main/java/de/ph87/data/unit/UnitListDeserializer.java deleted file mode 100644 index 09fcee2..0000000 --- a/src/main/java/de/ph87/data/unit/UnitListDeserializer.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.ph87.data.unit; - -import com.fasterxml.jackson.core.*; -import com.fasterxml.jackson.databind.*; - -import java.io.*; -import java.util.*; - -public class UnitListDeserializer extends JsonDeserializer> { - - @Override - public List deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException { - final String name = jsonParser.getValueAsString(); - return Arrays.stream(Unit.values()).filter(unit -> unit.unit.equals(name)).toList(); - } - -} diff --git a/src/main/java/de/ph87/data/unit/Value.java b/src/main/java/de/ph87/data/unit/Value.java deleted file mode 100644 index 4492e9f..0000000 --- a/src/main/java/de/ph87/data/unit/Value.java +++ /dev/null @@ -1,26 +0,0 @@ -package de.ph87.data.unit; - -import lombok.*; - -public class Value { - - public final double value; - - public final Unit unit; - - public Value(final double value, @NonNull final Unit unit) { - this.value = value; - this.unit = unit; - } - - public Value as(@NonNull final Unit target) throws Unit.NotConvertible { - if (this.unit == target) { - return this; - } - if (this.unit.base != target.base) { - throw new Unit.NotConvertible(this.unit, target); - } - return new Value(value * this.unit.factor / target.factor, target); - } - -} diff --git a/src/main/java/de/ph87/data/value/Value.java b/src/main/java/de/ph87/data/value/Value.java new file mode 100644 index 0000000..f1ba740 --- /dev/null +++ b/src/main/java/de/ph87/data/value/Value.java @@ -0,0 +1,88 @@ +package de.ph87.data.value; + +import com.fasterxml.jackson.core.*; +import com.fasterxml.jackson.databind.*; +import lombok.*; + +import java.io.*; +import java.util.*; + +public class Value { + + public final double value; + + public final Unit unit; + + public Value(final double value, @NonNull final Unit unit) { + this.value = value; + this.unit = unit; + } + + public Value as(@NonNull final Unit target) throws Unit.NotConvertible { + if (this.unit == target) { + return this; + } + if (this.unit.base != target.base) { + throw new Unit.NotConvertible(this.unit, target); + } + return new Value(value * this.unit.factor / target.factor, target); + } + + public enum Unit { + TEMPERATURE_C("°C"), + PRESSURE_HPA("hPa"), + HUMIDITY_RELATIVE_PERCENT("%"), + HUMIDITY_ABSOLUTE_MGL("mg/L"), + HUMIDITY_ABSOLUTE_GM3("g/m³", 1, HUMIDITY_ABSOLUTE_MGL), + ILLUMINANCE_LUX("lux"), + RESISTANCE_OHMS("Ω"), + ALTITUDE_M("m"), + POWER_W("W"), + POWER_KW("kW", 1000, POWER_W), + ENERGY_WH("W"), + ENERGY_KWH("kWh", 1000, ENERGY_WH), + IAQ("IAQ"), + IAQ_CO2_EQUIVALENT("ppm"), + IAQ_VOC_EQUIVALENT("ppm"), + SUN_DC("Δ°C"), + UNIT_PERCENT("%"), + ; + + public final String unit; + + public final double factor; + + public final Unit base; + + Unit(@NonNull final String unit) { + this.unit = unit; + this.factor = 1.0; + this.base = this; + } + + Unit(@NonNull final String unit, final double factor, @NonNull final Value.Unit base) { + this.unit = unit; + this.factor = factor; + this.base = base; + } + + public static class NotConvertible extends Exception { + + public NotConvertible(final @NonNull Value.Unit source, final Unit target) { + super("Cannot convert Units: source=%s, target=%s".formatted(source, target)); + } + + } + + public static class ListDeserializer extends JsonDeserializer> { + + @Override + public List deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException { + final String name = jsonParser.getValueAsString(); + return Arrays.stream(values()).filter(unit -> unit.unit.equals(name)).toList(); + } + + } + } + +}