[novafinedust] Use fire and forget commands to configure device (#10210)
Since the device does not follow its own protocol, we do not evaluate its replies to our configuration commands but rather do a fire and forget. Signed-off-by: Stefan Triller <github@stefantriller.de>
This commit is contained in:
parent
a30b5dfd00
commit
fe7b91f4b7
@ -16,6 +16,7 @@ import java.io.IOException;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.TooManyListenersException;
|
import java.util.TooManyListenersException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -62,6 +63,7 @@ public class SDS011Handler extends BaseThingHandler {
|
|||||||
|
|
||||||
private @Nullable ScheduledFuture<?> dataReadJob;
|
private @Nullable ScheduledFuture<?> dataReadJob;
|
||||||
private @Nullable ScheduledFuture<?> connectionMonitor;
|
private @Nullable ScheduledFuture<?> connectionMonitor;
|
||||||
|
private @Nullable Future<?> initJob;
|
||||||
private @Nullable ScheduledFuture<?> retryInitJob;
|
private @Nullable ScheduledFuture<?> retryInitJob;
|
||||||
|
|
||||||
private ZonedDateTime lastCommunication = ZonedDateTime.now();
|
private ZonedDateTime lastCommunication = ZonedDateTime.now();
|
||||||
@ -115,10 +117,10 @@ public class SDS011Handler extends BaseThingHandler {
|
|||||||
|
|
||||||
if (config.reporting) {
|
if (config.reporting) {
|
||||||
timeBetweenDataShouldArrive = Duration.ofMinutes(config.reportingInterval);
|
timeBetweenDataShouldArrive = Duration.ofMinutes(config.reportingInterval);
|
||||||
scheduler.submit(() -> initializeCommunicator(WorkMode.REPORTING, timeBetweenDataShouldArrive));
|
initJob = scheduler.submit(() -> initializeCommunicator(WorkMode.REPORTING, timeBetweenDataShouldArrive));
|
||||||
} else {
|
} else {
|
||||||
timeBetweenDataShouldArrive = Duration.ofSeconds(config.pollingInterval);
|
timeBetweenDataShouldArrive = Duration.ofSeconds(config.pollingInterval);
|
||||||
scheduler.submit(() -> initializeCommunicator(WorkMode.POLLING, timeBetweenDataShouldArrive));
|
initJob = scheduler.submit(() -> initializeCommunicator(WorkMode.POLLING, timeBetweenDataShouldArrive));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,66 +132,45 @@ public class SDS011Handler extends BaseThingHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean initSuccessful = false;
|
logger.trace("Trying to initialize device");
|
||||||
int retryInit = 3;
|
doInit(localCommunicator, mode, interval);
|
||||||
int retryCount = 0;
|
|
||||||
// sometimes the device is a little difficult and needs multiple configuration attempts
|
|
||||||
while (!initSuccessful && retryCount < retryInit) {
|
|
||||||
logger.trace("Trying to initialize device attempt={}", retryCount);
|
|
||||||
initSuccessful = doInit(localCommunicator, mode, interval);
|
|
||||||
retryCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (initSuccessful) {
|
lastCommunication = ZonedDateTime.now();
|
||||||
lastCommunication = ZonedDateTime.now();
|
|
||||||
updateStatus(ThingStatus.ONLINE);
|
|
||||||
|
|
||||||
if (mode == WorkMode.POLLING) {
|
if (mode == WorkMode.POLLING) {
|
||||||
dataReadJob = scheduler.scheduleWithFixedDelay(() -> {
|
dataReadJob = scheduler.scheduleWithFixedDelay(() -> {
|
||||||
try {
|
try {
|
||||||
localCommunicator.requestSensorData();
|
localCommunicator.requestSensorData();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
|
||||||
"Cannot query data from device");
|
"Cannot query data from device");
|
||||||
}
|
}
|
||||||
}, 2, config.pollingInterval, TimeUnit.SECONDS);
|
}, 2, config.pollingInterval, TimeUnit.SECONDS);
|
||||||
} else {
|
|
||||||
// start a job that reads the port until data arrives
|
|
||||||
int reportingReadStartDelay = 10;
|
|
||||||
int startReadBeforeDataArrives = 5;
|
|
||||||
long readReportedDataInterval = (config.reportingInterval * 60) - reportingReadStartDelay
|
|
||||||
- startReadBeforeDataArrives;
|
|
||||||
logger.trace("Scheduling job to receive reported values");
|
|
||||||
dataReadJob = scheduler.scheduleWithFixedDelay(() -> {
|
|
||||||
try {
|
|
||||||
localCommunicator.readSensorData();
|
|
||||||
} catch (IOException e) {
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
|
|
||||||
"Cannot query data from device, because: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}, reportingReadStartDelay, readReportedDataInterval, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration connectionMonitorStartDelay = timeBetweenDataShouldArrive
|
|
||||||
.plus(CONNECTION_MONITOR_START_DELAY_OFFSET);
|
|
||||||
connectionMonitor = scheduler.scheduleWithFixedDelay(this::verifyIfStillConnected,
|
|
||||||
connectionMonitorStartDelay.getSeconds(), timeBetweenDataShouldArrive.getSeconds(),
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
} else {
|
} else {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
|
// start a job that reads the port until data arrives
|
||||||
"Commands and replies from the device don't seem to match");
|
int reportingReadStartDelay = 10;
|
||||||
logger.debug(
|
int startReadBeforeDataArrives = 5;
|
||||||
"Could not configure sensor -> setting Thing to OFFLINE, disposing the handler and reschedule initialize in {} seconds",
|
long readReportedDataInterval = (config.reportingInterval * 60) - reportingReadStartDelay
|
||||||
RETRY_INIT_DELAY);
|
- startReadBeforeDataArrives;
|
||||||
doDispose(false);
|
logger.trace("Scheduling job to receive reported values");
|
||||||
retryInitJob = scheduler.schedule(this::initialize, RETRY_INIT_DELAY.getSeconds(), TimeUnit.SECONDS);
|
dataReadJob = scheduler.scheduleWithFixedDelay(() -> {
|
||||||
|
try {
|
||||||
|
localCommunicator.readSensorData();
|
||||||
|
} catch (IOException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
|
||||||
|
"Cannot query data from device, because: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}, reportingReadStartDelay, readReportedDataInterval, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Duration connectionMonitorStartDelay = timeBetweenDataShouldArrive.plus(CONNECTION_MONITOR_START_DELAY_OFFSET);
|
||||||
|
connectionMonitor = scheduler.scheduleWithFixedDelay(this::verifyIfStillConnected,
|
||||||
|
connectionMonitorStartDelay.getSeconds(), timeBetweenDataShouldArrive.getSeconds(), TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean doInit(SDS011Communicator localCommunicator, WorkMode mode, Duration interval) {
|
private void doInit(SDS011Communicator localCommunicator, WorkMode mode, Duration interval) {
|
||||||
boolean initSuccessful = false;
|
|
||||||
try {
|
try {
|
||||||
initSuccessful = localCommunicator.initialize(mode, interval);
|
localCommunicator.initialize(mode, interval);
|
||||||
} catch (final IOException ex) {
|
} catch (final IOException ex) {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, "I/O error!");
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, "I/O error!");
|
||||||
} catch (PortInUseException e) {
|
} catch (PortInUseException e) {
|
||||||
@ -201,7 +182,6 @@ public class SDS011Handler extends BaseThingHandler {
|
|||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
|
||||||
"Cannot set serial port parameters");
|
"Cannot set serial port parameters");
|
||||||
}
|
}
|
||||||
return initSuccessful;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean validateConfiguration() {
|
private boolean validateConfiguration() {
|
||||||
@ -243,6 +223,12 @@ public class SDS011Handler extends BaseThingHandler {
|
|||||||
this.connectionMonitor = null;
|
this.connectionMonitor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<?> localInitJob = this.initJob;
|
||||||
|
if (localInitJob != null) {
|
||||||
|
localInitJob.cancel(true);
|
||||||
|
this.initJob = null;
|
||||||
|
}
|
||||||
|
|
||||||
ScheduledFuture<?> localRetryOpenPortJob = this.retryInitJob;
|
ScheduledFuture<?> localRetryOpenPortJob = this.retryInitJob;
|
||||||
if (localRetryOpenPortJob != null) {
|
if (localRetryOpenPortJob != null) {
|
||||||
localRetryOpenPortJob.cancel(true);
|
localRetryOpenPortJob.cancel(true);
|
||||||
|
|||||||
@ -29,12 +29,8 @@ import org.eclipse.jdt.annotation.Nullable;
|
|||||||
import org.openhab.binding.novafinedust.internal.SDS011Handler;
|
import org.openhab.binding.novafinedust.internal.SDS011Handler;
|
||||||
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.CommandMessage;
|
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.CommandMessage;
|
||||||
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.Constants;
|
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.Constants;
|
||||||
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.ModeReply;
|
|
||||||
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.SensorFirmwareReply;
|
|
||||||
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.SensorMeasuredDataReply;
|
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.SensorMeasuredDataReply;
|
||||||
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.SensorReply;
|
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.SensorReply;
|
||||||
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.SleepReply;
|
|
||||||
import org.openhab.binding.novafinedust.internal.sds011protocol.messages.WorkingPeriodReply;
|
|
||||||
import org.openhab.core.io.transport.serial.PortInUseException;
|
import org.openhab.core.io.transport.serial.PortInUseException;
|
||||||
import org.openhab.core.io.transport.serial.SerialPort;
|
import org.openhab.core.io.transport.serial.SerialPort;
|
||||||
import org.openhab.core.io.transport.serial.SerialPortIdentifier;
|
import org.openhab.core.io.transport.serial.SerialPortIdentifier;
|
||||||
@ -52,7 +48,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class SDS011Communicator {
|
public class SDS011Communicator {
|
||||||
|
|
||||||
private static final int MAX_SENDOR_REPORTINGS_UNTIL_EXPECTED_REPLY = 20;
|
private static final int MAX_READ_UNTIL_SENSOR_DATA = 6; // at least 6 because we send 5 configuration commands
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(SDS011Communicator.class);
|
private final Logger logger = LoggerFactory.getLogger(SDS011Communicator.class);
|
||||||
|
|
||||||
@ -82,9 +78,8 @@ public class SDS011Communicator {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws UnsupportedCommOperationException
|
* @throws UnsupportedCommOperationException
|
||||||
*/
|
*/
|
||||||
public boolean initialize(WorkMode mode, Duration interval)
|
public void initialize(WorkMode mode, Duration interval)
|
||||||
throws PortInUseException, TooManyListenersException, IOException, UnsupportedCommOperationException {
|
throws PortInUseException, TooManyListenersException, IOException, UnsupportedCommOperationException {
|
||||||
boolean initSuccessful = true;
|
|
||||||
|
|
||||||
logger.trace("Initializing with mode={}, interval={}", mode, interval);
|
logger.trace("Initializing with mode={}, interval={}", mode, interval);
|
||||||
|
|
||||||
@ -102,30 +97,28 @@ public class SDS011Communicator {
|
|||||||
logger.trace("Input and Outputstream opened for the port");
|
logger.trace("Input and Outputstream opened for the port");
|
||||||
|
|
||||||
// wake up the device
|
// wake up the device
|
||||||
initSuccessful &= sendSleep(false);
|
sendSleep(false);
|
||||||
logger.trace("Wake up call done, initSuccessful={}", initSuccessful);
|
logger.trace("Wake up call done");
|
||||||
initSuccessful &= getFirmware();
|
getFirmware();
|
||||||
logger.trace("Firmware requested, initSuccessful={}", initSuccessful);
|
logger.trace("Firmware requested");
|
||||||
|
|
||||||
if (mode == WorkMode.POLLING) {
|
if (mode == WorkMode.POLLING) {
|
||||||
initSuccessful &= setMode(WorkMode.POLLING);
|
setMode(WorkMode.POLLING);
|
||||||
logger.trace("Polling mode set, initSuccessful={}", initSuccessful);
|
logger.trace("Polling mode set");
|
||||||
initSuccessful &= setWorkingPeriod((byte) 0);
|
setWorkingPeriod((byte) 0);
|
||||||
logger.trace("Working period for polling set, initSuccessful={}", initSuccessful);
|
logger.trace("Working period for polling set");
|
||||||
} else {
|
} else {
|
||||||
// reporting
|
// reporting
|
||||||
initSuccessful &= setWorkingPeriod((byte) interval.toMinutes());
|
setWorkingPeriod((byte) interval.toMinutes());
|
||||||
logger.trace("Working period for reporting set, initSuccessful={}", initSuccessful);
|
logger.trace("Working period for reporting set");
|
||||||
initSuccessful &= setMode(WorkMode.REPORTING);
|
setMode(WorkMode.REPORTING);
|
||||||
logger.trace("Reporting mode set, initSuccessful={}", initSuccessful);
|
logger.trace("Reporting mode set");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.serialPort = localSerialPort;
|
this.serialPort = localSerialPort;
|
||||||
|
|
||||||
return initSuccessful;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable SensorReply sendCommand(CommandMessage message) throws IOException {
|
private void sendCommand(CommandMessage message) throws IOException {
|
||||||
byte[] commandData = message.getBytes();
|
byte[] commandData = message.getBytes();
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Will send command: {} ({})", HexUtils.bytesToHex(commandData), Arrays.toString(commandData));
|
logger.debug("Will send command: {} ({})", HexUtils.bytesToHex(commandData), Arrays.toString(commandData));
|
||||||
@ -139,23 +132,12 @@ public class SDS011Communicator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Give the sensor some time to handle the command
|
// Give the sensor some time to handle the command before doing something else with it
|
||||||
Thread.sleep(500);
|
Thread.sleep(500);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
logger.warn("Problem while waiting for reading a reply to our command.");
|
logger.warn("Interrupted while waiting after sending command={}", message);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
SensorReply reply = readReply();
|
|
||||||
// in case there is still another reporting active, we want to discard the sensor data and read the reply to our
|
|
||||||
// command again, this might happen more often in case the sensor has buffered some data
|
|
||||||
for (int i = 0; i < MAX_SENDOR_REPORTINGS_UNTIL_EXPECTED_REPLY; i++) {
|
|
||||||
if (reply instanceof SensorMeasuredDataReply) {
|
|
||||||
reply = readReply();
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return reply;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void write(byte[] commandData) throws IOException {
|
private void write(byte[] commandData) throws IOException {
|
||||||
@ -166,21 +148,13 @@ public class SDS011Communicator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean setWorkingPeriod(byte period) throws IOException {
|
private void setWorkingPeriod(byte period) throws IOException {
|
||||||
CommandMessage m = new CommandMessage(Command.WORKING_PERIOD, new byte[] { Constants.SET_ACTION, period });
|
CommandMessage m = new CommandMessage(Command.WORKING_PERIOD, new byte[] { Constants.SET_ACTION, period });
|
||||||
logger.debug("Sending work period: {}", period);
|
logger.debug("Sending work period: {}", period);
|
||||||
SensorReply reply = sendCommand(m);
|
sendCommand(m);
|
||||||
logger.debug("Got reply to setWorkingPeriod command: {}", reply);
|
|
||||||
if (reply instanceof WorkingPeriodReply) {
|
|
||||||
WorkingPeriodReply wpReply = (WorkingPeriodReply) reply;
|
|
||||||
if (wpReply.getPeriod() == period && wpReply.getActionType() == Constants.SET_ACTION) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean setMode(WorkMode workMode) throws IOException {
|
private void setMode(WorkMode workMode) throws IOException {
|
||||||
byte haveToRequestData = 0;
|
byte haveToRequestData = 0;
|
||||||
if (workMode == WorkMode.POLLING) {
|
if (workMode == WorkMode.POLLING) {
|
||||||
haveToRequestData = 1;
|
haveToRequestData = 1;
|
||||||
@ -188,18 +162,10 @@ public class SDS011Communicator {
|
|||||||
|
|
||||||
CommandMessage m = new CommandMessage(Command.MODE, new byte[] { Constants.SET_ACTION, haveToRequestData });
|
CommandMessage m = new CommandMessage(Command.MODE, new byte[] { Constants.SET_ACTION, haveToRequestData });
|
||||||
logger.debug("Sending mode: {}", workMode);
|
logger.debug("Sending mode: {}", workMode);
|
||||||
SensorReply reply = sendCommand(m);
|
sendCommand(m);
|
||||||
logger.debug("Got reply to setMode command: {}", reply);
|
|
||||||
if (reply instanceof ModeReply) {
|
|
||||||
ModeReply mr = (ModeReply) reply;
|
|
||||||
if (mr.getActionType() == Constants.SET_ACTION && mr.getMode() == workMode) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean sendSleep(boolean doSleep) throws IOException {
|
private void sendSleep(boolean doSleep) throws IOException {
|
||||||
byte payload = (byte) 1;
|
byte payload = (byte) 1;
|
||||||
if (doSleep) {
|
if (doSleep) {
|
||||||
payload = (byte) 0;
|
payload = (byte) 0;
|
||||||
@ -207,38 +173,21 @@ public class SDS011Communicator {
|
|||||||
|
|
||||||
CommandMessage m = new CommandMessage(Command.SLEEP, new byte[] { Constants.SET_ACTION, payload });
|
CommandMessage m = new CommandMessage(Command.SLEEP, new byte[] { Constants.SET_ACTION, payload });
|
||||||
logger.debug("Sending doSleep: {}", doSleep);
|
logger.debug("Sending doSleep: {}", doSleep);
|
||||||
SensorReply reply = sendCommand(m);
|
sendCommand(m);
|
||||||
logger.debug("Got reply to sendSleep command: {}", reply);
|
|
||||||
|
|
||||||
|
// as it turns out, the protocol doesn't work as described: sometimes the device just wakes up without replying
|
||||||
|
// to us. Hence we should not wait for a reply, but just force to wake it up to then send out our configuration
|
||||||
|
// commands
|
||||||
if (!doSleep) {
|
if (!doSleep) {
|
||||||
// sometimes the sensor does not wakeup on the first attempt, thus we try again
|
// sometimes the sensor does not wakeup on the first attempt, thus we try again
|
||||||
for (int i = 0; reply == null && i < 3; i++) {
|
sendCommand(m);
|
||||||
reply = sendCommand(m);
|
|
||||||
logger.debug("Got reply to sendSleep command after retry#{}: {}", i + 1, reply);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reply instanceof SleepReply) {
|
|
||||||
SleepReply sr = (SleepReply) reply;
|
|
||||||
if (sr.getActionType() == Constants.SET_ACTION && sr.getSleep() == payload) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean getFirmware() throws IOException {
|
private void getFirmware() throws IOException {
|
||||||
CommandMessage m = new CommandMessage(Command.FIRMWARE, new byte[] {});
|
CommandMessage m = new CommandMessage(Command.FIRMWARE, new byte[] {});
|
||||||
logger.debug("Sending get firmware request");
|
logger.debug("Sending get firmware request");
|
||||||
SensorReply reply = sendCommand(m);
|
sendCommand(m);
|
||||||
logger.debug("Got reply to getFirmware command: {}", reply);
|
|
||||||
|
|
||||||
if (reply instanceof SensorFirmwareReply) {
|
|
||||||
SensorFirmwareReply fwReply = (SensorFirmwareReply) reply;
|
|
||||||
thingHandler.setFirmware(fwReply.getFirmware());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -256,7 +205,7 @@ public class SDS011Communicator {
|
|||||||
try {
|
try {
|
||||||
Thread.sleep(200); // give the device some time to handle the command
|
Thread.sleep(200); // give the device some time to handle the command
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
logger.warn("Interrupted while waiting before reading a reply to our rquest data command.");
|
logger.warn("Interrupted while waiting before reading a reply to our request data command.");
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
readSensorData();
|
readSensorData();
|
||||||
@ -271,7 +220,7 @@ public class SDS011Communicator {
|
|||||||
if (localInpuStream != null) {
|
if (localInpuStream != null) {
|
||||||
logger.trace("Reading for reply until first byte is found");
|
logger.trace("Reading for reply until first byte is found");
|
||||||
while ((b = localInpuStream.read()) != Constants.MESSAGE_START_AS_INT) {
|
while ((b = localInpuStream.read()) != Constants.MESSAGE_START_AS_INT) {
|
||||||
logger.debug("Trying to find first reply byte now...");
|
// logger.trace("Trying to find first reply byte now...");
|
||||||
}
|
}
|
||||||
readBuffer[0] = (byte) b;
|
readBuffer[0] = (byte) b;
|
||||||
int remainingBytesRead = localInpuStream.read(readBuffer, 1, Constants.REPLY_LENGTH - 1);
|
int remainingBytesRead = localInpuStream.read(readBuffer, 1, Constants.REPLY_LENGTH - 1);
|
||||||
@ -286,16 +235,26 @@ public class SDS011Communicator {
|
|||||||
|
|
||||||
public void readSensorData() throws IOException {
|
public void readSensorData() throws IOException {
|
||||||
logger.trace("readSensorData() called");
|
logger.trace("readSensorData() called");
|
||||||
|
|
||||||
|
boolean foundSensorData = doRead();
|
||||||
|
for (int i = 0; !foundSensorData && i < MAX_READ_UNTIL_SENSOR_DATA; i++) {
|
||||||
|
foundSensorData = doRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean doRead() throws IOException {
|
||||||
SensorReply reply = readReply();
|
SensorReply reply = readReply();
|
||||||
logger.trace("readSensorData(): Read reply={}", reply);
|
logger.trace("doRead(): Read reply={}", reply);
|
||||||
if (reply instanceof SensorMeasuredDataReply) {
|
if (reply instanceof SensorMeasuredDataReply) {
|
||||||
SensorMeasuredDataReply sensorData = (SensorMeasuredDataReply) reply;
|
SensorMeasuredDataReply sensorData = (SensorMeasuredDataReply) reply;
|
||||||
logger.trace("We received sensor data");
|
logger.trace("We received sensor data");
|
||||||
if (sensorData.isValidData()) {
|
if (sensorData.isValidData()) {
|
||||||
logger.trace("Sensor data is valid => updating channels");
|
logger.trace("Sensor data is valid => updating channels");
|
||||||
thingHandler.updateChannels(sensorData);
|
thingHandler.updateChannels(sensorData);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user