95 lines
3.4 KiB
Java
95 lines
3.4 KiB
Java
package de.ph87.data.topic.parser;
|
|
|
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
import de.ph87.data.series.data.delta.DeltaService;
|
|
import de.ph87.data.series.data.varying.VaryingService;
|
|
import de.ph87.data.topic.TopicDto;
|
|
import de.ph87.data.topic.TopicParserAbstract;
|
|
import lombok.NonNull;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.stereotype.Service;
|
|
import tools.jackson.databind.ObjectMapper;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.ZoneId;
|
|
import java.time.ZonedDateTime;
|
|
|
|
@Slf4j
|
|
@Service
|
|
public class TasmotaSmartMeter extends TopicParserAbstract<TasmotaSmartMeter.Dto> {
|
|
|
|
public TasmotaSmartMeter(@NonNull final ObjectMapper mapper, @NonNull final DeltaService deltaService, @NonNull final VaryingService varyingService) {
|
|
super(Dto.class, mapper, deltaService, varyingService);
|
|
}
|
|
|
|
@Override
|
|
protected void handle2(final @NonNull TopicDto topic, @NonNull final Dto dto) {
|
|
delta(topic.series0, dto.meter.number, dto.date, dto.meter.purchaseKWh);
|
|
delta(topic.series1, dto.meter.number, dto.date, dto.meter.deliverKWh);
|
|
varying(topic.series2, dto.date, Math.max(0, dto.meter.powerW));
|
|
varying(topic.series3, dto.date, Math.max(0, -dto.meter.powerW));
|
|
}
|
|
|
|
public static class Dto {
|
|
|
|
@NonNull
|
|
public final ZonedDateTime date;
|
|
|
|
@NonNull
|
|
public final Meter meter;
|
|
|
|
public Dto(
|
|
@JsonProperty(value = "Time", required = true) @NonNull final String localDateTimeString,
|
|
@JsonProperty(value = "meter", required = true) @NonNull final Meter meter
|
|
) {
|
|
this.date = ZonedDateTime.of(LocalDateTime.parse(localDateTimeString), ZoneId.systemDefault());
|
|
this.meter = meter;
|
|
}
|
|
|
|
public static class Meter {
|
|
|
|
@NonNull
|
|
public final String number;
|
|
|
|
public final double purchaseKWh;
|
|
|
|
public final double deliverKWh;
|
|
|
|
public final double powerW;
|
|
|
|
public Meter(
|
|
@JsonProperty(value = "number", required = true) @NonNull final String number,
|
|
@JsonProperty(value = "energy_purchased_kwh", required = true) final double purchaseWh,
|
|
@JsonProperty(value = "energy_delivered_kwh", required = true) final double deliverWh,
|
|
@JsonProperty(value = "power_w", required = true) final double powerW
|
|
) {
|
|
this.number = parseMeterNumber(number);
|
|
this.purchaseKWh = purchaseWh;
|
|
this.deliverKWh = deliverWh;
|
|
this.powerW = powerW;
|
|
}
|
|
|
|
@NonNull
|
|
private static String parseMeterNumber(@NonNull final String input) {
|
|
if (input.isEmpty()) {
|
|
throw new NumberFormatException("Cannot parse Meter number: No Hex-chars read.");
|
|
}
|
|
if (input.length() % 2 != 0) {
|
|
throw new NumberFormatException("Cannot parse Meter number: Hex-char count must be multiple of 2.");
|
|
}
|
|
final int length = Integer.parseInt(input.substring(0, 2), 16);
|
|
if (input.length() != length * 2) {
|
|
throw new NumberFormatException("Cannot parse Meter number: Invalid length");
|
|
}
|
|
final int type = Integer.parseInt(input.substring(2, 4), 16);
|
|
final String name = "" + (char) Integer.parseInt(input.substring(4, 6), 16) + (char) Integer.parseInt(input.substring(6, 8), 16) + (char) Integer.parseInt(input.substring(8, 10), 16);
|
|
final int number = Integer.parseInt(input.substring(10), 16);
|
|
return "%d%s%s".formatted(type, name, number);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|