diff --git a/currentmonitor/lantern-currentmonitor/src/test/java/com/lanternsoftware/currentmonitor/CreateConfig.java b/currentmonitor/lantern-currentmonitor/src/test/java/com/lanternsoftware/currentmonitor/CreateConfig.java index c882746..cd9b95e 100644 --- a/currentmonitor/lantern-currentmonitor/src/test/java/com/lanternsoftware/currentmonitor/CreateConfig.java +++ b/currentmonitor/lantern-currentmonitor/src/test/java/com/lanternsoftware/currentmonitor/CreateConfig.java @@ -1,15 +1,28 @@ package com.lanternsoftware.currentmonitor; +import com.lanternsoftware.datamodel.currentmonitor.Breaker; +import com.lanternsoftware.util.CollectionUtils; import com.lanternsoftware.util.LanternFiles; import com.lanternsoftware.util.ResourceLoader; import com.lanternsoftware.util.dao.DaoSerializer; public class CreateConfig { public static void main(String[] args) { -// MonitorConfig c = new MonitorConfig(0, "https://mark.lanternsoftware.com/currentmonitor"); - MonitorConfig c = new MonitorConfig(1, "https://mark.lanternsoftware.com/currentmonitor"); - c.setDebug(true); - ResourceLoader.writeFile(LanternFiles.OPS_PATH + "hub1.json", DaoSerializer.toJson(c)); + MonitorConfig c = new MonitorConfig(1, "https://lanternsoftware.com/currentmonitor"); + c.setHost(""); + c.setDebug(false); + c.setMqttBrokerUrl("http://192.168.1.80:1883"); + c.setMqttFrequency(60); + c.setMqttPortCalibrationFactor(1.0); + c.setMqttVoltageCalibrationFactor(1.0); + Breaker b1 = new Breaker(); + b1.setPanel(0); + b1.setSpace(1); + b1.setHub(0); + b1.setPort(1); + b1.setSizeAmps(20); + c.setMqttBreakers(CollectionUtils.asArrayList(b1)); + ResourceLoader.writeFile(LanternFiles.OPS_PATH + "mqtt1.json", DaoSerializer.toJson(c)); } } diff --git a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/SignupServlet.java b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/SignupServlet.java index 3a8a6a3..a6cb0d4 100644 --- a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/SignupServlet.java +++ b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/SignupServlet.java @@ -12,13 +12,14 @@ import com.lanternsoftware.util.servlet.LanternServlet; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.Locale; @WebServlet("/signup") public class SignupServlet extends LanternServlet { @Override protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) { BasicAuth auth = new BasicAuth(_req); - Account acct = Globals.dao.getAccountByUsername(auth.getUsername()); + Account acct = Globals.dao.getAccountByUsername(auth.getUsername().toLowerCase().trim()); if (acct != null) { jsonResponse(_rep, SignupResponse.error("An account for " + auth.getUsername() + " already exists")); return; diff --git a/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/Switch.java b/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/Switch.java index 3c359a9..2f4e882 100644 --- a/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/Switch.java +++ b/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/Switch.java @@ -21,7 +21,7 @@ public class Switch { private boolean hold; private boolean hidden; private boolean suppressEvents; - private String thermometerUrl; + private String sourceUrl; private String controllerUrl; private ThermostatMode thermostatMode; private int lowLevel; @@ -30,18 +30,18 @@ public class Switch { public Switch() { } - public Switch(String _room, String _name, int _nodeId, boolean _primary, boolean _multilevel, String _thermometerUrl, int _lowLevel) { - this(_room, _name, _nodeId, 0, _primary, false, _thermometerUrl, _lowLevel, null); + public Switch(String _room, String _name, int _nodeId, boolean _primary, boolean _multilevel, String _sourceUrl, int _lowLevel) { + this(_room, _name, _nodeId, 0, _primary, false, _sourceUrl, _lowLevel, null); } - public Switch(String _room, String _name, int _nodeId, int _level, boolean _primary, boolean _hold, String _thermometerUrl, int _lowLevel, List _schedule) { + public Switch(String _room, String _name, int _nodeId, int _level, boolean _primary, boolean _hold, String _sourceUrl, int _lowLevel, List _schedule) { room = _room; name = _name; nodeId = _nodeId; level = _level; primary = _primary; hold = _hold; - thermometerUrl = _thermometerUrl; + sourceUrl = _sourceUrl; lowLevel = _lowLevel; schedule = _schedule; } @@ -128,12 +128,12 @@ public class Switch { hold = _hold; } - public String getThermometerUrl() { - return thermometerUrl; + public String getSourceUrl() { + return sourceUrl; } - public void setThermometerUrl(String _thermometerUrl) { - thermometerUrl = _thermometerUrl; + public void setSourceUrl(String _sourceUrl) { + sourceUrl = _sourceUrl; } public String getControllerUrl() { @@ -152,8 +152,8 @@ public class Switch { return type == SwitchType.SPACE_HEATER_THERMOSTAT; } - public boolean isThermometerUrlValid() { - return NullUtils.makeNotNull(thermometerUrl).startsWith("http"); + public boolean isSourceUrlValid() { + return NullUtils.makeNotNull(sourceUrl).startsWith("http"); } public boolean isZWaveThermostat() { @@ -244,7 +244,7 @@ public class Switch { s.setPrimary(isPrimary()); s.setHold(isHold()); s.setHidden(isHidden()); - s.setThermometerUrl(getThermometerUrl()); + s.setSourceUrl(getSourceUrl()); s.setControllerUrl(getControllerUrl()); s.setThermostatMode(getThermostatMode()); s.setLowLevel(getLowLevel()); diff --git a/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/SwitchType.java b/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/SwitchType.java index c1f1a60..88eaecc 100644 --- a/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/SwitchType.java +++ b/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/SwitchType.java @@ -8,5 +8,6 @@ public enum SwitchType { THERMOMETER, RELAY, SECURITY, - RELAY_BUTTON + RELAY_BUTTON, + CO2_SENSOR } diff --git a/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/ZWaveConfig.java b/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/ZWaveConfig.java index b79b769..7dd629d 100644 --- a/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/ZWaveConfig.java +++ b/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/ZWaveConfig.java @@ -5,7 +5,9 @@ import com.lanternsoftware.util.NullUtils; import com.lanternsoftware.util.dao.annotations.DBSerializable; import com.lanternsoftware.util.dao.annotations.PrimaryKey; +import java.util.ArrayList; import java.util.List; +import java.util.TreeSet; @DBSerializable(autogen = false) public class ZWaveConfig { @@ -75,4 +77,10 @@ public class ZWaveConfig { public boolean isMySwitch(Switch _sw) { return (isMaster() && NullUtils.isEmpty(_sw.getControllerUrl())) || _sw.isControlledBy(getUrl()); } + + public List getControllers() { + TreeSet controllers = new TreeSet<>(CollectionUtils.filter(CollectionUtils.transform(switches, Switch::getControllerUrl), NullUtils::isNotEmpty)); + controllers.add(masterUrl); + return new ArrayList<>(controllers); + } } diff --git a/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/dao/SwitchSerializer.java b/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/dao/SwitchSerializer.java index d1b70aa..1cbe891 100644 --- a/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/dao/SwitchSerializer.java +++ b/zwave/lantern-datamodel-zwave/src/main/java/com/lanternsoftware/datamodel/zwave/dao/SwitchSerializer.java @@ -39,7 +39,7 @@ public class SwitchSerializer extends AbstractDaoSerializer d.put("hold", _o.isHold()); d.put("hidden", _o.isHidden()); d.put("suppress_events", _o.isSuppressEvents()); - d.put("thermometer_url", _o.getThermometerUrl()); + d.put("source_url", _o.getSourceUrl()); d.put("controller_url", _o.getControllerUrl()); d.put("thermostat_mode", DaoSerializer.toEnumName(_o.getThermostatMode())); d.put("low_level", _o.getLowLevel()); @@ -62,7 +62,7 @@ public class SwitchSerializer extends AbstractDaoSerializer o.setHold(DaoSerializer.getBoolean(_d, "hold")); o.setHidden(DaoSerializer.getBoolean(_d, "hidden")); o.setSuppressEvents(DaoSerializer.getBoolean(_d, "suppress_events")); - o.setThermometerUrl(DaoSerializer.getString(_d, "thermometer_url")); + o.setSourceUrl(DaoSerializer.getString(_d, "source_url")); o.setControllerUrl(DaoSerializer.getString(_d, "controller_url")); o.setThermostatMode(DaoSerializer.getEnum(_d, "thermostat_mode", ThermostatMode.class)); o.setLowLevel(DaoSerializer.getInteger(_d, "low_level")); diff --git a/zwave/lantern-service-thermometer/pom.xml b/zwave/lantern-service-thermometer/pom.xml index 3160a85..ead746e 100644 --- a/zwave/lantern-service-thermometer/pom.xml +++ b/zwave/lantern-service-thermometer/pom.xml @@ -33,11 +33,7 @@ com.neuronrobotics nrjavaserial 5.2.1 - - - com.fazecast - jSerialComm - 2.5.1 + provided org.hid4java 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 index 921c6c9..37b71c8 100644 --- 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 @@ -28,11 +28,11 @@ public class MHZ19BCO2Sensor implements ICO2Sensor { private InputStream is; private OutputStream os; - private MHZ19BCO2Sensor(String _port) { + public MHZ19BCO2Sensor(String _port) { this(_port, DEFAULT_TIMEOUT); } - private MHZ19BCO2Sensor(String _port, int _timeout) { + public MHZ19BCO2Sensor(String _port, int _timeout) { try { CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(_port); serialPort = portIdentifier.open("co2port", 2000); diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/config/EnvironmentConfig.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/config/EnvironmentConfig.java new file mode 100644 index 0000000..fa472a5 --- /dev/null +++ b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/config/EnvironmentConfig.java @@ -0,0 +1,16 @@ +package com.lanternsoftware.thermometer.config; + +import com.lanternsoftware.util.dao.annotations.DBSerializable; + +@DBSerializable +public class EnvironmentConfig { + private String co2serialPort; + + public String getCo2serialPort() { + return co2serialPort; + } + + public void setCo2serialPort(String _co2serialPort) { + co2serialPort = _co2serialPort; + } +} diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/config/dao/EnvironmentConfigSerializer.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/config/dao/EnvironmentConfigSerializer.java new file mode 100644 index 0000000..6a957d2 --- /dev/null +++ b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/config/dao/EnvironmentConfigSerializer.java @@ -0,0 +1,39 @@ +package com.lanternsoftware.thermometer.config.dao; + +import com.lanternsoftware.thermometer.config.EnvironmentConfig; +import com.lanternsoftware.util.dao.AbstractDaoSerializer; +import com.lanternsoftware.util.dao.DaoEntity; +import com.lanternsoftware.util.dao.DaoProxyType; +import com.lanternsoftware.util.dao.DaoSerializer; +import java.util.Collections; +import java.util.List; + +public class EnvironmentConfigSerializer extends AbstractDaoSerializer +{ + @Override + public Class getSupportedClass() + { + return EnvironmentConfig.class; + } + + @Override + public List getSupportedProxies() { + return Collections.singletonList(DaoProxyType.MONGO); + } + + @Override + public DaoEntity toDaoEntity(EnvironmentConfig _o) + { + DaoEntity d = new DaoEntity(); + d.put("co2serial_port", _o.getCo2serialPort()); + return d; + } + + @Override + public EnvironmentConfig fromDaoEntity(DaoEntity _d) + { + EnvironmentConfig o = new EnvironmentConfig(); + o.setCo2serialPort(DaoSerializer.getString(_d, "co2serial_port")); + return o; + } +} \ No newline at end of file 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 d8d46aa..4be9eb7 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 @@ -2,7 +2,14 @@ package com.lanternsoftware.thermometer.context; import com.lanternsoftware.thermometer.DS18B20Thermometer; import com.lanternsoftware.thermometer.HidThermometer; +import com.lanternsoftware.thermometer.ICO2Sensor; import com.lanternsoftware.thermometer.IThermometer; +import com.lanternsoftware.thermometer.MHZ19BCO2Sensor; +import com.lanternsoftware.thermometer.config.EnvironmentConfig; +import com.lanternsoftware.util.LanternFiles; +import com.lanternsoftware.util.NullUtils; +import com.lanternsoftware.util.ResourceLoader; +import com.lanternsoftware.util.dao.DaoSerializer; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @@ -10,18 +17,25 @@ import java.util.ArrayList; import java.util.List; public class Globals implements ServletContextListener { + private static EnvironmentConfig config; public static List thermometers = new ArrayList<>(); + public static ICO2Sensor co2Sensor; @Override public void contextInitialized(ServletContextEvent sce) { + config = DaoSerializer.parse(ResourceLoader.loadFile(LanternFiles.OPS_PATH + "environment.json"), EnvironmentConfig.class); IThermometer t = new HidThermometer(); if (t.isConnected()) thermometers.add(t); thermometers.addAll(DS18B20Thermometer.devices()); + if ((config != null) && NullUtils.isNotEmpty(config.getCo2serialPort())) + co2Sensor = new MHZ19BCO2Sensor(config.getCo2serialPort()); } @Override public void contextDestroyed(ServletContextEvent sce) { thermometers.forEach(IThermometer::shutdown); + if (co2Sensor != null) + co2Sensor.shutdown(); } } diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/servlet/CO2Servlet.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/servlet/CO2Servlet.java new file mode 100644 index 0000000..a968fba --- /dev/null +++ b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/servlet/CO2Servlet.java @@ -0,0 +1,19 @@ +package com.lanternsoftware.thermometer.servlet; + +import com.lanternsoftware.thermometer.context.Globals; +import com.lanternsoftware.util.servlet.LanternServlet; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/co2") +public class CO2Servlet extends LanternServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + if (Globals.co2Sensor == null) + resp.setStatus(404); + else + setResponseEntity(resp, "application/json", "{\"ppm\": "+ Globals.co2Sensor.getPPM() + "}"); + } +} diff --git a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/servlet/ThermoServlet.java b/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/servlet/ThermoServlet.java deleted file mode 100644 index efe7e65..0000000 --- a/zwave/lantern-service-thermometer/src/main/java/com/lanternsoftware/thermometer/servlet/ThermoServlet.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.lanternsoftware.thermometer.servlet; - -import com.lanternsoftware.util.NullUtils; -import org.apache.commons.io.IOUtils; - -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletResponse; -import java.io.OutputStream; - -public abstract class ThermoServlet extends HttpServlet { - public static void setResponseHtml(HttpServletResponse _response, String _sHtml) { - setResponseEntity(_response, "text/html", _sHtml); - } - - public static void setResponseEntity(HttpServletResponse _response, String _sContentType, String _sEntity) { - setResponseEntity(_response, 200, _sContentType, _sEntity); - } - - public static void setResponseEntity(HttpServletResponse _response, String _sContentType, byte[] _btData) { - setResponseEntity(_response, 200, _sContentType, _btData); - } - - public static void setResponseEntity(HttpServletResponse _response, int _iStatus, String _sContentType, String _sEntity) { - setResponseEntity(_response, _iStatus, _sContentType, NullUtils.toByteArray(_sEntity)); - } - - public static void setResponseEntity(HttpServletResponse _response, int _iStatus, String _sContentType, byte[] _btData) { - OutputStream os = null; - try { - _response.setStatus(_iStatus); - _response.setCharacterEncoding("UTF-8"); - _response.setContentType(_sContentType); - if ((_btData != null) && (_btData.length > 0)) { - _response.setContentLength(_btData.length); - os = _response.getOutputStream(); - os.write(_btData); - } else - _response.setContentLength(0); - } catch (Exception e) { - e.printStackTrace(); - } finally { - IOUtils.closeQuietly(os); - } - } -} diff --git a/zwave/lantern-service-thermometer/src/main/resources/META-INF/services/com.lanternsoftware.util.dao.IDaoSerializer b/zwave/lantern-service-thermometer/src/main/resources/META-INF/services/com.lanternsoftware.util.dao.IDaoSerializer new file mode 100644 index 0000000..259ee95 --- /dev/null +++ b/zwave/lantern-service-thermometer/src/main/resources/META-INF/services/com.lanternsoftware.util.dao.IDaoSerializer @@ -0,0 +1 @@ +com.lanternsoftware.thermometer.config.dao.EnvironmentConfigSerializer diff --git a/zwave/lantern-service-thermometer/src/main/resources/logback.xml b/zwave/lantern-service-thermometer/src/main/resources/logback.xml index e39eed9..e869b85 100644 --- a/zwave/lantern-service-thermometer/src/main/resources/logback.xml +++ b/zwave/lantern-service-thermometer/src/main/resources/logback.xml @@ -11,7 +11,7 @@ /opt/tomcat/log/thermo.txt - /opt/currentmonitor/log/thermo.%d{yyyy-MM-dd}.%i.txt + /opt/tomcat/log/thermo.%d{yyyy-MM-dd}.%i.txt 20MB 20 diff --git a/zwave/lantern-service-thermometer/src/test/java/com/lanternsoftware/thermometer/GenerateEnvironmentSerializers.java b/zwave/lantern-service-thermometer/src/test/java/com/lanternsoftware/thermometer/GenerateEnvironmentSerializers.java new file mode 100644 index 0000000..b996dea --- /dev/null +++ b/zwave/lantern-service-thermometer/src/test/java/com/lanternsoftware/thermometer/GenerateEnvironmentSerializers.java @@ -0,0 +1,10 @@ +package com.lanternsoftware.thermometer; + +import com.lanternsoftware.util.LanternFiles; +import com.lanternsoftware.util.dao.generator.DaoSerializerGenerator; + +public class GenerateEnvironmentSerializers { + public static void main(String[] args) { + DaoSerializerGenerator.generateSerializers(LanternFiles.SOURCE_PATH, true, null); + } +} 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 d4aa332..d2dda92 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,7 +22,8 @@ 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.AddNodeToNetworkStartRequest; +import com.lanternsoftware.zwave.message.impl.AddNodeToNetworkStopRequest; import com.lanternsoftware.zwave.message.impl.BinarySwitchReportRequest; import com.lanternsoftware.zwave.message.impl.BinarySwitchSetRequest; import com.lanternsoftware.zwave.message.impl.CRC16EncapRequest; @@ -30,6 +31,8 @@ import com.lanternsoftware.zwave.message.impl.MultilevelSensorGetRequest; import com.lanternsoftware.zwave.message.impl.MultilevelSensorReportRequest; import com.lanternsoftware.zwave.message.impl.MultilevelSwitchReportRequest; import com.lanternsoftware.zwave.message.impl.MultilevelSwitchSetRequest; +import com.lanternsoftware.zwave.message.impl.RemoveNodeFromNetworkStartRequest; +import com.lanternsoftware.zwave.message.impl.RemoveNodeFromNetworkStopRequest; import com.lanternsoftware.zwave.message.impl.ThermostatModeSetRequest; import com.lanternsoftware.zwave.message.impl.ThermostatSetPointReportRequest; import com.lanternsoftware.zwave.message.impl.ThermostatSetPointSetRequest; @@ -127,10 +130,10 @@ public class ZWaveApp { mySwitches.put(sw.getNodeId(), sw); CollectionUtils.addToMultiMap(sw.getRoom() + ":" + sw.getName(), sw, groups); } - if (CollectionUtils.anyQualify(mySwitches.values(), Switch::isThermometerUrlValid)) { + if (CollectionUtils.anyQualify(mySwitches.values(), Switch::isSourceUrlValid)) { timer.scheduleAtFixedRate(new ThermostatTask(), 0, 30000); } - if (CollectionUtils.anyQualify(mySwitches.values(), _s->_s.isRelay() || _s.isRelayButton())) { + if (CollectionUtils.anyQualify(mySwitches.values(), _s->_s.isRelay() || _s.isRelayButton() || (_s.isSpaceHeaterThermostat() && _s.getGpioPin() != 0))) { relayController = new RelayController(); } List securitySwitches = CollectionUtils.filter(mySwitches.values(), Switch::isSecurity); @@ -227,7 +230,7 @@ public class ZWaveApp { } }); - controller.send(new MultilevelSwitchSetRequest((byte)2, 0xFF)); +// controller.send(new MultilevelSwitchSetRequest((byte)2, 0xFF)); // controller.send(new MultilevelSensorGetRequest((byte)11)); // controller.send(new ThermostatSetPointGetRequest((byte)11, ThermostatSetPointIndex.HEATING)); @@ -451,7 +454,8 @@ public class ZWaveApp { nodes.addAll(CollectionUtils.filter(peers.get(_primary.getNodeId()), _p->!_p.isPrimary())); for (Switch node : nodes) { logger.info("Setting {}, Node {} to {}", node.getName(), node.getNodeId(), _level); - controller.send(node.isMultilevel() ? new MultilevelSwitchSetRequest((byte) node.getNodeId(), _level) : new BinarySwitchSetRequest((byte) node.getNodeId(), _level > 0)); + byte nid = (byte) (node.getNodeId()%1000); + controller.send(node.isMultilevel() ? new MultilevelSwitchSetRequest(nid, _level) : new BinarySwitchSetRequest(nid, _level > 0)); } } @@ -469,16 +473,22 @@ public class ZWaveApp { if (_sw.isSpaceHeaterThermostat()) { double tempF = getTemperatureCelsius(_sw) * 1.8 + 32; if (tempF > _sw.getLevel() + 0.4) { - setGroupSwitchLevel(_sw, 0); + if (_sw.getGpioPin() > 0) + relayController.setRelay(_sw.getGpioPin(), _sw.getLowLevel() > 0); + else + setGroupSwitchLevel(_sw, 0); logger.info("Turning {} {} off, temp is: {} set to: {}", _sw.getRoom(), _sw.getName(), tempF, _sw.getLevel()); } else if (tempF < _sw.getLevel() - 0.4) { - setGroupSwitchLevel(_sw, 255); + if (_sw.getGpioPin() > 0) + relayController.setRelay(_sw.getGpioPin(), _sw.getLowLevel() == 0); + else + setGroupSwitchLevel(_sw, 255); logger.info("Turning {} {} on, temp is: {} set to: {}", _sw.getRoom(), _sw.getName(), tempF, _sw.getLevel()); } } } catch (Throwable t) { - logger.error("Failed to check temperature for thermostat {}", _sw.getName()); + logger.error("Failed to check temperature for thermostat {}", _sw.getName(), t); } } @@ -506,6 +516,13 @@ public class ZWaveApp { } } + public int getCO2ppm(int _nodeId) { + Switch sw = switches.get(_nodeId); + if (sw == null) + return 0; + return DaoSerializer.getInteger(DaoSerializer.parse(pool.executeToString(new HttpGet(sw.getSourceUrl()))), "ppm"); + } + public double getTemperatureCelsius(int _nodeId) { return getTemperatureCelsius(switches.get(_nodeId)); } @@ -513,8 +530,8 @@ public class ZWaveApp { private double getTemperatureCelsius(Switch _sw) { if ((pool == null) || (_sw == null)) return 0.0; - if (_sw.isThermometerUrlValid()) - return DaoSerializer.getDouble(DaoSerializer.parse(pool.executeToString(new HttpGet(_sw.getThermometerUrl()))), "temp"); + if (_sw.isSourceUrlValid()) + return DaoSerializer.getDouble(DaoSerializer.parse(pool.executeToString(new HttpGet(_sw.getSourceUrl()))), "temp"); else if (_sw.isZWaveThermostat() && config.isMySwitch(_sw)) { synchronized (ZWAVE_MUTEX) { synchronized (sensors) { @@ -531,4 +548,58 @@ public class ZWaveApp { } return 0.0; } + + public void addNodeToNetwork(boolean _enable, int _controllerIdx) { + ZWaveConfig config = Globals.app.getConfig(); + if (_enable) { + String controllerUrl = CollectionUtils.get(config.getControllers(), _controllerIdx); + if (NullUtils.isEqual(controllerUrl, config.getUrl()) && (controller != null)) + controller.send(new AddNodeToNetworkStartRequest()); + else { + HttpGet get = new HttpGet(controllerUrl + "/addNode/1/" + _controllerIdx); + get.setHeader("auth_code", authCode); + pool.execute(get); + } + } + else { + if (controller != null) + controller.send(new AddNodeToNetworkStopRequest()); + List controllers = config.getControllers(); + controllers.remove(config.getUrl()); + if (config.isMaster()) { + for (String controllerUrl : controllers) { + HttpGet get = new HttpGet(controllerUrl + "/addNode/0"); + get.setHeader("auth_code", authCode); + pool.execute(get); + } + } + } + } + + public void removeNodeFromNetwork(boolean _enable, int _controllerIdx) { + ZWaveConfig config = Globals.app.getConfig(); + if (_enable) { + String controllerUrl = CollectionUtils.get(config.getControllers(), _controllerIdx); + if (NullUtils.isEqual(controllerUrl, config.getUrl()) && (controller != null)) + controller.send(new RemoveNodeFromNetworkStartRequest()); + else { + HttpGet get = new HttpGet(controllerUrl + "/removeNode/1/" + _controllerIdx); + get.setHeader("auth_code", authCode); + pool.execute(get); + } + } + else { + if (controller != null) + controller.send(new RemoveNodeFromNetworkStopRequest()); + List controllers = config.getControllers(); + controllers.remove(config.getUrl()); + if (config.isMaster()) { + for (String controllerUrl : controllers) { + HttpGet get = new HttpGet(controllerUrl + "/removeNode/0"); + get.setHeader("auth_code", authCode); + pool.execute(get); + } + } + } + } } diff --git a/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/relay/RelayController.java b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/relay/RelayController.java index ad5cd48..51ab884 100644 --- a/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/relay/RelayController.java +++ b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/relay/RelayController.java @@ -26,6 +26,7 @@ public class RelayController { return; } } + LOG.info("Setting pin {} to {}", _pin, _on); if (_on) pin.high(); else diff --git a/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/servlet/AddNodeServlet.java b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/servlet/AddNodeServlet.java new file mode 100644 index 0000000..ee42c0b --- /dev/null +++ b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/servlet/AddNodeServlet.java @@ -0,0 +1,19 @@ +package com.lanternsoftware.zwave.servlet; + +import com.lanternsoftware.util.CollectionUtils; +import com.lanternsoftware.util.NullUtils; +import com.lanternsoftware.util.dao.DaoSerializer; +import com.lanternsoftware.util.dao.auth.AuthCode; +import com.lanternsoftware.zwave.context.Globals; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/addNode/*") +public class AddNodeServlet extends SecureServlet { + @Override + protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) { + Globals.app.addNodeToNetwork(NullUtils.isEqual(CollectionUtils.get(path(_req), 0), "1"), DaoSerializer.toInteger(CollectionUtils.get(path(_req), 1))); + } +} diff --git a/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/servlet/CO2Servlet.java b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/servlet/CO2Servlet.java new file mode 100644 index 0000000..bdd9084 --- /dev/null +++ b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/servlet/CO2Servlet.java @@ -0,0 +1,21 @@ +package com.lanternsoftware.zwave.servlet; + +import com.lanternsoftware.util.CollectionUtils; +import com.lanternsoftware.util.NullUtils; +import com.lanternsoftware.util.dao.DaoEntity; +import com.lanternsoftware.util.dao.DaoSerializer; +import com.lanternsoftware.util.dao.auth.AuthCode; +import com.lanternsoftware.zwave.context.Globals; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/co2/*") +public class CO2Servlet extends SecureServlet { + @Override + protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) { + String[] path = path(_req); + jsonResponse(_rep, DaoSerializer.toJson(new DaoEntity("ppm", Globals.app.getCO2ppm(NullUtils.toInteger(CollectionUtils.get(path, 0)))))); + } +} diff --git a/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/servlet/RemoveNodeServlet.java b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/servlet/RemoveNodeServlet.java new file mode 100644 index 0000000..a033ea5 --- /dev/null +++ b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/servlet/RemoveNodeServlet.java @@ -0,0 +1,19 @@ +package com.lanternsoftware.zwave.servlet; + +import com.lanternsoftware.util.CollectionUtils; +import com.lanternsoftware.util.NullUtils; +import com.lanternsoftware.util.dao.DaoSerializer; +import com.lanternsoftware.util.dao.auth.AuthCode; +import com.lanternsoftware.zwave.context.Globals; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/removeNode/*") +public class RemoveNodeServlet extends SecureServlet { + @Override + protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) { + Globals.app.removeNodeFromNetwork(NullUtils.isEqual(CollectionUtils.get(path(_req), 0), "1"), DaoSerializer.toInteger(CollectionUtils.get(path(_req), 1))); + } +} diff --git a/zwave/lantern-service-zwave/src/main/resources/logback.xml b/zwave/lantern-service-zwave/src/main/resources/logback.xml index ece41c5..0c83f96 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-zwave/pom.xml b/zwave/lantern-zwave/pom.xml index 45802e6..a333cf9 100644 --- a/zwave/lantern-zwave/pom.xml +++ b/zwave/lantern-zwave/pom.xml @@ -16,6 +16,7 @@ com.neuronrobotics nrjavaserial 5.2.1 + provided org.slf4j diff --git a/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/AddNodeToNetworkStartRequest.java b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/AddNodeToNetworkStartRequest.java new file mode 100644 index 0000000..2450a6f --- /dev/null +++ b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/AddNodeToNetworkStartRequest.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 AddNodeToNetworkStartRequest extends NoCommandRequestMessage { + public AddNodeToNetworkStartRequest() { + super(ControllerMessageType.AddNodeToNetwork); + } + + @Override + public byte[] getPayload() { + byte[] payload = new byte[1]; + payload[0] = (byte)0xC1; + return payload; + } +} 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/AddNodeToNetworkStopRequest.java similarity index 75% rename from zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/AddNodeToNetworkRequest.java rename to zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/AddNodeToNetworkStopRequest.java index c48399a..e7a1412 100644 --- 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/AddNodeToNetworkStopRequest.java @@ -3,8 +3,8 @@ 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() { +public class AddNodeToNetworkStopRequest extends NoCommandRequestMessage { + public AddNodeToNetworkStopRequest() { super(ControllerMessageType.AddNodeToNetwork); } diff --git a/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/RemoveNodeFromNetworkStartRequest.java b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/RemoveNodeFromNetworkStartRequest.java new file mode 100644 index 0000000..831dfed --- /dev/null +++ b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/RemoveNodeFromNetworkStartRequest.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 RemoveNodeFromNetworkStartRequest extends NoCommandRequestMessage { + public RemoveNodeFromNetworkStartRequest() { + super(ControllerMessageType.RemoveNodeFromNetwork); + } + + @Override + public byte[] getPayload() { + byte[] payload = new byte[1]; + payload[0] = (byte)0xC1; + return payload; + } +} diff --git a/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/RemoveNodeFromNetworkStopRequest.java b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/RemoveNodeFromNetworkStopRequest.java new file mode 100644 index 0000000..b71a56d --- /dev/null +++ b/zwave/lantern-zwave/src/main/java/com/lanternsoftware/zwave/message/impl/RemoveNodeFromNetworkStopRequest.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 RemoveNodeFromNetworkStopRequest extends NoCommandRequestMessage { + public RemoveNodeFromNetworkStopRequest() { + super(ControllerMessageType.RemoveNodeFromNetwork); + } + + @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 68627d2..11fb745 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,4 +1,5 @@ -com.lanternsoftware.zwave.message.impl.AddNodeToNetworkRequest +com.lanternsoftware.zwave.message.impl.AddNodeToNetworkStartRequest +com.lanternsoftware.zwave.message.impl.AddNodeToNetworkStopRequest com.lanternsoftware.zwave.message.impl.ApplicationUpdateRequest com.lanternsoftware.zwave.message.impl.AssociationGetRequest com.lanternsoftware.zwave.message.impl.AssociationReportRequest @@ -20,6 +21,8 @@ com.lanternsoftware.zwave.message.impl.MultilevelSwitchReportRequest com.lanternsoftware.zwave.message.impl.MultilevelSwitchSetRequest com.lanternsoftware.zwave.message.impl.NodeInfoRequest com.lanternsoftware.zwave.message.impl.NodeInfoResponse +com.lanternsoftware.zwave.message.impl.RemoveNodeFromNetworkStartRequest +com.lanternsoftware.zwave.message.impl.RemoveNodeFromNetworkStopRequest com.lanternsoftware.zwave.message.impl.SendDataRequest com.lanternsoftware.zwave.message.impl.SendDataResponse com.lanternsoftware.zwave.message.impl.ThermostatModeGetRequest