From 6d2bb8a21677f9c8cf550cec2d80f7e19292770d Mon Sep 17 00:00:00 2001 From: Oleg Davudyuk <19592644+ilveann@users.noreply.github.com> Date: Tue, 13 Oct 2020 02:46:27 +0300 Subject: [PATCH] [airvisualnode] Support AirVisual Pro version (#8686) * [airvisualnode] Support AirVisual Pro version * [airvisualnode] Autodetect Pro version * [airvisualnode] Remove unused channels Signed-off-by: Oleg Davydyuk --- .../AirVisualNodeBindingConstants.java | 9 +- .../internal/config/AirVisualNodeConfig.java | 2 + .../handler/AirVisualNodeHandler.java | 68 ++++++- .../internal/json/MeasurementsInterface.java | 43 +++++ .../internal/json/NodeDataInterface.java | 35 ++++ .../json/{ => airvisual}/Measurements.java | 16 +- .../json/{ => airvisual}/NodeData.java | 10 +- .../json/{ => airvisual}/PowerSaving.java | 5 +- .../json/{ => airvisual}/Settings.java | 2 +- .../internal/json/{ => airvisual}/Status.java | 2 +- .../json/airvisualpro/Measurements.java | 149 +++++++++++++++ .../json/airvisualpro/PowerSaving.java | 78 ++++++++ .../json/airvisualpro/ProNodeData.java | 84 +++++++++ .../json/airvisualpro/SensorLife.java | 35 ++++ .../json/airvisualpro/SensorMode.java | 46 +++++ .../internal/json/airvisualpro/Settings.java | 173 ++++++++++++++++++ .../internal/json/airvisualpro/Status.java | 157 ++++++++++++++++ .../resources/OH-INF/thing/thing-types.xml | 16 ++ 18 files changed, 909 insertions(+), 21 deletions(-) create mode 100644 bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/MeasurementsInterface.java create mode 100644 bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/NodeDataInterface.java rename bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/{ => airvisual}/Measurements.java (88%) rename bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/{ => airvisual}/NodeData.java (82%) rename bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/{ => airvisual}/PowerSaving.java (87%) rename bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/{ => airvisual}/Settings.java (98%) rename bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/{ => airvisual}/Status.java (97%) create mode 100644 bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Measurements.java create mode 100644 bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/PowerSaving.java create mode 100644 bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/ProNodeData.java create mode 100644 bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/SensorLife.java create mode 100644 bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/SensorMode.java create mode 100644 bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Settings.java create mode 100644 bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Status.java diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/AirVisualNodeBindingConstants.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/AirVisualNodeBindingConstants.java index 630fe8c0a76..8b27781a7b5 100644 --- a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/AirVisualNodeBindingConstants.java +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/AirVisualNodeBindingConstants.java @@ -40,6 +40,8 @@ public class AirVisualNodeBindingConstants { public static final String CHANNEL_HUMIDITY = "humidity"; public static final String CHANNEL_AQI_US = "aqi"; public static final String CHANNEL_PM_25 = "pm_25"; + public static final String CHANNEL_PM_10 = "pm_10"; + public static final String CHANNEL_PM_01 = "pm_01"; public static final String CHANNEL_TEMP_CELSIUS = "temperature"; public static final String CHANNEL_TIMESTAMP = "timestamp"; public static final String CHANNEL_USED_MEMORY = "used_memory"; @@ -53,7 +55,8 @@ public class AirVisualNodeBindingConstants { .unmodifiableSet(new HashSet<>(Arrays.asList(THING_TYPE_AVNODE))); // List of all supported Channel ids - public static final Set SUPPORTED_CHANNEL_IDS = Collections.unmodifiableSet(new HashSet<>( - Arrays.asList(CHANNEL_CO2, CHANNEL_HUMIDITY, CHANNEL_AQI_US, CHANNEL_PM_25, CHANNEL_TEMP_CELSIUS, - CHANNEL_BATTERY_LEVEL, CHANNEL_WIFI_STRENGTH, CHANNEL_TIMESTAMP, CHANNEL_USED_MEMORY))); + public static final Set SUPPORTED_CHANNEL_IDS = Collections + .unmodifiableSet(new HashSet<>(Arrays.asList(CHANNEL_CO2, CHANNEL_HUMIDITY, CHANNEL_AQI_US, CHANNEL_PM_25, + CHANNEL_PM_10, CHANNEL_PM_01, CHANNEL_TEMP_CELSIUS, CHANNEL_BATTERY_LEVEL, CHANNEL_WIFI_STRENGTH, + CHANNEL_TIMESTAMP, CHANNEL_USED_MEMORY))); } diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/config/AirVisualNodeConfig.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/config/AirVisualNodeConfig.java index 4a637c4746e..8e3dbef9237 100644 --- a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/config/AirVisualNodeConfig.java +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/config/AirVisualNodeConfig.java @@ -30,4 +30,6 @@ public class AirVisualNodeConfig { public String share; public long refresh; + + public boolean isProVersion; } diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/handler/AirVisualNodeHandler.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/handler/AirVisualNodeHandler.java index 1b22c18b40b..8a9cc0a302b 100644 --- a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/handler/AirVisualNodeHandler.java +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/handler/AirVisualNodeHandler.java @@ -29,11 +29,17 @@ import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.zone.ZoneRules; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import org.openhab.binding.airvisualnode.internal.config.AirVisualNodeConfig; -import org.openhab.binding.airvisualnode.internal.json.NodeData; +import org.openhab.binding.airvisualnode.internal.json.MeasurementsInterface; +import org.openhab.binding.airvisualnode.internal.json.NodeDataInterface; +import org.openhab.binding.airvisualnode.internal.json.airvisual.NodeData; +import org.openhab.binding.airvisualnode.internal.json.airvisualpro.ProNodeData; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.QuantityType; @@ -43,6 +49,7 @@ import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingStatus; import org.openhab.core.thing.ThingStatusDetail; import org.openhab.core.thing.binding.BaseThingHandler; +import org.openhab.core.thing.binding.builder.ThingBuilder; import org.openhab.core.types.Command; import org.openhab.core.types.RefreshType; import org.openhab.core.types.State; @@ -84,7 +91,9 @@ public class AirVisualNodeHandler extends BaseThingHandler { private String nodeShareName; - private NodeData nodeData; + private NodeDataInterface nodeData; + + private boolean isProVersion; public AirVisualNodeHandler(Thing thing) { super(thing); @@ -115,9 +124,33 @@ public class AirVisualNodeHandler extends BaseThingHandler { this.refreshInterval = config.refresh * 1000L; + try { + var jsonData = gson.fromJson(getNodeJsonData(), Map.class); + this.isProVersion = jsonData.get("measurements") instanceof ArrayList; + } catch (IOException e) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Can't get node json"); + return; + } + + if (!this.isProVersion) { + removeProChannels(); + } + schedulePoll(); } + private void removeProChannels() { + List channels = new ArrayList<>(getThing().getChannels()); + channels.removeIf(channel -> channel.getLabel().equals("PM0.1") || channel.getLabel().equals("PM10")); + replaceChannels(channels); + } + + private void replaceChannels(List channels) { + ThingBuilder thingBuilder = editThing(); + thingBuilder.withChannels(channels); + updateThing(thingBuilder.build()); + } + @Override public void handleCommand(ChannelUID channelUID, Command command) { if (command instanceof RefreshType) { @@ -163,7 +196,14 @@ public class AirVisualNodeHandler extends BaseThingHandler { private void pollNode() throws IOException { String jsonData = getNodeJsonData(); - NodeData currentNodeData = gson.fromJson(jsonData, NodeData.class); + + NodeDataInterface currentNodeData; + if (isProVersion) { + currentNodeData = gson.fromJson(jsonData, ProNodeData.class); + } else { + currentNodeData = gson.fromJson(jsonData, NodeData.class); + } + if (nodeData == null || currentNodeData.getStatus().getDatetime() > nodeData.getStatus().getDatetime()) { nodeData = currentNodeData; // Update all channels from the updated Node data @@ -189,7 +229,7 @@ public class AirVisualNodeHandler extends BaseThingHandler { } } - private State getChannelState(String channelId, NodeData nodeData) { + private State getChannelState(String channelId, NodeDataInterface nodeData) { State state = UnDefType.UNDEF; // Handle system channel IDs separately, because 'switch/case' expressions must be constant expressions @@ -199,24 +239,32 @@ public class AirVisualNodeHandler extends BaseThingHandler { state = new DecimalType( BigDecimal.valueOf(Math.max(0, nodeData.getStatus().getWifiStrength() - 1)).longValue()); } else { + MeasurementsInterface measurements = nodeData.getMeasurements(); // Handle binding-specific channel IDs switch (channelId) { case CHANNEL_CO2: - state = new QuantityType<>(nodeData.getMeasurements().getCo2Ppm(), PARTS_PER_MILLION); + state = new QuantityType<>(measurements.getCo2Ppm(), PARTS_PER_MILLION); break; case CHANNEL_HUMIDITY: - state = new QuantityType<>(nodeData.getMeasurements().getHumidityRH(), PERCENT); + state = new QuantityType<>(measurements.getHumidityRH(), PERCENT); break; case CHANNEL_AQI_US: - state = new QuantityType<>(nodeData.getMeasurements().getPm25AQIUS(), ONE); + state = new QuantityType<>(measurements.getPm25AQIUS(), ONE); break; case CHANNEL_PM_25: // PM2.5 is in ug/m3 - state = new QuantityType<>(nodeData.getMeasurements().getPm25Ugm3(), - MICRO(GRAM).divide(CUBIC_METRE)); + state = new QuantityType<>(measurements.getPm25Ugm3(), MICRO(GRAM).divide(CUBIC_METRE)); + break; + case CHANNEL_PM_10: + // PM10 is in ug/m3 + state = new QuantityType<>(measurements.getPm10Ugm3(), MICRO(GRAM).divide(CUBIC_METRE)); + break; + case CHANNEL_PM_01: + // PM0.1 is in ug/m3 + state = new QuantityType<>(measurements.getPm01Ugm3(), MICRO(GRAM).divide(CUBIC_METRE)); break; case CHANNEL_TEMP_CELSIUS: - state = new QuantityType<>(nodeData.getMeasurements().getTemperatureC(), CELSIUS); + state = new QuantityType<>(measurements.getTemperatureC(), CELSIUS); break; case CHANNEL_TIMESTAMP: // It seem the Node timestamp is Unix timestamp converted from UTC time plus timezone offset. diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/MeasurementsInterface.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/MeasurementsInterface.java new file mode 100644 index 00000000000..f6790438b15 --- /dev/null +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/MeasurementsInterface.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.airvisualnode.internal.json; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * Interface for AirVisual and AirVisual Pro models measurements data + * + * @author Oleg Davydyuk - Initial contribution + */ +@NonNullByDefault +public interface MeasurementsInterface { + int getCo2Ppm(); + + int getHumidityRH(); + + int getPm25AQICN(); + + int getPm25AQIUS(); + + float getPm01Ugm3(); + + float getPm10Ugm3(); + + float getPm25Ugm3(); + + float getTemperatureC(); + + float getTemperatureF(); + + int getVocPpb(); +} diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/NodeDataInterface.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/NodeDataInterface.java new file mode 100644 index 00000000000..8a7e5283831 --- /dev/null +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/NodeDataInterface.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.airvisualnode.internal.json; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.airvisualnode.internal.json.airvisual.Settings; +import org.openhab.binding.airvisualnode.internal.json.airvisual.Status; + +/** + * Interface for AirVisual and AirVisual Pro models + * + * @author Oleg Davydyuk - Initial contribution + */ +@NonNullByDefault +public interface NodeDataInterface { + DateAndTime getDateAndTime(); + + MeasurementsInterface getMeasurements(); + + String getSerialNumber(); + + Settings getSettings(); + + Status getStatus(); +} diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/Measurements.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/Measurements.java similarity index 88% rename from bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/Measurements.java rename to bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/Measurements.java index 62418e13d9c..395b5d01204 100644 --- a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/Measurements.java +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/Measurements.java @@ -10,7 +10,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.airvisualnode.internal.json; +package org.openhab.binding.airvisualnode.internal.json.airvisual; + +import org.openhab.binding.airvisualnode.internal.json.MeasurementsInterface; import com.google.gson.annotations.SerializedName; @@ -19,7 +21,7 @@ import com.google.gson.annotations.SerializedName; * * @author Victor Antonovich - Initial contribution */ -public class Measurements { +public class Measurements implements MeasurementsInterface { private int co2Ppm; @SerializedName("humidity_RH") @@ -79,6 +81,16 @@ public class Measurements { this.pm25AQIUS = pm25AQIUS; } + @Override + public float getPm01Ugm3() { + return 0; + } + + @Override + public float getPm10Ugm3() { + return 0; + } + public float getPm25Ugm3() { return pm25Ugm3; } diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/NodeData.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/NodeData.java similarity index 82% rename from bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/NodeData.java rename to bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/NodeData.java index 31175e5a60d..b2ca3dada4f 100644 --- a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/NodeData.java +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/NodeData.java @@ -10,14 +10,18 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.airvisualnode.internal.json; +package org.openhab.binding.airvisualnode.internal.json.airvisual; + +import org.openhab.binding.airvisualnode.internal.json.DateAndTime; +import org.openhab.binding.airvisualnode.internal.json.MeasurementsInterface; +import org.openhab.binding.airvisualnode.internal.json.NodeDataInterface; /** * Top level object for AirVisual Node JSON data. * * @author Victor Antonovich - Initial contribution */ -public class NodeData { +public class NodeData implements NodeDataInterface { private DateAndTime dateAndTime; private Measurements measurements; @@ -42,7 +46,7 @@ public class NodeData { this.dateAndTime = dateAndTime; } - public Measurements getMeasurements() { + public MeasurementsInterface getMeasurements() { return measurements; } diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/PowerSaving.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/PowerSaving.java similarity index 87% rename from bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/PowerSaving.java rename to bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/PowerSaving.java index 5a9dd81b89c..91d7955aef7 100644 --- a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/PowerSaving.java +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/PowerSaving.java @@ -10,10 +10,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.airvisualnode.internal.json; +package org.openhab.binding.airvisualnode.internal.json.airvisual; import java.util.List; +import org.openhab.binding.airvisualnode.internal.json.PowerSavingTime; +import org.openhab.binding.airvisualnode.internal.json.PowerSavingTimeSlot; + import com.google.gson.annotations.SerializedName; /** diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/Settings.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/Settings.java similarity index 98% rename from bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/Settings.java rename to bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/Settings.java index b8294b1a593..3bf18287b2a 100644 --- a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/Settings.java +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/Settings.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.airvisualnode.internal.json; +package org.openhab.binding.airvisualnode.internal.json.airvisual; /** * Settings data. diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/Status.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/Status.java similarity index 97% rename from bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/Status.java rename to bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/Status.java index f48c6e2dadd..dd3ac33d57d 100644 --- a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/Status.java +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisual/Status.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.airvisualnode.internal.json; +package org.openhab.binding.airvisualnode.internal.json.airvisual; /** * Status data. diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Measurements.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Measurements.java new file mode 100644 index 00000000000..26730736b6c --- /dev/null +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Measurements.java @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.airvisualnode.internal.json.airvisualpro; + +import org.openhab.binding.airvisualnode.internal.json.MeasurementsInterface; + +import com.google.gson.annotations.SerializedName; + +/** + * Measurements data. + * + * @author Victor Antonovich - Initial contribution + */ +public class Measurements implements MeasurementsInterface { + + @SerializedName("co2_ppm") + private int co2Ppm; + + @SerializedName("humidity_RH") + private int humidityRH; + + @SerializedName("pm25_AQICN") + private int pm25AQICN; + + @SerializedName("pm25_AQIUS") + private int pm25AQIUS; + + @SerializedName("pm01_ugm3") + private float pm01Ugm3; + + @SerializedName("pm25_ugm3") + private float pm25Ugm3; + + @SerializedName("pm10_ugm3") + private float pm10Ugm3; + + @SerializedName("temperature_C") + private float temperatureC; + + @SerializedName("temperature_F") + private float temperatureF; + + private int vocPpb; + + public Measurements(int co2Ppm, int humidityRH, int pm25AQICN, int pm25AQIUS, float pm01Ugm3, float pm10Ugm3, + float pm25Ugm3, float temperatureC, float temperatureF, int vocPpb) { + + this.co2Ppm = co2Ppm; + this.humidityRH = humidityRH; + this.pm25AQICN = pm25AQICN; + this.pm25AQIUS = pm25AQIUS; + this.pm01Ugm3 = pm01Ugm3; + this.pm10Ugm3 = pm10Ugm3; + this.pm25Ugm3 = pm25Ugm3; + this.temperatureC = temperatureC; + this.temperatureF = temperatureF; + this.vocPpb = vocPpb; + } + + public int getCo2Ppm() { + return co2Ppm; + } + + public void setCo2Ppm(int co2Ppm) { + this.co2Ppm = co2Ppm; + } + + public int getHumidityRH() { + return humidityRH; + } + + public void setHumidityRH(int humidityRH) { + this.humidityRH = humidityRH; + } + + public int getPm25AQICN() { + return pm25AQICN; + } + + public void setPm25AQICN(int pm25AQICN) { + this.pm25AQICN = pm25AQICN; + } + + public int getPm25AQIUS() { + return pm25AQIUS; + } + + public void setPm25AQIUS(int pm25AQIUS) { + this.pm25AQIUS = pm25AQIUS; + } + + public float getPm01Ugm3() { + return pm01Ugm3; + } + + public void setPm01Ugm3(float pm01Ugm3) { + this.pm01Ugm3 = pm01Ugm3; + } + + public float getPm10Ugm3() { + return pm10Ugm3; + } + + public void setPm10Ugm3(float pm10Ugm3) { + this.pm10Ugm3 = pm10Ugm3; + } + + public float getPm25Ugm3() { + return pm25Ugm3; + } + + public void setPm25Ugm3(float pm25Ugm3) { + this.pm25Ugm3 = pm25Ugm3; + } + + public float getTemperatureC() { + return temperatureC; + } + + public void setTemperatureC(float temperatureC) { + this.temperatureC = temperatureC; + } + + public float getTemperatureF() { + return temperatureF; + } + + public void setTemperatureF(float temperatureF) { + this.temperatureF = temperatureF; + } + + public int getVocPpb() { + return vocPpb; + } + + public void setVocPpb(int vocPpb) { + this.vocPpb = vocPpb; + } +} diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/PowerSaving.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/PowerSaving.java new file mode 100644 index 00000000000..d4ba72d541d --- /dev/null +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/PowerSaving.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.airvisualnode.internal.json.airvisualpro; + +import java.util.List; + +import org.openhab.binding.airvisualnode.internal.json.PowerSavingTime; +import org.openhab.binding.airvisualnode.internal.json.PowerSavingTimeSlot; + +import com.google.gson.annotations.SerializedName; + +/** + * Power saving data. + * + * @author Victor Antonovich - Initial contribution + */ +public class PowerSaving { + + @SerializedName("2slots") + private List timeSlots = null; + + private String mode; + + private long runningTime; + + @SerializedName("yes") + private List times = null; + + public PowerSaving(List timeSlots, String mode, long runningTime, + List times) { + this.mode = mode; + this.runningTime = runningTime; + this.times = times; + this.timeSlots = timeSlots; + } + + public List getTimeSlots() { + return timeSlots; + } + + public void setTimeSlots(List timeSlots) { + this.timeSlots = timeSlots; + } + + public List getTimes() { + return times; + } + + public void setTimes(List times) { + this.times = times; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public long getRunningTime() { + return runningTime; + } + + public void setRunningTime(long runningTime) { + this.runningTime = runningTime; + } +} diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/ProNodeData.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/ProNodeData.java new file mode 100644 index 00000000000..6f0e97defcd --- /dev/null +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/ProNodeData.java @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.airvisualnode.internal.json.airvisualpro; + +import java.util.List; + +import org.openhab.binding.airvisualnode.internal.json.DateAndTime; +import org.openhab.binding.airvisualnode.internal.json.MeasurementsInterface; +import org.openhab.binding.airvisualnode.internal.json.NodeDataInterface; +import org.openhab.binding.airvisualnode.internal.json.airvisual.Settings; +import org.openhab.binding.airvisualnode.internal.json.airvisual.Status; + +/** + * Top level object for AirVisual Node JSON data. + * + * @author Victor Antonovich - Initial contribution + */ +public class ProNodeData implements NodeDataInterface { + + private DateAndTime dateAndTime; + private List measurements; + private String serialNumber; + private Settings settings; + private Status status; + + public ProNodeData(DateAndTime dateAndTime, List measurements, String serialNumber, Settings settings, + Status status) { + this.dateAndTime = dateAndTime; + this.measurements = measurements; + this.serialNumber = serialNumber; + this.settings = settings; + this.status = status; + } + + public DateAndTime getDateAndTime() { + return dateAndTime; + } + + public void setDateAndTime(DateAndTime dateAndTime) { + this.dateAndTime = dateAndTime; + } + + public MeasurementsInterface getMeasurements() { + return measurements.get(0); + } + + public void setMeasurements(List measurements) { + this.measurements = measurements; + } + + public String getSerialNumber() { + return serialNumber; + } + + public void setSerialNumber(String serialNumber) { + this.serialNumber = serialNumber; + } + + public Settings getSettings() { + return settings; + } + + public void setSettings(Settings settings) { + this.settings = settings; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } +} diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/SensorLife.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/SensorLife.java new file mode 100644 index 00000000000..cdd4f0f6f36 --- /dev/null +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/SensorLife.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.airvisualnode.internal.json.airvisualpro; + +/** + * Sensor Usage/Life data + * + * @author Oleg Davydyuk - Initial contribution + */ +public class SensorLife { + + private long pm25; + + public SensorLife(long pm25) { + this.pm25 = pm25; + } + + public long getPm25() { + return pm25; + } + + public void setPm25(long pm25) { + this.pm25 = pm25; + } +} diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/SensorMode.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/SensorMode.java new file mode 100644 index 00000000000..6d6d8026933 --- /dev/null +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/SensorMode.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.airvisualnode.internal.json.airvisualpro; + +/** + * Sensor Operating Mode + * + * @author Oleg Davydyuk - Initial contribution + */ +public class SensorMode { + + private long customModeInterval; + + private long mode; + + public SensorMode(long customModeInterval, long mode) { + this.customModeInterval = customModeInterval; + this.mode = mode; + } + + public long getCustomModeInterval() { + return customModeInterval; + } + + public void setCustomModeInterval(long customModeInterval) { + this.customModeInterval = customModeInterval; + } + + public long getMode() { + return mode; + } + + public void setMode(long mode) { + this.mode = mode; + } +} diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Settings.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Settings.java new file mode 100644 index 00000000000..c3c050755ea --- /dev/null +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Settings.java @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.airvisualnode.internal.json.airvisualpro; + +import org.openhab.binding.airvisualnode.internal.json.airvisual.PowerSaving; + +/** + * Settings data. + * + * @author Victor Antonovich - Initial contribution + */ +public class Settings { + + private String followMode; + private String followedStation; + private boolean isAqiUsa; + private boolean isConcentrationShowed; + private boolean isIndoor; + private boolean isLcdOn; + private boolean isNetworkTime; + private boolean isTemperatureCelsius; + private String language; + private int lcdBrightness; + private String nodeName; + private PowerSaving powerSaving; + private SensorMode sensorMode; + private String speedUnit; + private String timezone; + + public Settings(String followMode, String followedStation, boolean isAqiUsa, boolean isConcentrationShowed, + boolean isIndoor, boolean isLcdOn, boolean isNetworkTime, boolean isTemperatureCelsius, String language, + int lcdBrightness, String nodeName, PowerSaving powerSaving, SensorMode sensorMode, String speedUnit, + String timezone) { + + this.followMode = followMode; + this.followedStation = followedStation; + this.isAqiUsa = isAqiUsa; + this.isConcentrationShowed = isConcentrationShowed; + this.isIndoor = isIndoor; + this.isLcdOn = isLcdOn; + this.isNetworkTime = isNetworkTime; + this.isTemperatureCelsius = isTemperatureCelsius; + this.language = language; + this.lcdBrightness = lcdBrightness; + this.nodeName = nodeName; + this.powerSaving = powerSaving; + this.sensorMode = sensorMode; + this.speedUnit = speedUnit; + this.timezone = timezone; + } + + public String getFollowMode() { + return followMode; + } + + public void setFollowMode(String followMode) { + this.followMode = followMode; + } + + public String getFollowedStation() { + return followedStation; + } + + public void setFollowedStation(String followedStation) { + this.followedStation = followedStation; + } + + public boolean isIsAqiUsa() { + return isAqiUsa; + } + + public void setIsAqiUsa(boolean isAqiUsa) { + this.isAqiUsa = isAqiUsa; + } + + public boolean isIsConcentrationShowed() { + return isConcentrationShowed; + } + + public void setIsConcentrationShowed(boolean isConcentrationShowed) { + this.isConcentrationShowed = isConcentrationShowed; + } + + public boolean isIsIndoor() { + return isIndoor; + } + + public void setIsIndoor(boolean isIndoor) { + this.isIndoor = isIndoor; + } + + public boolean isIsLcdOn() { + return isLcdOn; + } + + public void setIsLcdOn(boolean isLcdOn) { + this.isLcdOn = isLcdOn; + } + + public boolean isIsNetworkTime() { + return isNetworkTime; + } + + public void setIsNetworkTime(boolean isNetworkTime) { + this.isNetworkTime = isNetworkTime; + } + + public boolean isIsTemperatureCelsius() { + return isTemperatureCelsius; + } + + public void setIsTemperatureCelsius(boolean isTemperatureCelsius) { + this.isTemperatureCelsius = isTemperatureCelsius; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public int getLcdBrightness() { + return lcdBrightness; + } + + public void setLcdBrightness(int lcdBrightness) { + this.lcdBrightness = lcdBrightness; + } + + public String getNodeName() { + return nodeName; + } + + public void setNodeName(String nodeName) { + this.nodeName = nodeName; + } + + public PowerSaving getPowerSaving() { + return powerSaving; + } + + public void setPowerSaving(PowerSaving powerSaving) { + this.powerSaving = powerSaving; + } + + public String getSpeedUnit() { + return speedUnit; + } + + public void setSpeedUnit(String speedUnit) { + this.speedUnit = speedUnit; + } + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } +} diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Status.java b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Status.java new file mode 100644 index 00000000000..9c8cb4290fa --- /dev/null +++ b/bundles/org.openhab.binding.airvisualnode/src/main/java/org/openhab/binding/airvisualnode/internal/json/airvisualpro/Status.java @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.airvisualnode.internal.json.airvisualpro; + +/** + * Status data. + * + * @author Victor Antonovich - Initial contribution + */ +public class Status { + + private String appVersion; + private int battery; + private long datetime; + private String deviceName; + private String ipAddress; + private String macAddress; + private String model; + private SensorLife sensorLife; + private String sensorPm25Serial; + private int syncTime; + private String systemVersion; + private int usedMemory; + private int wifiStrength; + + public Status(String appVersion, int battery, long datetime, String deviceName, String ipAddress, String macAddress, + String model, SensorLife sensorLife, String sensorPm25Serial, int syncTime, String systemVersion, + int usedMemory, int wifiStrength) { + this.appVersion = appVersion; + this.battery = battery; + this.datetime = datetime; + this.deviceName = deviceName; + this.ipAddress = ipAddress; + this.macAddress = macAddress; + this.model = model; + this.sensorLife = sensorLife; + this.sensorPm25Serial = sensorPm25Serial; + this.syncTime = syncTime; + this.systemVersion = systemVersion; + this.usedMemory = usedMemory; + this.wifiStrength = wifiStrength; + } + + public String getAppVersion() { + return appVersion; + } + + public void setAppVersion(String appVersion) { + this.appVersion = appVersion; + } + + public int getBattery() { + return battery; + } + + public void setBattery(int battery) { + this.battery = battery; + } + + public long getDatetime() { + return datetime; + } + + public void setDatetime(long datetime) { + this.datetime = datetime; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getIpAddress() { + return ipAddress; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + + public String getMacAddress() { + return macAddress; + } + + public void setMacAddress(String macAddress) { + this.macAddress = macAddress; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public SensorLife getSensorLife() { + return sensorLife; + } + + public void setSensorLife(SensorLife sensorLife) { + this.sensorLife = sensorLife; + } + + public String getSensorPm25Serial() { + return sensorPm25Serial; + } + + public void setSensorPm25Serial(String sensorPm25Serial) { + this.sensorPm25Serial = sensorPm25Serial; + } + + public int getSyncTime() { + return syncTime; + } + + public void setSyncTime(int syncTime) { + this.syncTime = syncTime; + } + + public String getSystemVersion() { + return systemVersion; + } + + public void setSystemVersion(String systemVersion) { + this.systemVersion = systemVersion; + } + + public int getUsedMemory() { + return usedMemory; + } + + public void setUsedMemory(int usedMemory) { + this.usedMemory = usedMemory; + } + + public int getWifiStrength() { + return wifiStrength; + } + + public void setWifiStrength(int wifiStrength) { + this.wifiStrength = wifiStrength; + } +} diff --git a/bundles/org.openhab.binding.airvisualnode/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.airvisualnode/src/main/resources/OH-INF/thing/thing-types.xml index 7fc108b8f80..23a85d0d973 100644 --- a/bundles/org.openhab.binding.airvisualnode/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.airvisualnode/src/main/resources/OH-INF/thing/thing-types.xml @@ -14,7 +14,9 @@ + + @@ -90,6 +92,20 @@ + + Number:Density + + PM10 level, µg/m³(Only in Pro version) + + + + + Number:Density + + PM0.1 level, µg/m³(Only in Pro version) + + + Number:Temperature