diff --git a/src/main/java/de/ph87/data/DemoService.java b/src/main/java/de/ph87/data/DemoService.java index 84b735a..89a1785 100644 --- a/src/main/java/de/ph87/data/DemoService.java +++ b/src/main/java/de/ph87/data/DemoService.java @@ -29,6 +29,13 @@ public class DemoService { @Transactional @EventListener(ApplicationReadyEvent.class) public void init() { + final Series infraredHeater = series("infraredHeater/state", "", SeriesType.BOOL, 5); + topic( + "Infrarotheizung", + "now", + new TopicQuery(infraredHeater, "$.state", "timestamp", "true") + ); + final Series electricityEnergyProduce = series("electricity/energy/produce", "kWh", SeriesType.DELTA, 5); final Series electricityPowerProduce = series("electricity/power/produce", "W", SeriesType.VARYING, 5); topic( diff --git a/src/main/java/de/ph87/data/topic/TopicReceiver.java b/src/main/java/de/ph87/data/topic/TopicReceiver.java index 2921180..1331214 100644 --- a/src/main/java/de/ph87/data/topic/TopicReceiver.java +++ b/src/main/java/de/ph87/data/topic/TopicReceiver.java @@ -20,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.util.Optional; @Slf4j @Service @@ -95,24 +96,40 @@ public class TopicReceiver { return; } } - final double value = query.getFunction().apply(json.read(query.getValueQuery(), Double.class)) * query.getFactor(); - series.update(date, value); - applicationEventPublisher.publishEvent(new SeriesDto(series)); - switch (series.getType()) { - case BOOL -> { - final ZonedDateTime begin = queryTimestamp(json, query.getBeginQuery(), topic.getTimestampType()); - final boolean terminated = json.read(query.getTerminatedQuery(), Boolean.class); - boolService.write(series, begin, date, value > 0, terminated); - } - case DELTA -> deltaService.write(series, date, value); - case VARYING -> varyingService.write(series, date, value); - } + final Object valueRaw = json.read(query.getValueQuery()); + queryValue(valueRaw).ifPresentOrElse( + v -> { + final double value = query.getFunction().apply(v) * query.getFactor(); + series.update(date, value); + applicationEventPublisher.publishEvent(new SeriesDto(series)); + + switch (series.getType()) { + case BOOL -> { + final ZonedDateTime begin = "timestamp".equals(query.getBeginQuery()) ? date : queryTimestamp(json, query.getBeginQuery(), topic.getTimestampType()); + final boolean terminated = !"true".equals(query.getTerminatedQuery()) && json.read(query.getTerminatedQuery(), Boolean.class); + boolService.write(series, begin, date, value > 0, terminated); + } + case DELTA -> deltaService.write(series, date, value); + case VARYING -> varyingService.write(series, date, value); + } + }, + () -> topic.error(log, "Failed to parse value: %s".formatted(valueRaw)) + ); } catch (Exception e) { topic.error(log, "Error executing TopicQuery: %s\n topic=%s\n query=%s\n inbound=%s".formatted(e.toString(), topic, query, inbound), e); } } + private static Optional queryValue(final Object valueRaw) { + if (valueRaw instanceof final Number n) { + return Optional.of((double) n); + } else if (valueRaw instanceof final Boolean b) { + return Optional.of(b ? 1.0 : 0.0); + } + return Optional.empty(); + } + @NonNull private Topic updateOrCreate(@NonNull final String name) { return topicRepository.findByName(name).stream().peek(Topic::update).findFirst().orElseGet(() -> topicRepository.save(new Topic(name))); @@ -120,6 +137,9 @@ public class TopicReceiver { @NonNull private static ZonedDateTime queryTimestamp(@NonNull final DocumentContext json, @NonNull final String query, @NonNull final TimestampType type) { + if ("now".equals(query)) { + return ZonedDateTime.now(); + } return switch (type) { case TimestampType.EPOCH_SECONDS -> ZonedDateTime.ofInstant(Instant.ofEpochSecond(json.read(query, Long.class)), ZoneId.systemDefault()); case TimestampType.EPOCH_MILLISECONDS -> ZonedDateTime.ofInstant(Instant.ofEpochMilli(json.read(query, Long.class)), ZoneId.systemDefault()); diff --git a/src/main/java/de/ph87/data/topic/query/TopicQuery.java b/src/main/java/de/ph87/data/topic/query/TopicQuery.java index ab97d7a..bd8f3d6 100644 --- a/src/main/java/de/ph87/data/topic/query/TopicQuery.java +++ b/src/main/java/de/ph87/data/topic/query/TopicQuery.java @@ -46,6 +46,10 @@ public class TopicQuery { this(series, valueQuery, "", "", TopicQueryFunction.NONE, 1); } + public TopicQuery(@Nullable final Series series, @NonNull final String valueQuery, @NonNull final String beginQuery, @NonNull final String terminatedQuery) { + this(series, valueQuery, beginQuery, terminatedQuery, TopicQueryFunction.NONE, 1); + } + public TopicQuery(@Nullable final Series series, @NonNull final String valueQuery, final double factor) { this(series, valueQuery, "", "", TopicQueryFunction.NONE, factor); }