DemoService: infraredHeater

This commit is contained in:
Patrick Haßel 2025-09-16 11:25:38 +02:00
parent 41a645227c
commit 840b49743a
3 changed files with 43 additions and 12 deletions

View File

@ -29,6 +29,13 @@ public class DemoService {
@Transactional @Transactional
@EventListener(ApplicationReadyEvent.class) @EventListener(ApplicationReadyEvent.class)
public void init() { 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 electricityEnergyProduce = series("electricity/energy/produce", "kWh", SeriesType.DELTA, 5);
final Series electricityPowerProduce = series("electricity/power/produce", "W", SeriesType.VARYING, 5); final Series electricityPowerProduce = series("electricity/power/produce", "W", SeriesType.VARYING, 5);
topic( topic(

View File

@ -20,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.Instant; import java.time.Instant;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Optional;
@Slf4j @Slf4j
@Service @Service
@ -95,24 +96,40 @@ public class TopicReceiver {
return; return;
} }
} }
final double value = query.getFunction().apply(json.read(query.getValueQuery(), Double.class)) * query.getFactor();
final Object valueRaw = json.read(query.getValueQuery());
queryValue(valueRaw).ifPresentOrElse(
v -> {
final double value = query.getFunction().apply(v) * query.getFactor();
series.update(date, value); series.update(date, value);
applicationEventPublisher.publishEvent(new SeriesDto(series)); applicationEventPublisher.publishEvent(new SeriesDto(series));
switch (series.getType()) { switch (series.getType()) {
case BOOL -> { case BOOL -> {
final ZonedDateTime begin = queryTimestamp(json, query.getBeginQuery(), topic.getTimestampType()); final ZonedDateTime begin = "timestamp".equals(query.getBeginQuery()) ? date : queryTimestamp(json, query.getBeginQuery(), topic.getTimestampType());
final boolean terminated = json.read(query.getTerminatedQuery(), Boolean.class); final boolean terminated = !"true".equals(query.getTerminatedQuery()) && json.read(query.getTerminatedQuery(), Boolean.class);
boolService.write(series, begin, date, value > 0, terminated); boolService.write(series, begin, date, value > 0, terminated);
} }
case DELTA -> deltaService.write(series, date, value); case DELTA -> deltaService.write(series, date, value);
case VARYING -> varyingService.write(series, date, value); case VARYING -> varyingService.write(series, date, value);
} }
},
() -> topic.error(log, "Failed to parse value: %s".formatted(valueRaw))
);
} catch (Exception e) { } 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); 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<Double> 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 @NonNull
private Topic updateOrCreate(@NonNull final String name) { private Topic updateOrCreate(@NonNull final String name) {
return topicRepository.findByName(name).stream().peek(Topic::update).findFirst().orElseGet(() -> topicRepository.save(new Topic(name))); return topicRepository.findByName(name).stream().peek(Topic::update).findFirst().orElseGet(() -> topicRepository.save(new Topic(name)));
@ -120,6 +137,9 @@ public class TopicReceiver {
@NonNull @NonNull
private static ZonedDateTime queryTimestamp(@NonNull final DocumentContext json, @NonNull final String query, @NonNull final TimestampType type) { 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) { return switch (type) {
case TimestampType.EPOCH_SECONDS -> ZonedDateTime.ofInstant(Instant.ofEpochSecond(json.read(query, Long.class)), ZoneId.systemDefault()); 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()); case TimestampType.EPOCH_MILLISECONDS -> ZonedDateTime.ofInstant(Instant.ofEpochMilli(json.read(query, Long.class)), ZoneId.systemDefault());

View File

@ -46,6 +46,10 @@ public class TopicQuery {
this(series, valueQuery, "", "", TopicQueryFunction.NONE, 1); 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) { public TopicQuery(@Nullable final Series series, @NonNull final String valueQuery, final double factor) {
this(series, valueQuery, "", "", TopicQueryFunction.NONE, factor); this(series, valueQuery, "", "", TopicQueryFunction.NONE, factor);
} }