diff --git a/zwave/lantern-service-thermometer/pom.xml b/zwave/lantern-service-thermometer/pom.xml
index bd618d2..3160a85 100644
--- a/zwave/lantern-service-thermometer/pom.xml
+++ b/zwave/lantern-service-thermometer/pom.xml
@@ -15,7 +15,7 @@
com.lanternsoftware.util
- lantern-util-common
+ lantern-util-servlet
1.0.0
@@ -29,10 +29,25 @@
logback-classic
1.2.3
+
+ com.neuronrobotics
+ nrjavaserial
+ 5.2.1
+
+
+ com.fazecast
+ jSerialComm
+ 2.5.1
+
org.hid4java
hid4java
- 0.5.0
+ 0.7.0
+
+
+ com.pi4j
+ pi4j-device
+ 1.3
diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/DS18B20Thermometer.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/DS18B20Thermometer.java
new file mode 100644
index 0000000..30e3b27
--- /dev/null
+++ b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/DS18B20Thermometer.java
@@ -0,0 +1,41 @@
+package com.lanternsoftware.thermometer;
+
+import com.lanternsoftware.util.CollectionUtils;
+import com.pi4j.component.temperature.TemperatureSensor;
+import com.pi4j.component.temperature.impl.TmpDS18B20DeviceType;
+import com.pi4j.io.w1.W1Device;
+import com.pi4j.io.w1.W1Master;
+
+import java.util.List;
+
+public class DS18B20Thermometer implements IThermometer {
+ W1Device device;
+
+ public static List devices() {
+ W1Master master = new W1Master();
+ return CollectionUtils.transform(master.getDevices(TmpDS18B20DeviceType.FAMILY_CODE), DS18B20Thermometer::new);
+ }
+
+ public DS18B20Thermometer() {
+ W1Master master = new W1Master();
+ device = CollectionUtils.getFirst(master.getDevices(TmpDS18B20DeviceType.FAMILY_CODE));
+ }
+
+ public DS18B20Thermometer(W1Device _device) {
+ device = _device;
+ }
+
+ @Override
+ public double getTemperatureCelsius() {
+ return device == null?-273:((TemperatureSensor) device).getTemperature();
+ }
+
+ @Override
+ public boolean isConnected() {
+ return device != null;
+ }
+
+ @Override
+ public void shutdown() {
+ }
+}
diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/context/ThermometerApp.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/HidThermometer.java
similarity index 80%
rename from zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/context/ThermometerApp.java
rename to zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/HidThermometer.java
index a682b96..912ae3d 100644
--- a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/context/ThermometerApp.java
+++ b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/HidThermometer.java
@@ -1,4 +1,4 @@
-package com.lanternsoftware.thermometer.context;
+package com.lanternsoftware.thermometer;
import com.lanternsoftware.util.NullUtils;
import com.lanternsoftware.util.concurrency.ConcurrencyUtils;
@@ -11,14 +11,15 @@ import org.slf4j.LoggerFactory;
import java.util.Timer;
import java.util.TimerTask;
-public class ThermometerApp {
- private static final Logger LOG = LoggerFactory.getLogger(ThermometerApp.class);
+public class HidThermometer implements IThermometer{
+ private static final Logger LOG = LoggerFactory.getLogger(HidThermometer.class);
private HidDevice device;
private final Timer timer = new Timer();
private double lastTemp;
+ private final byte[] READ = hexToByte("0180330100000000");
- public void start() {
+ public HidThermometer() {
HidServices hs = HidManager.getHidServices();
for (HidDevice d : hs.getAttachedHidDevices()) {
if (NullUtils.isEqual(d.getVendorId(), (short) 0x413d) && NullUtils.isEqual(d.getProductId(), (short) 0x2107)) {
@@ -27,11 +28,13 @@ public class ThermometerApp {
}
}
if ((device != null) && device.open()) {
- synchronized (device) {
- read(hexToByte("0182770100000000"));
- read(hexToByte("0186ff0100000000"));
- read(hexToByte("0182770100000000"));
- read(hexToByte("0182770100000000"));
+ final byte[] INIT1 = hexToByte("0182770100000000");
+ final byte[] INIT2 = hexToByte("0186ff0100000000");
+ synchronized (this) {
+ read(INIT1);
+ read(INIT2);
+ read(INIT1);
+ read(INIT1);
}
} else {
LOG.error("Failed to open HID Device");
@@ -45,7 +48,11 @@ public class ThermometerApp {
}, 0L, 10000L);
}
- public void stop() {
+ public boolean isConnected() {
+ return device != null;
+ }
+
+ public void shutdown() {
timer.cancel();
ConcurrencyUtils.sleep(10000);
if (device != null) {
@@ -100,14 +107,14 @@ public class ThermometerApp {
}
return response;
}
- public double getTemperature() {
+ public double getTemperatureCelsius() {
return lastTemp;
}
- public double readTemperature() {
+ private double readTemperature() {
if (device != null) {
- synchronized (device) {
- byte[] response = read(hexToByte("0180330100000000"));
+ synchronized (this) {
+ byte[] response = read(READ);
if (response == null)
return 5.0;
int rawReading = ((response[3] & 0xFF) + (response[2] << 8));
diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/ICO2Sensor.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/ICO2Sensor.java
new file mode 100644
index 0000000..a619e4f
--- /dev/null
+++ b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/ICO2Sensor.java
@@ -0,0 +1,6 @@
+package com.lanternsoftware.thermometer;
+
+public interface ICO2Sensor {
+ int getPPM();
+ void shutdown();
+}
diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/IThermometer.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/IThermometer.java
new file mode 100644
index 0000000..cadb5e7
--- /dev/null
+++ b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/IThermometer.java
@@ -0,0 +1,7 @@
+package com.lanternsoftware.thermometer;
+
+public interface IThermometer {
+ double getTemperatureCelsius();
+ boolean isConnected();
+ void shutdown();
+}
diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/MHZ19BCO2Sensor.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/MHZ19BCO2Sensor.java
new file mode 100644
index 0000000..921c6c9
--- /dev/null
+++ b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/MHZ19BCO2Sensor.java
@@ -0,0 +1,165 @@
+package com.lanternsoftware.thermometer;
+
+import com.lanternsoftware.util.concurrency.ConcurrencyUtils;
+import gnu.io.CommPortIdentifier;
+import gnu.io.SerialPort;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class MHZ19BCO2Sensor implements ICO2Sensor {
+ private static final Logger LOG = LoggerFactory.getLogger(MHZ19BCO2Sensor.class);
+
+ private static final int DEFAULT_TIMEOUT = 1000;
+
+ private static final byte[] CMD_GAS_CONCENTRATION = {(byte)0xff, 0x01, (byte)0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
+ private static final byte[] CMD_CALIBRATE_ZERO_POINT = {(byte)0xff, 0x01, (byte)0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78};
+ private static final byte[] CMD_AUTO_CALIBRATION_ON_WITHOUT_CHECKSUM = {(byte)0xff, 0x01, (byte)0x79, (byte)0xa0, 0x00, 0x00, 0x00, 0x00};
+ private static final byte[] CMD_AUTO_CALIBRATION_OFF_WITHOUT_CHECKSUM = {(byte)0xff, 0x01, (byte)0x79, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ private static final int CALIBRATE_SPAN_POINT_MIN = 1000;
+
+ private SerialPort serialPort;
+ private InputStream is;
+ private OutputStream os;
+
+ private MHZ19BCO2Sensor(String _port) {
+ this(_port, DEFAULT_TIMEOUT);
+ }
+
+ private MHZ19BCO2Sensor(String _port, int _timeout) {
+ try {
+ CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(_port);
+ serialPort = portIdentifier.open("co2port", 2000);
+ serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
+ serialPort.enableReceiveTimeout(_timeout);
+ serialPort.enableReceiveThreshold(9);
+ is = serialPort.getInputStream();
+ os = serialPort.getOutputStream();
+ } catch (Exception _e) {
+ if (serialPort != null) {
+ serialPort.close();
+ serialPort = null;
+ }
+ LOG.error("Exception while starting MHZ19BCO2Sensor", _e);
+ }
+ }
+
+ public void shutdown() {
+ IOUtils.closeQuietly(is);
+ IOUtils.closeQuietly(os);
+ if (serialPort != null)
+ serialPort.close();
+ }
+
+ private void write(byte[] out) {
+ try {
+ int length = is.available();
+ if (length > 0) {
+ byte[] unread = new byte[length];
+ int read = is.read(unread, 0, length);
+ LOG.debug("deleted unread buffer length:{}", read);
+ }
+ os.write(out, 0, out.length);
+ }
+ catch (Exception _e) {
+ LOG.error("Exception while writing to MHZ19B", _e);
+ }
+ }
+
+ private byte getCheckSum(byte[] data) {
+ int ret = 0;
+ for (int i = 1; i <= 7; i++) {
+ ret += data[i];
+ }
+ return (byte)(~(byte)(ret & 0x000000ff) + 1);
+ }
+
+ private byte[] getCommandWithCheckSum(byte[] baseCommand) {
+ byte[] checkSum = {getCheckSum(baseCommand)};
+ byte[] data = new byte[baseCommand.length + 1];
+ System.arraycopy(baseCommand, 0, data, 0, baseCommand.length);
+ System.arraycopy(checkSum, 0, data, baseCommand.length, 1);
+ return data;
+ }
+
+ @Override
+ public int getPPM() {
+ write(CMD_GAS_CONCENTRATION);
+ try {
+ ByteBuffer buf = ByteBuffer.allocate(2);
+ byte[] data = new byte[9];
+ if (is.read(data, 0, 9) < 9)
+ return 0;
+ buf.put(data[2]);
+ buf.put(data[3]);
+ return buf.getShort(0);
+ }
+ catch (Exception _e) {
+ LOG.error("Could not read value from MHZ19B", _e);
+ return 0;
+ }
+ }
+
+ public void setCalibrateZeroPoint() {
+ write(CMD_CALIBRATE_ZERO_POINT);
+ }
+
+ public void setCalibrateSpanPoint(int point) {
+ if (point < CALIBRATE_SPAN_POINT_MIN) {
+ LOG.info("since span needs at least {} ppm, set it to {} ppm.", CALIBRATE_SPAN_POINT_MIN, CALIBRATE_SPAN_POINT_MIN);
+ point = CALIBRATE_SPAN_POINT_MIN;
+ }
+
+ byte high = (byte)((point / 256) & 0x000000ff);
+ byte low = (byte)((point % 256) & 0x000000ff);
+ byte[] CMD_CALIBRATE_SPAN_POINT = {(byte)0xff, 0x01, (byte)0x88, high, low, 0x00, 0x00, 0x00};
+
+ write(getCommandWithCheckSum(CMD_CALIBRATE_SPAN_POINT));
+ LOG.info("set the calibration span point to {} ppm.", point);
+ }
+
+ public void setAutoCalibration(boolean set) {
+ if (set) {
+ write(getCommandWithCheckSum(CMD_AUTO_CALIBRATION_ON_WITHOUT_CHECKSUM));
+ LOG.info("set auto calibration to ON.");
+ } else {
+ write(getCommandWithCheckSum(CMD_AUTO_CALIBRATION_OFF_WITHOUT_CHECKSUM));
+ LOG.info("set auto calibration to OFF.");
+ }
+ }
+
+ private void setDetectionRange(int range) {
+ byte high = (byte)((range / 256) & 0x000000ff);
+ byte low = (byte)((range % 256) & 0x000000ff);
+ byte[] CMD_DETECTION_RANGE = {(byte)0xff, 0x01, (byte)0x99, high, low, 0x00, 0x00, 0x00};
+
+ write(getCommandWithCheckSum(CMD_DETECTION_RANGE));
+ LOG.info("set the detection range to {} ppm.", range);
+ }
+
+ public void setDetectionRange2000() {
+ setDetectionRange(2000);
+ }
+
+ public void setDetectionRange5000() {
+ setDetectionRange(5000);
+ }
+
+ public static void main(String[] args) {
+ MHZ19BCO2Sensor mhz19b = new MHZ19BCO2Sensor("/dev/ttyAMA0");
+ mhz19b.setDetectionRange5000();
+ mhz19b.setAutoCalibration(false);
+ AtomicInteger i = new AtomicInteger(0);
+ while (i.incrementAndGet() < 2000) {
+ LOG.debug("co2: {}PPM", mhz19b.getPPM());
+ ConcurrencyUtils.sleep(5000);
+ }
+ Runtime.getRuntime().addShutdownHook(new Thread(mhz19b::shutdown, "Shutdown"));
+ }
+}
diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/TestThermo.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/TestThermo.java
deleted file mode 100644
index 1ccfe7b..0000000
--- a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/TestThermo.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.lanternsoftware.thermometer;
-
-import com.lanternsoftware.thermometer.context.ThermometerApp;
-
-public class TestThermo {
- public static void main(String[] args) {
- ThermometerApp app = new ThermometerApp();
- app.start();
- try {
- Thread.sleep(20000);
- } catch (InterruptedException _e) {
- _e.printStackTrace();
- }
- app.stop();
- }
-}
diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/context/Globals.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/context/Globals.java
index 553f540..d8d46aa 100644
--- a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/context/Globals.java
+++ b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/context/Globals.java
@@ -1,22 +1,27 @@
package com.lanternsoftware.thermometer.context;
+import com.lanternsoftware.thermometer.DS18B20Thermometer;
+import com.lanternsoftware.thermometer.HidThermometer;
+import com.lanternsoftware.thermometer.IThermometer;
+
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
+import java.util.ArrayList;
+import java.util.List;
public class Globals implements ServletContextListener {
- public static ThermometerApp app;
+ public static List thermometers = new ArrayList<>();
@Override
public void contextInitialized(ServletContextEvent sce) {
- app = new ThermometerApp();
- app.start();
+ IThermometer t = new HidThermometer();
+ if (t.isConnected())
+ thermometers.add(t);
+ thermometers.addAll(DS18B20Thermometer.devices());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
- if (app != null) {
- app.stop();
- app = null;
- }
+ thermometers.forEach(IThermometer::shutdown);
}
}
diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/servlet/TempServlet.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/servlet/TempServlet.java
index 1eccd99..16cac6a 100644
--- a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/servlet/TempServlet.java
+++ b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/servlet/TempServlet.java
@@ -1,18 +1,23 @@
package com.lanternsoftware.thermometer.servlet;
+import com.lanternsoftware.thermometer.IThermometer;
import com.lanternsoftware.thermometer.context.Globals;
+import com.lanternsoftware.util.CollectionUtils;
+import com.lanternsoftware.util.dao.DaoSerializer;
+import com.lanternsoftware.util.servlet.LanternServlet;
-import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-@WebServlet("/temp")
-public class TempServlet extends ThermoServlet {
+@WebServlet("/temp/*")
+public class TempServlet extends LanternServlet {
@Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- setResponseEntity(resp, "application/json", "{\"temp\": "+ Globals.app.getTemperature() + "}");
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
+ int idx = DaoSerializer.toInteger(CollectionUtils.get(path(req), 0));
+ IThermometer therm = CollectionUtils.get(Globals.thermometers, idx);
+ double temp = therm == null ? -273 : therm.getTemperatureCelsius();
+ setResponseEntity(resp, "application/json", "{\"temp\": "+ temp + "}");
}
}
diff --git a/zwave/lantern-service-thermometer/src/main/resources/logback.xml b/zwave/lantern-service-thermometer/src/main/resources/logback.xml
index 939eaaa..e39eed9 100644
--- a/zwave/lantern-service-thermometer/src/main/resources/logback.xml
+++ b/zwave/lantern-service-thermometer/src/main/resources/logback.xml
@@ -9,9 +9,9 @@
- /opt/currentmonitor/log/log.txt
+ /opt/tomcat/log/thermo.txt
- /opt/currentmonitor/log/log.%d{yyyy-MM-dd}.%i.txt
+ /opt/currentmonitor/log/thermo.%d{yyyy-MM-dd}.%i.txt
20MB
20
@@ -20,9 +20,10 @@
-
+
+
\ No newline at end of file
diff --git a/zwave/lantern-service-thermometer/src/test/java/com/lanternsoftware/thermometer/TestStartup.java b/zwave/lantern-service-thermometer/src/test/java/com/lanternsoftware/thermometer/TestStartup.java
index 5dc82b4..a04074f 100644
--- a/zwave/lantern-service-thermometer/src/test/java/com/lanternsoftware/thermometer/TestStartup.java
+++ b/zwave/lantern-service-thermometer/src/test/java/com/lanternsoftware/thermometer/TestStartup.java
@@ -1,16 +1,14 @@
package com.lanternsoftware.thermometer;
-import com.lanternsoftware.thermometer.context.ThermometerApp;
+import com.lanternsoftware.util.concurrency.ConcurrencyUtils;
public class TestStartup {
public static void main(String[] args) {
- ThermometerApp app = new ThermometerApp();
- app.start();
- try {
- Thread.sleep(20000);
- } catch (InterruptedException _e) {
- _e.printStackTrace();
+ IThermometer thermometer = new DS18B20Thermometer();
+ for (int i=0; i<200; i++) {
+ System.out.println(String.format("%.2f", thermometer.getTemperatureCelsius()));
+ ConcurrencyUtils.sleep(1000);
}
- app.stop();
+ thermometer.shutdown();
}
}
diff --git a/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/TestSecurity.java b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/TestSecurity.java
index 31fc024..80a742e 100644
--- a/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/TestSecurity.java
+++ b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/TestSecurity.java
@@ -2,6 +2,7 @@ package com.lanternsoftware.zwave;
import com.lanternsoftware.datamodel.zwave.Switch;
import com.lanternsoftware.datamodel.zwave.SwitchType;
+import com.lanternsoftware.util.concurrency.ConcurrencyUtils;
import com.lanternsoftware.zwave.security.SecurityController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -14,6 +15,8 @@ public class TestSecurity {
Switch sw = new Switch("Garage", "Door 1", 1000, true, false, null, 0);
sw.setGpioPin(7);
sw.setType(SwitchType.SECURITY);
- c.listen(sw, (nodeId, _open) -> LOG.info("Door is " + (_open ? "OPEN" : "CLOSED")));
+ c.listen(sw, (nodeId, _open) -> LOG.error("Door event, now " + (_open ? "OPEN" : "CLOSED")));
+ ConcurrencyUtils.sleep(60000);
+ c.shutdown();
}
}
diff --git a/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/context/ZWaveApp.java b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/context/ZWaveApp.java
index ac5799a..d4aa332 100644
--- a/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/context/ZWaveApp.java
+++ b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/context/ZWaveApp.java
@@ -22,6 +22,7 @@ import com.lanternsoftware.zwave.controller.Controller;
import com.lanternsoftware.zwave.dao.MongoZWaveDao;
import com.lanternsoftware.zwave.message.IMessageSubscriber;
import com.lanternsoftware.zwave.message.MessageEngine;
+import com.lanternsoftware.zwave.message.impl.AddNodeToNetworkRequest;
import com.lanternsoftware.zwave.message.impl.BinarySwitchReportRequest;
import com.lanternsoftware.zwave.message.impl.BinarySwitchSetRequest;
import com.lanternsoftware.zwave.message.impl.CRC16EncapRequest;
@@ -226,6 +227,8 @@ public class ZWaveApp {
}
});
+ controller.send(new MultilevelSwitchSetRequest((byte)2, 0xFF));
+
// controller.send(new MultilevelSensorGetRequest((byte)11));
// controller.send(new ThermostatSetPointGetRequest((byte)11, ThermostatSetPointIndex.HEATING));
// controller.send(new ThermostatSetPointGetRequest((byte)11, ThermostatSetPointIndex.COOLING));
diff --git a/zwave/lantern-service-zwave/src/main/resources/logback.xml b/zwave/lantern-service-zwave/src/main/resources/logback.xml
index 0c83f96..ece41c5 100644
--- a/zwave/lantern-service-zwave/src/main/resources/logback.xml
+++ b/zwave/lantern-service-zwave/src/main/resources/logback.xml
@@ -9,7 +9,7 @@
-
+
diff --git a/zwave/lantern-service-zwave/src/test/java/com/lanternsoftware/zwave/TestStartup.java b/zwave/lantern-service-zwave/src/test/java/com/lanternsoftware/zwave/TestStartup.java
index ef3b633..0a1777d 100644
--- a/zwave/lantern-service-zwave/src/test/java/com/lanternsoftware/zwave/TestStartup.java
+++ b/zwave/lantern-service-zwave/src/test/java/com/lanternsoftware/zwave/TestStartup.java
@@ -7,10 +7,10 @@ public class TestStartup {
ZWaveApp app = new ZWaveApp();
app.start();
try {
- Thread.sleep(20000);
+ Thread.sleep(20000000);
} catch (InterruptedException _e) {
_e.printStackTrace();
}
- app.stop();
+ Runtime.getRuntime().addShutdownHook(new Thread(app::stop, "Shutdown"));
}
}
diff --git a/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/controller/Controller.java b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/controller/Controller.java
index a89cc68..de5b428 100644
--- a/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/controller/Controller.java
+++ b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/controller/Controller.java
@@ -39,13 +39,13 @@ public class Controller {
private SerialPort serialPort;
private OutputStream os;
private boolean running = false;
- private AtomicInteger callbackId = new AtomicInteger(0);
+ private final AtomicInteger callbackId = new AtomicInteger(0);
private final Object ackMutex = new Object();
private final Object responseMutex = new Object();
private final Object callbackMutex = new Object();
private boolean responseReceived;
private final Map callbacks = new HashMap<>();
- private ExecutorService executor = Executors.newFixedThreadPool(2);
+ private final ExecutorService executor = Executors.newFixedThreadPool(2);
private NodeManager nodeManager;
public boolean start(String _port) {
@@ -172,9 +172,10 @@ public class Controller {
logger.debug("Finished outbound of: {}", message.describe());
}
if (message instanceof RequestMessage) {
- logger.debug("Waiting for response from: {}", message.describe());
synchronized (responseMutex) {
- responseMutex.wait(1000);
+ logger.debug("Waiting for response from: {}", message.describe());
+ if (!responseReceived)
+ responseMutex.wait(1000);
logger.debug("Response received: {}", responseReceived);
responseReceived = false;
}
diff --git a/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/MessageEngine.java b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/MessageEngine.java
index 83f62cd..c24357d 100644
--- a/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/MessageEngine.java
+++ b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/MessageEngine.java
@@ -33,9 +33,17 @@ public abstract class MessageEngine {
}
MessageType messageType = _data[2] == 0x00 ? MessageType.REQUEST : MessageType.RESPONSE;
ControllerMessageType controllerMessageType = ControllerMessageType.fromByte((byte)(_data[3] & 0xFF));
- int offset = ((messageType == MessageType.REQUEST) && NullUtils.isOneOf(controllerMessageType, ControllerMessageType.SendData, ControllerMessageType.ApplicationCommandHandler))?7:5;
- CommandClass commandClass = _data.length > offset + 1 ? CommandClass.fromByte((byte)(_data[offset] & 0xFF)):CommandClass.NO_OPERATION;
- byte command = ((commandClass == CommandClass.NO_OPERATION) || (_data.length <= offset+2))?0:(byte)(_data[offset+1] & 0xFF);
+ CommandClass commandClass = CommandClass.NO_OPERATION;
+ byte command = 0;
+ int offset = 5;
+ if (NullUtils.isOneOf(controllerMessageType, ControllerMessageType.SendData, ControllerMessageType.ApplicationCommandHandler)) {
+ if (messageType == MessageType.REQUEST)
+ offset = 7;
+ if (_data.length > offset + 1)
+ commandClass = CommandClass.fromByte((byte)(_data[offset] & 0xFF));
+ if (_data.length > offset + 2)
+ command = (byte)(_data[offset+1] & 0xFF);
+ }
Message message = messages.get(Message.toKey(controllerMessageType.data, messageType.data, commandClass.data, command));
if (message == null) {
logger.debug("Could not find message class for message: {} {} {} {}", controllerMessageType.label, messageType.name(), commandClass.label, command);
diff --git a/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/AddNodeToNetworkRequest.java b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/AddNodeToNetworkRequest.java
new file mode 100644
index 0000000..c48399a
--- /dev/null
+++ b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/AddNodeToNetworkRequest.java
@@ -0,0 +1,17 @@
+package com.lanternsoftware.zwave.message.impl;
+
+import com.lanternsoftware.zwave.message.ControllerMessageType;
+import com.lanternsoftware.zwave.message.NoCommandRequestMessage;
+
+public class AddNodeToNetworkRequest extends NoCommandRequestMessage {
+ public AddNodeToNetworkRequest() {
+ super(ControllerMessageType.AddNodeToNetwork);
+ }
+
+ @Override
+ public byte[] getPayload() {
+ byte[] payload = new byte[1];
+ payload[0] = (byte)0x05;
+ return payload;
+ }
+}
diff --git a/zwave/lantern-zwave/src/main/resources/META-INF/services/com.lanternsoftware.zwave.message.Message b/zwave/lantern-zwave/src/main/resources/META-INF/services/com.lanternsoftware.zwave.message.Message
index 231b36f..68627d2 100644
--- a/zwave/lantern-zwave/src/main/resources/META-INF/services/com.lanternsoftware.zwave.message.Message
+++ b/zwave/lantern-zwave/src/main/resources/META-INF/services/com.lanternsoftware.zwave.message.Message
@@ -1,3 +1,4 @@
+com.lanternsoftware.zwave.message.impl.AddNodeToNetworkRequest
com.lanternsoftware.zwave.message.impl.ApplicationUpdateRequest
com.lanternsoftware.zwave.message.impl.AssociationGetRequest
com.lanternsoftware.zwave.message.impl.AssociationReportRequest