From 533691d62e1a7c21fc54334520dab0b7f9595815 Mon Sep 17 00:00:00 2001 From: Kevin Dargel Date: Sun, 26 Mar 2023 16:05:12 +0200 Subject: [PATCH] added test and example app for AirQuality/environment sensors --- .../VINDSTYRKAAirQualitySensor.java | 65 +++++++++++++++++++ .../airquality/AirQualityMonitor.java | 55 ++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 dirigera-client-api/src/test/java/de/dvdgeisler/iot/dirigera/client/api/model/device/environmentsensor/VINDSTYRKAAirQualitySensor.java create mode 100644 dirigera-client-examples/src/main/java/de/dvdgeisler/iot/dirigera/client/examples/airquality/AirQualityMonitor.java diff --git a/dirigera-client-api/src/test/java/de/dvdgeisler/iot/dirigera/client/api/model/device/environmentsensor/VINDSTYRKAAirQualitySensor.java b/dirigera-client-api/src/test/java/de/dvdgeisler/iot/dirigera/client/api/model/device/environmentsensor/VINDSTYRKAAirQualitySensor.java new file mode 100644 index 0000000..5b1ea26 --- /dev/null +++ b/dirigera-client-api/src/test/java/de/dvdgeisler/iot/dirigera/client/api/model/device/environmentsensor/VINDSTYRKAAirQualitySensor.java @@ -0,0 +1,65 @@ +package de.dvdgeisler.iot.dirigera.client.api.model.device.environmentsensor; + +import de.dvdgeisler.iot.dirigera.client.api.model.device.Device; +import de.dvdgeisler.iot.dirigera.client.api.model.device.DeviceTest; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class VINDSTYRKAAirQualitySensor extends DeviceTest { + final static String JSON = """ + { + "id" : "XXXXXXXXXXXXXXXXXXX", + "type" : "sensor", + "deviceType" : "environmentSensor", + "createdAt" : "2023-03-10T13:23:42.000Z", + "isReachable" : true, + "lastSeen" : "2023-03-26T14:10:16.000Z", + "attributes" : { + "customName" : "Luftsensor", + "firmwareVersion" : "1.0.11", + "hardwareVersion" : "1", + "manufacturer" : "IKEA of Sweden", + "model" : "VINDSTYRKA", + "productCode" : "E2112", + "serialNumber" : "XXXXXXXXXXXX", + "currentTemperature" : 19, + "currentRH" : 52, + "currentPM25" : 2, + "maxMeasuredPM25" : 999, + "minMeasuredPM25" : 0, + "vocIndex" : 112, + "identifyPeriod" : 0, + "identifyStarted" : "2000-01-01T00:00:00.000Z", + "permittingJoin" : false, + "otaPolicy" : "autoUpdate", + "otaProgress" : 0, + "otaScheduleEnd" : "00:00", + "otaScheduleStart" : "00:00", + "otaState" : "readyToCheck", + "otaStatus" : "upToDate" + }, + "capabilities" : { + "canSend" : [ ], + "canReceive" : [ "customName" ] + }, + "room" : { + "id" : "255c7093-f8bc-4ea6-aa32-e352f673b716", + "name" : "Schlafzimmer ", + "color" : "ikea_yellow_no_24", + "icon" : "rooms_bed" + }, + "deviceSet" : [ ], + "remoteLinks" : [ ], + "isHidden" : false + } + """; + + public VINDSTYRKAAirQualitySensor() { + super(JSON); + } + + @Override + public void validateDeserialize(final Device device) { + assertTrue(device instanceof EnvironmentSensorDevice); + } +} \ No newline at end of file diff --git a/dirigera-client-examples/src/main/java/de/dvdgeisler/iot/dirigera/client/examples/airquality/AirQualityMonitor.java b/dirigera-client-examples/src/main/java/de/dvdgeisler/iot/dirigera/client/examples/airquality/AirQualityMonitor.java new file mode 100644 index 0000000..f92b640 --- /dev/null +++ b/dirigera-client-examples/src/main/java/de/dvdgeisler/iot/dirigera/client/examples/airquality/AirQualityMonitor.java @@ -0,0 +1,55 @@ +package de.dvdgeisler.iot.dirigera.client.examples.airquality; + +import de.dvdgeisler.iot.dirigera.client.api.DirigeraApi; +import de.dvdgeisler.iot.dirigera.client.api.model.device.DeviceType; +import de.dvdgeisler.iot.dirigera.client.api.model.device.environmentsensor.EnvironmentSensorDevice; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import reactor.core.publisher.Flux; + +/** + * Monitor air quality + */ +@SpringBootApplication +@ComponentScan(basePackageClasses = {DirigeraApi.class}) +@EnableScheduling +public class AirQualityMonitor { + private final static Logger log = LoggerFactory.getLogger(AirQualityMonitor.class); + + private final DirigeraApi api; + + public AirQualityMonitor(final DirigeraApi api) { + this.api = api; + } + + @Scheduled(fixedRate = 1000) + public void monitor() { + this.api.device.environmentSensor.all() + .flatMapMany(Flux::fromIterable) + .filter(d -> d.deviceType == DeviceType.ENVIRONMENT_SENSOR) + .cast(EnvironmentSensorDevice.class) + .doOnNext(this::printAirQualityData) + .blockLast(); + } + + private void printAirQualityData(final EnvironmentSensorDevice sensor) { + log.info("{}: Temperature={}, RelativeHumidity={}, PM25={}, VOC={}, isReachable={}", + sensor.attributes.state.customName != null && !sensor.attributes.state.customName.isBlank() ? sensor.attributes.state.customName : sensor.id, + sensor.attributes.currentTemperature, + sensor.attributes.currentRH, + sensor.attributes.currentPM25, + sensor.attributes.vocIndex, + sensor.isReachable); + } + + public static void main(String[] args) { + SpringApplication.run(AirQualityMonitor.class, args); + } + + +}