[airvisualnode] Add null annotations (#13895)
* Add null annotation Signed-off-by: Leo Siepel <leosiepel@gmail.com>
This commit is contained in:
parent
88c0b720c6
commit
1c5b794145
|
@ -14,6 +14,7 @@ package org.openhab.binding.airvisualnode.internal;
|
||||||
|
|
||||||
import static org.openhab.binding.airvisualnode.internal.AirVisualNodeBindingConstants.*;
|
import static org.openhab.binding.airvisualnode.internal.AirVisualNodeBindingConstants.*;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.airvisualnode.internal.handler.AirVisualNodeHandler;
|
import org.openhab.binding.airvisualnode.internal.handler.AirVisualNodeHandler;
|
||||||
import org.openhab.core.thing.Thing;
|
import org.openhab.core.thing.Thing;
|
||||||
|
@ -29,6 +30,7 @@ import org.osgi.service.component.annotations.Component;
|
||||||
*
|
*
|
||||||
* @author Victor Antonovich - Initial contribution
|
* @author Victor Antonovich - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.airvisualnode")
|
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.airvisualnode")
|
||||||
public class AirVisualNodeHandlerFactory extends BaseThingHandlerFactory {
|
public class AirVisualNodeHandlerFactory extends BaseThingHandlerFactory {
|
||||||
|
|
||||||
|
|
|
@ -12,22 +12,25 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.config;
|
package org.openhab.binding.airvisualnode.internal.config;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for AirVisual Node.
|
* Configuration for AirVisual Node.
|
||||||
*
|
*
|
||||||
* @author Victor Antonovich - Initial contribution
|
* @author Victor Antonovich - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class AirVisualNodeConfig {
|
public class AirVisualNodeConfig {
|
||||||
|
|
||||||
public static final String ADDRESS = "address";
|
public static final String ADDRESS = "address";
|
||||||
|
|
||||||
public String address;
|
public String address = "";
|
||||||
|
|
||||||
public String username;
|
public String username = "";
|
||||||
|
|
||||||
public String password;
|
public String password = "";
|
||||||
|
|
||||||
public String share;
|
public String share = "";
|
||||||
|
|
||||||
public long refresh;
|
public long refresh;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.airvisualnode.internal.AirVisualNodeBindingConstants;
|
import org.openhab.binding.airvisualnode.internal.AirVisualNodeBindingConstants;
|
||||||
import org.openhab.binding.airvisualnode.internal.config.AirVisualNodeConfig;
|
import org.openhab.binding.airvisualnode.internal.config.AirVisualNodeConfig;
|
||||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||||
|
@ -39,16 +41,18 @@ import jcifs.smb.SmbFile;
|
||||||
*
|
*
|
||||||
* @author Victor Antonovich - Initial contribution
|
* @author Victor Antonovich - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
@Component(service = DiscoveryService.class)
|
@Component(service = DiscoveryService.class)
|
||||||
public class AirVisualNodeDiscoveryService extends AbstractDiscoveryService {
|
public class AirVisualNodeDiscoveryService extends AbstractDiscoveryService {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(AirVisualNodeDiscoveryService.class);
|
private final Logger logger = LoggerFactory.getLogger(AirVisualNodeDiscoveryService.class);
|
||||||
|
private static final int REFRESH_MINUTES = 5;
|
||||||
|
|
||||||
public static final String AVISUAL_WORKGROUP_NAME = "MSHOME";
|
public static final String AVISUAL_WORKGROUP_NAME = "MSHOME";
|
||||||
|
|
||||||
private static final Pattern AVISUAL_NAME_PATTERN = Pattern.compile("^AVISUAL-([^/]+)$");
|
private static final Pattern AVISUAL_NAME_PATTERN = Pattern.compile("^AVISUAL-([^/]+)$");
|
||||||
|
|
||||||
private ScheduledFuture<?> backgroundDiscoveryFuture;
|
private @Nullable ScheduledFuture<?> backgroundDiscoveryFuture;
|
||||||
|
|
||||||
public AirVisualNodeDiscoveryService() {
|
public AirVisualNodeDiscoveryService() {
|
||||||
super(Collections.singleton(AirVisualNodeBindingConstants.THING_TYPE_AVNODE), 600, true);
|
super(Collections.singleton(AirVisualNodeBindingConstants.THING_TYPE_AVNODE), 600, true);
|
||||||
|
@ -63,19 +67,20 @@ public class AirVisualNodeDiscoveryService extends AbstractDiscoveryService {
|
||||||
@Override
|
@Override
|
||||||
protected void startBackgroundDiscovery() {
|
protected void startBackgroundDiscovery() {
|
||||||
logger.debug("Starting background discovery");
|
logger.debug("Starting background discovery");
|
||||||
backgroundDiscoveryFuture = scheduler.scheduleWithFixedDelay(this::scan, 0, 5, TimeUnit.MINUTES);
|
ScheduledFuture<?> localDiscoveryFuture = backgroundDiscoveryFuture;
|
||||||
|
if (localDiscoveryFuture == null || localDiscoveryFuture.isCancelled()) {
|
||||||
|
backgroundDiscoveryFuture = scheduler.scheduleWithFixedDelay(this::scan, 0, REFRESH_MINUTES,
|
||||||
|
TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void stopBackgroundDiscovery() {
|
protected void stopBackgroundDiscovery() {
|
||||||
logger.debug("Stopping background discovery");
|
logger.debug("Stopping background discovery");
|
||||||
cancelBackgroundDiscoveryFuture();
|
|
||||||
super.stopBackgroundDiscovery();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancelBackgroundDiscoveryFuture() {
|
ScheduledFuture<?> localDiscoveryFuture = backgroundDiscoveryFuture;
|
||||||
if (backgroundDiscoveryFuture != null && !backgroundDiscoveryFuture.isDone()) {
|
if (localDiscoveryFuture != null) {
|
||||||
backgroundDiscoveryFuture.cancel(true);
|
localDiscoveryFuture.cancel(true);
|
||||||
backgroundDiscoveryFuture = null;
|
backgroundDiscoveryFuture = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +92,7 @@ public class AirVisualNodeDiscoveryService extends AbstractDiscoveryService {
|
||||||
String workgroupUrl = "smb://" + AVISUAL_WORKGROUP_NAME + "/";
|
String workgroupUrl = "smb://" + AVISUAL_WORKGROUP_NAME + "/";
|
||||||
workgroupMembers = new SmbFile(workgroupUrl).listFiles();
|
workgroupMembers = new SmbFile(workgroupUrl).listFiles();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// Can't get workgroup member list
|
logger.debug("IOException while trying to get workgroup member list", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +110,10 @@ public class AirVisualNodeDiscoveryService extends AbstractDiscoveryService {
|
||||||
// Extract the Node serial number from device name
|
// Extract the Node serial number from device name
|
||||||
String nodeSerialNumber = m.group(1);
|
String nodeSerialNumber = m.group(1);
|
||||||
|
|
||||||
|
if (nodeSerialNumber != null) {
|
||||||
|
logger.debug("Extracting the Node serial number failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
// The Node Thing UID is serial number converted to lower case
|
// The Node Thing UID is serial number converted to lower case
|
||||||
ThingUID thingUID = new ThingUID(AirVisualNodeBindingConstants.THING_TYPE_AVNODE,
|
ThingUID thingUID = new ThingUID(AirVisualNodeBindingConstants.THING_TYPE_AVNODE,
|
||||||
nodeSerialNumber.toLowerCase());
|
nodeSerialNumber.toLowerCase());
|
||||||
|
@ -119,14 +128,19 @@ public class AirVisualNodeDiscoveryService extends AbstractDiscoveryService {
|
||||||
|
|
||||||
// Create discovery result
|
// Create discovery result
|
||||||
String nodeAddress = nodeNbtAddress.getInetAddress().getHostAddress();
|
String nodeAddress = nodeNbtAddress.getInetAddress().getHostAddress();
|
||||||
DiscoveryResult result = DiscoveryResultBuilder.create(thingUID)
|
if (nodeAddress != null) {
|
||||||
.withProperty(AirVisualNodeConfig.ADDRESS, nodeAddress)
|
DiscoveryResult result = DiscoveryResultBuilder.create(thingUID)
|
||||||
.withRepresentationProperty(AirVisualNodeConfig.ADDRESS)
|
.withProperty(AirVisualNodeConfig.ADDRESS, nodeAddress)
|
||||||
.withLabel("AirVisual Node (" + nodeSerialNumber + ")").build();
|
.withRepresentationProperty(AirVisualNodeConfig.ADDRESS)
|
||||||
thingDiscovered(result);
|
.withLabel("AirVisual Node (" + nodeSerialNumber + ")").build();
|
||||||
|
thingDiscovered(result);
|
||||||
|
} else {
|
||||||
|
logger.debug("Getting the node address from the host failed");
|
||||||
|
}
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
logger.debug("The Node address resolving failed ", e);
|
logger.debug("The Node address resolving failed ", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json;
|
package org.openhab.binding.airvisualnode.internal.dto;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date and time / timestamp data.
|
* Date and time / timestamp data.
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json;
|
package org.openhab.binding.airvisualnode.internal.dto;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json;
|
package org.openhab.binding.airvisualnode.internal.dto;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.airvisual.Settings;
|
import org.openhab.binding.airvisualnode.internal.dto.airvisual.Settings;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.airvisual.Status;
|
import org.openhab.binding.airvisualnode.internal.dto.airvisual.Status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for AirVisual and AirVisual Pro models
|
* Interface for AirVisual and AirVisual Pro models
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json;
|
package org.openhab.binding.airvisualnode.internal.dto;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Power saving time data.
|
* Power saving time data.
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json;
|
package org.openhab.binding.airvisualnode.internal.dto;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Power saving time slot data.
|
* Power saving time slot data.
|
|
@ -10,9 +10,9 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisual;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisual;
|
||||||
|
|
||||||
import org.openhab.binding.airvisualnode.internal.json.MeasurementsInterface;
|
import org.openhab.binding.airvisualnode.internal.dto.MeasurementsInterface;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
|
@ -10,17 +10,19 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisual;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisual;
|
||||||
|
|
||||||
import org.openhab.binding.airvisualnode.internal.json.DateAndTime;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.MeasurementsInterface;
|
import org.openhab.binding.airvisualnode.internal.dto.DateAndTime;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.NodeDataInterface;
|
import org.openhab.binding.airvisualnode.internal.dto.MeasurementsInterface;
|
||||||
|
import org.openhab.binding.airvisualnode.internal.dto.NodeDataInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top level object for AirVisual Node JSON data.
|
* Top level object for AirVisual Node JSON data.
|
||||||
*
|
*
|
||||||
* @author Victor Antonovich - Initial contribution
|
* @author Victor Antonovich - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class NodeData implements NodeDataInterface {
|
public class NodeData implements NodeDataInterface {
|
||||||
|
|
||||||
private DateAndTime dateAndTime;
|
private DateAndTime dateAndTime;
|
|
@ -10,12 +10,12 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisual;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisual;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.openhab.binding.airvisualnode.internal.json.PowerSavingTime;
|
import org.openhab.binding.airvisualnode.internal.dto.PowerSavingTime;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.PowerSavingTimeSlot;
|
import org.openhab.binding.airvisualnode.internal.dto.PowerSavingTimeSlot;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisual;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisual;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings data.
|
* Settings data.
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisual;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisual;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Status data.
|
* Status data.
|
|
@ -10,9 +10,9 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisualpro;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisualpro;
|
||||||
|
|
||||||
import org.openhab.binding.airvisualnode.internal.json.MeasurementsInterface;
|
import org.openhab.binding.airvisualnode.internal.dto.MeasurementsInterface;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
@ -54,7 +54,6 @@ public class Measurements implements MeasurementsInterface {
|
||||||
|
|
||||||
public Measurements(int co2Ppm, int humidityRH, int pm25AQICN, int pm25AQIUS, float pm01Ugm3, float pm10Ugm3,
|
public Measurements(int co2Ppm, int humidityRH, int pm25AQICN, int pm25AQIUS, float pm01Ugm3, float pm10Ugm3,
|
||||||
float pm25Ugm3, float temperatureC, float temperatureF, int vocPpb) {
|
float pm25Ugm3, float temperatureC, float temperatureF, int vocPpb) {
|
||||||
|
|
||||||
this.co2Ppm = co2Ppm;
|
this.co2Ppm = co2Ppm;
|
||||||
this.humidityRH = humidityRH;
|
this.humidityRH = humidityRH;
|
||||||
this.pm25AQICN = pm25AQICN;
|
this.pm25AQICN = pm25AQICN;
|
|
@ -10,12 +10,12 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisualpro;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisualpro;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.openhab.binding.airvisualnode.internal.json.PowerSavingTime;
|
import org.openhab.binding.airvisualnode.internal.dto.PowerSavingTime;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.PowerSavingTimeSlot;
|
import org.openhab.binding.airvisualnode.internal.dto.PowerSavingTimeSlot;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
|
@ -10,21 +10,23 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisualpro;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisualpro;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.openhab.binding.airvisualnode.internal.json.DateAndTime;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.MeasurementsInterface;
|
import org.openhab.binding.airvisualnode.internal.dto.DateAndTime;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.NodeDataInterface;
|
import org.openhab.binding.airvisualnode.internal.dto.MeasurementsInterface;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.airvisual.Settings;
|
import org.openhab.binding.airvisualnode.internal.dto.NodeDataInterface;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.airvisual.Status;
|
import org.openhab.binding.airvisualnode.internal.dto.airvisual.Settings;
|
||||||
|
import org.openhab.binding.airvisualnode.internal.dto.airvisual.Status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top level object for AirVisual Node JSON data.
|
* Top level object for AirVisual Node JSON data.
|
||||||
*
|
*
|
||||||
* @author Victor Antonovich - Initial contribution
|
* @author Victor Antonovich - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class ProNodeData implements NodeDataInterface {
|
public class ProNodeData implements NodeDataInterface {
|
||||||
|
|
||||||
private DateAndTime dateAndTime;
|
private DateAndTime dateAndTime;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisualpro;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisualpro;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sensor Usage/Life data
|
* Sensor Usage/Life data
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisualpro;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisualpro;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sensor Operating Mode
|
* Sensor Operating Mode
|
|
@ -10,9 +10,9 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisualpro;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisualpro;
|
||||||
|
|
||||||
import org.openhab.binding.airvisualnode.internal.json.airvisual.PowerSaving;
|
import org.openhab.binding.airvisualnode.internal.dto.airvisual.PowerSaving;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings data.
|
* Settings data.
|
||||||
|
@ -41,7 +41,6 @@ public class Settings {
|
||||||
boolean isIndoor, boolean isLcdOn, boolean isNetworkTime, boolean isTemperatureCelsius, String language,
|
boolean isIndoor, boolean isLcdOn, boolean isNetworkTime, boolean isTemperatureCelsius, String language,
|
||||||
int lcdBrightness, String nodeName, PowerSaving powerSaving, SensorMode sensorMode, String speedUnit,
|
int lcdBrightness, String nodeName, PowerSaving powerSaving, SensorMode sensorMode, String speedUnit,
|
||||||
String timezone) {
|
String timezone) {
|
||||||
|
|
||||||
this.followMode = followMode;
|
this.followMode = followMode;
|
||||||
this.followedStation = followedStation;
|
this.followedStation = followedStation;
|
||||||
this.isAqiUsa = isAqiUsa;
|
this.isAqiUsa = isAqiUsa;
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.airvisualnode.internal.json.airvisualpro;
|
package org.openhab.binding.airvisualnode.internal.dto.airvisualpro;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Status data.
|
* Status data.
|
|
@ -35,11 +35,13 @@ import java.util.Map;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.airvisualnode.internal.config.AirVisualNodeConfig;
|
import org.openhab.binding.airvisualnode.internal.config.AirVisualNodeConfig;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.MeasurementsInterface;
|
import org.openhab.binding.airvisualnode.internal.dto.MeasurementsInterface;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.NodeDataInterface;
|
import org.openhab.binding.airvisualnode.internal.dto.NodeDataInterface;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.airvisual.NodeData;
|
import org.openhab.binding.airvisualnode.internal.dto.airvisual.NodeData;
|
||||||
import org.openhab.binding.airvisualnode.internal.json.airvisualpro.ProNodeData;
|
import org.openhab.binding.airvisualnode.internal.dto.airvisualpro.ProNodeData;
|
||||||
import org.openhab.core.library.types.DateTimeType;
|
import org.openhab.core.library.types.DateTimeType;
|
||||||
import org.openhab.core.library.types.DecimalType;
|
import org.openhab.core.library.types.DecimalType;
|
||||||
import org.openhab.core.library.types.QuantityType;
|
import org.openhab.core.library.types.QuantityType;
|
||||||
|
@ -71,29 +73,23 @@ import jcifs.smb.SmbFileInputStream;
|
||||||
*
|
*
|
||||||
* @author Victor Antonovich - Initial contribution
|
* @author Victor Antonovich - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class AirVisualNodeHandler extends BaseThingHandler {
|
public class AirVisualNodeHandler extends BaseThingHandler {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(AirVisualNodeHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(AirVisualNodeHandler.class);
|
||||||
|
|
||||||
public static final String NODE_JSON_FILE = "latest_config_measurements.json";
|
public static final String NODE_JSON_FILE = "latest_config_measurements.json";
|
||||||
|
private static final long DELAY_IN_MS = 500;
|
||||||
|
|
||||||
private final Gson gson;
|
private final Gson gson;
|
||||||
|
private @Nullable ScheduledFuture<?> pollFuture;
|
||||||
private ScheduledFuture<?> pollFuture;
|
|
||||||
|
|
||||||
private long refreshInterval;
|
private long refreshInterval;
|
||||||
|
private String nodeAddress = "";
|
||||||
private String nodeAddress;
|
private String nodeUsername = "";
|
||||||
|
private String nodePassword = "";
|
||||||
private String nodeUsername;
|
private String nodeShareName = "";
|
||||||
|
private @Nullable NodeDataInterface nodeData;
|
||||||
private String nodePassword;
|
private boolean isProVersion = false;
|
||||||
|
|
||||||
private String nodeShareName;
|
|
||||||
|
|
||||||
private NodeDataInterface nodeData;
|
|
||||||
|
|
||||||
private boolean isProVersion;
|
|
||||||
|
|
||||||
public AirVisualNodeHandler(Thing thing) {
|
public AirVisualNodeHandler(Thing thing) {
|
||||||
super(thing);
|
super(thing);
|
||||||
|
@ -106,22 +102,19 @@ public class AirVisualNodeHandler extends BaseThingHandler {
|
||||||
|
|
||||||
AirVisualNodeConfig config = getConfigAs(AirVisualNodeConfig.class);
|
AirVisualNodeConfig config = getConfigAs(AirVisualNodeConfig.class);
|
||||||
|
|
||||||
if (config.address == null) {
|
if (config.address.isBlank()) {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Node address must be set");
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Node address must be set");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.nodeAddress = config.address;
|
if (config.password.isBlank()) {
|
||||||
|
|
||||||
this.nodeUsername = config.username;
|
|
||||||
|
|
||||||
if (config.password == null) {
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Node password must be set");
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Node password must be set");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.nodeAddress = config.address;
|
||||||
|
this.nodeUsername = config.username;
|
||||||
this.nodePassword = config.password;
|
this.nodePassword = config.password;
|
||||||
|
|
||||||
this.nodeShareName = config.share;
|
this.nodeShareName = config.share;
|
||||||
|
|
||||||
this.refreshInterval = config.refresh * 1000L;
|
this.refreshInterval = config.refresh * 1000L;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -141,10 +134,17 @@ public class AirVisualNodeHandler extends BaseThingHandler {
|
||||||
|
|
||||||
private void removeProChannels() {
|
private void removeProChannels() {
|
||||||
List<Channel> channels = new ArrayList<>(getThing().getChannels());
|
List<Channel> channels = new ArrayList<>(getThing().getChannels());
|
||||||
channels.removeIf(channel -> channel.getLabel().equals("PM0.1") || channel.getLabel().equals("PM10"));
|
channels.removeIf(channel -> isProChannel(channel.getLabel()));
|
||||||
replaceChannels(channels);
|
replaceChannels(channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isProChannel(@Nullable String channelLabel) {
|
||||||
|
if (channelLabel == null || channelLabel.isBlank()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return "PM0.1".equals(channelLabel) || "PM10".equals(channelLabel);
|
||||||
|
}
|
||||||
|
|
||||||
private void replaceChannels(List<Channel> channels) {
|
private void replaceChannels(List<Channel> channels) {
|
||||||
ThingBuilder thingBuilder = editThing();
|
ThingBuilder thingBuilder = editThing();
|
||||||
thingBuilder.withChannels(channels);
|
thingBuilder.withChannels(channels);
|
||||||
|
@ -173,14 +173,15 @@ public class AirVisualNodeHandler extends BaseThingHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void stopPoll() {
|
private synchronized void stopPoll() {
|
||||||
if (pollFuture != null && !pollFuture.isCancelled()) {
|
ScheduledFuture<?> localFuture = pollFuture;
|
||||||
pollFuture.cancel(false);
|
if (localFuture != null) {
|
||||||
|
localFuture.cancel(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void schedulePoll() {
|
private synchronized void schedulePoll() {
|
||||||
logger.debug("Scheduling poll for 500ms out, then every {} ms", refreshInterval);
|
logger.debug("Scheduling poll for {}}ms out, then every {} ms", DELAY_IN_MS, refreshInterval);
|
||||||
pollFuture = scheduler.scheduleWithFixedDelay(this::poll, 500, refreshInterval, TimeUnit.MILLISECONDS);
|
pollFuture = scheduler.scheduleWithFixedDelay(this::poll, DELAY_IN_MS, refreshInterval, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void poll() {
|
private void poll() {
|
||||||
|
@ -203,8 +204,9 @@ public class AirVisualNodeHandler extends BaseThingHandler {
|
||||||
} else {
|
} else {
|
||||||
currentNodeData = gson.fromJson(jsonData, NodeData.class);
|
currentNodeData = gson.fromJson(jsonData, NodeData.class);
|
||||||
}
|
}
|
||||||
|
NodeDataInterface localNodeDate = nodeData;
|
||||||
if (nodeData == null || currentNodeData.getStatus().getDatetime() > nodeData.getStatus().getDatetime()) {
|
if (localNodeDate == null
|
||||||
|
|| currentNodeData.getStatus().getDatetime() > localNodeDate.getStatus().getDatetime()) {
|
||||||
nodeData = currentNodeData;
|
nodeData = currentNodeData;
|
||||||
// Update all channels from the updated Node data
|
// Update all channels from the updated Node data
|
||||||
for (Channel channel : getThing().getChannels()) {
|
for (Channel channel : getThing().getChannels()) {
|
||||||
|
@ -222,8 +224,9 @@ public class AirVisualNodeHandler extends BaseThingHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateChannel(String channelId, boolean force) {
|
private void updateChannel(String channelId, boolean force) {
|
||||||
if (nodeData != null && (force || isLinked(channelId))) {
|
NodeDataInterface localnodeData = nodeData;
|
||||||
State state = getChannelState(channelId, nodeData);
|
if (localnodeData != null && (force || isLinked(channelId))) {
|
||||||
|
State state = getChannelState(channelId, localnodeData);
|
||||||
logger.debug("Update channel {} with state {}", channelId, state);
|
logger.debug("Update channel {} with state {}", channelId, state);
|
||||||
updateState(channelId, state);
|
updateState(channelId, state);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue