[airvisualnode] Support AirVisual Pro version (#8686)
* [airvisualnode] Support AirVisual Pro version * [airvisualnode] Autodetect Pro version * [airvisualnode] Remove unused channels Signed-off-by: Oleg Davydyuk <ilveann@gmail.com>
This commit is contained in:
parent
0eac453308
commit
6d2bb8a216
|
@ -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<String> 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<String> 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)));
|
||||
}
|
||||
|
|
|
@ -30,4 +30,6 @@ public class AirVisualNodeConfig {
|
|||
public String share;
|
||||
|
||||
public long refresh;
|
||||
|
||||
public boolean isProVersion;
|
||||
}
|
||||
|
|
|
@ -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<Channel> channels = new ArrayList<>(getThing().getChannels());
|
||||
channels.removeIf(channel -> channel.getLabel().equals("PM0.1") || channel.getLabel().equals("PM10"));
|
||||
replaceChannels(channels);
|
||||
}
|
||||
|
||||
private void replaceChannels(List<Channel> 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.
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
/**
|
|
@ -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.
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<PowerSavingTimeSlot> timeSlots = null;
|
||||
|
||||
private String mode;
|
||||
|
||||
private long runningTime;
|
||||
|
||||
@SerializedName("yes")
|
||||
private List<PowerSavingTime> times = null;
|
||||
|
||||
public PowerSaving(List<PowerSavingTimeSlot> timeSlots, String mode, long runningTime,
|
||||
List<PowerSavingTime> times) {
|
||||
this.mode = mode;
|
||||
this.runningTime = runningTime;
|
||||
this.times = times;
|
||||
this.timeSlots = timeSlots;
|
||||
}
|
||||
|
||||
public List<PowerSavingTimeSlot> getTimeSlots() {
|
||||
return timeSlots;
|
||||
}
|
||||
|
||||
public void setTimeSlots(List<PowerSavingTimeSlot> timeSlots) {
|
||||
this.timeSlots = timeSlots;
|
||||
}
|
||||
|
||||
public List<PowerSavingTime> getTimes() {
|
||||
return times;
|
||||
}
|
||||
|
||||
public void setTimes(List<PowerSavingTime> 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;
|
||||
}
|
||||
}
|
|
@ -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> measurements;
|
||||
private String serialNumber;
|
||||
private Settings settings;
|
||||
private Status status;
|
||||
|
||||
public ProNodeData(DateAndTime dateAndTime, List<Measurements> 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> 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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -14,7 +14,9 @@
|
|||
<channel id="co2" typeId="Co2"/>
|
||||
<channel id="humidity" typeId="Humidity"/>
|
||||
<channel id="aqi" typeId="Aqi"/>
|
||||
<channel id="pm_01" typeId="Pm_01"/>
|
||||
<channel id="pm_25" typeId="Pm_25"/>
|
||||
<channel id="pm_10" typeId="Pm_10"/>
|
||||
<channel id="temperature" typeId="Temperature"/>
|
||||
<channel id="timestamp" typeId="Timestamp"/>
|
||||
<channel id="used_memory" typeId="Used_memory"/>
|
||||
|
@ -90,6 +92,20 @@
|
|||
<state readOnly="true" pattern="%.1f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="Pm_10">
|
||||
<item-type>Number:Density</item-type>
|
||||
<label>PM10</label>
|
||||
<description>PM10 level, µg/m³(Only in Pro version)</description>
|
||||
<state readOnly="true" pattern="%.1f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="Pm_01">
|
||||
<item-type>Number:Density</item-type>
|
||||
<label>PM0.1</label>
|
||||
<description>PM0.1 level, µg/m³(Only in Pro version)</description>
|
||||
<state readOnly="true" pattern="%.1f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="Temperature">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Temperature</label>
|
||||
|
|
Loading…
Reference in New Issue