mirror of
https://github.com/zyphlar/LanternPowerMonitor.git
synced 2024-03-08 14:07:47 +00:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
package com.lanternsoftware.zwave.context;
|
||||
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.MongoCurrentMonitorDao;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
public class Globals implements ServletContextListener {
|
||||
public static ZWaveApp app;
|
||||
public static MongoCurrentMonitorDao cmDao;
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
cmDao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
app = new ZWaveApp();
|
||||
app.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
if (app != null) {
|
||||
app.stop();
|
||||
app = null;
|
||||
}
|
||||
if (cmDao != null)
|
||||
cmDao.shutdown();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
package com.lanternsoftware.zwave.context;
|
||||
|
||||
import com.lanternsoftware.datamodel.zwave.Switch;
|
||||
import com.lanternsoftware.datamodel.zwave.SwitchSchedule;
|
||||
import com.lanternsoftware.datamodel.zwave.SwitchTransition;
|
||||
import com.lanternsoftware.datamodel.zwave.ThermostatMode;
|
||||
import com.lanternsoftware.datamodel.zwave.ZWaveConfig;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.DateUtils;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.concurrency.ConcurrencyUtils;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
import com.lanternsoftware.util.http.HttpPool;
|
||||
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.BinarySwitchSetRequest;
|
||||
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.ThermostatModeSetRequest;
|
||||
import com.lanternsoftware.zwave.message.impl.ThermostatSetPointReportRequest;
|
||||
import com.lanternsoftware.zwave.message.impl.ThermostatSetPointSetRequest;
|
||||
import com.lanternsoftware.zwave.message.thermostat.ThermostatSetPointIndex;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class ZWaveApp {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ZWaveApp.class);
|
||||
|
||||
private MongoZWaveDao dao;
|
||||
private ZWaveConfig config;
|
||||
private Controller controller;
|
||||
private final Map<Integer, Switch> switches = new HashMap<>();
|
||||
private final Map<Integer, List<Integer>> peers = new HashMap<>();
|
||||
private Timer timer;
|
||||
private HttpPool pool;
|
||||
private SwitchScheduleTask nextScheduleTask;
|
||||
private final Map<Integer, Double> temperatures = new HashMap<>();
|
||||
private final Object ZWAVE_MUTEX = new Object();
|
||||
|
||||
public void start() {
|
||||
try {
|
||||
dao = new MongoZWaveDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
controller = new Controller();
|
||||
controller.start("COM4");
|
||||
timer = new Timer("ZWaveApp Timer");
|
||||
pool = new HttpPool(10, 10, 30000, 10000, 10000);
|
||||
|
||||
//// for (int node = 3; node < 7; node++) {
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 7, new byte[]{99}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 8, new byte[]{0, (byte) 1}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 9, new byte[]{99}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 10, new byte[]{0, (byte) 1}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 11, new byte[]{99}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 12, new byte[]{0, (byte) 1}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// }
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
config = dao.getConfig(1);
|
||||
Map<String, List<Integer>> groups = new HashMap<>();
|
||||
for (Switch sw : CollectionUtils.makeNotNull(config.getSwitches())) {
|
||||
switches.put(sw.getNodeId(), sw);
|
||||
CollectionUtils.addToMultiMap(sw.getRoom() + ":" + sw.getName(), sw.getNodeId(), groups);
|
||||
}
|
||||
if (CollectionUtils.filterOne(config.getSwitches(), Switch::isUrlThermostat) != null) {
|
||||
timer.scheduleAtFixedRate(new ThermostatTask(), 0, 30000);
|
||||
}
|
||||
for (List<Integer> group : groups.values()) {
|
||||
for (Integer node : group) {
|
||||
peers.put(node, CollectionUtils.filter(group, _i -> !_i.equals(node)));
|
||||
}
|
||||
}
|
||||
scheduleNextTransition();
|
||||
|
||||
MessageEngine.subscribe(new IMessageSubscriber<MultilevelSensorReportRequest>() {
|
||||
@Override
|
||||
public Class<MultilevelSensorReportRequest> getHandledMessageClass() {
|
||||
return MultilevelSensorReportRequest.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(MultilevelSensorReportRequest _message) {
|
||||
synchronized (temperatures) {
|
||||
temperatures.put((int) _message.getNodeId(), _message.getTemperatureCelsius());
|
||||
temperatures.notify();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
MessageEngine.subscribe(new IMessageSubscriber<ThermostatSetPointReportRequest>() {
|
||||
@Override
|
||||
public Class<ThermostatSetPointReportRequest> getHandledMessageClass() {
|
||||
return ThermostatSetPointReportRequest.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(ThermostatSetPointReportRequest _message) {
|
||||
synchronized (switches) {
|
||||
Switch sw = switches.get((int) _message.getNodeId());
|
||||
if (sw != null) {
|
||||
if (NullUtils.isOneOf(_message.getIndex(), ThermostatSetPointIndex.HEATING, ThermostatSetPointIndex.COOLING)) {
|
||||
sw.setLevel((int) Math.round(_message.getTemperatureCelsius() * 1.8) + 32);
|
||||
persistConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
MessageEngine.subscribe(new IMessageSubscriber<MultilevelSwitchReportRequest>() {
|
||||
@Override
|
||||
public Class<MultilevelSwitchReportRequest> getHandledMessageClass() {
|
||||
return MultilevelSwitchReportRequest.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(MultilevelSwitchReportRequest _message) {
|
||||
synchronized (switches) {
|
||||
Switch sw = switches.get((int) _message.getNodeId());
|
||||
if (sw != null) {
|
||||
sw.setLevel(_message.getLevel());
|
||||
for (Integer node : CollectionUtils.makeNotNull(peers.get((int) _message.getNodeId()))) {
|
||||
sw = switches.get(node);
|
||||
sw.setLevel(_message.getLevel());
|
||||
logger.info("Mirror Event from node {} to node {}", _message.getNodeId(), node);
|
||||
controller.send(new MultilevelSwitchSetRequest(node.byteValue(), _message.getLevel()));
|
||||
}
|
||||
persistConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// controller.send(new MultilevelSensorGetRequest((byte)11));
|
||||
// controller.send(new ThermostatSetPointGetRequest((byte)11, ThermostatSetPointIndex.HEATING));
|
||||
// controller.send(new ThermostatSetPointGetRequest((byte)11, ThermostatSetPointIndex.COOLING));
|
||||
// controller.send(new ThermostatSetPointGetRequest((byte)11, ThermostatSetPointIndex.HEATING_ECON));
|
||||
// controller.send(new ThermostatSetPointGetRequest((byte)11, ThermostatSetPointIndex.COOLING_ECON));
|
||||
// controller.send(new ThermostatSetPointSupportedGetRequest((byte)11));
|
||||
// controller.send(new ThermostatSetPointCapabilitiesGetRequest((byte)11));
|
||||
// controller.send(new ThermostatSetPointSetRequest((byte)11, ThermostatSetPointIndex.HEATING_ECON, 72));
|
||||
// controller.send(new ThermostatModeSetRequest((byte)11, ThermostatMode.HEAT));
|
||||
// controller.send(new ThermostatModeGetRequest((byte)11));
|
||||
}
|
||||
|
||||
private void scheduleNextTransition() {
|
||||
TimeZone tz = TimeZone.getTimeZone("America/Chicago");
|
||||
if (nextScheduleTask != null)
|
||||
nextScheduleTask.cancel();
|
||||
List<SwitchTransition> nextTransitions = CollectionUtils.getAllSmallest(CollectionUtils.aggregate(switches.values(), _s->CollectionUtils.transform(_s.getSchedule(), _t->_t.getNextTransition(_s, tz))), Comparator.comparing(SwitchTransition::getTransitionTime));
|
||||
if (!CollectionUtils.isEmpty(nextTransitions)) {
|
||||
for (SwitchTransition tr : nextTransitions) {
|
||||
logger.info("Next transition scheduled for node {} to level {} at {}", tr.getSwitch().getNodeId(), tr.getLevel(), DateUtils.format("hh:mm:ssa", tz, tr.getTransitionTime()));
|
||||
}
|
||||
nextScheduleTask = new SwitchScheduleTask(nextTransitions);
|
||||
timer.schedule(nextScheduleTask, CollectionUtils.getFirst(nextTransitions).getTransitionTime());
|
||||
} else
|
||||
nextScheduleTask = null;
|
||||
}
|
||||
|
||||
public void setSwitchLevel(int _nodeId, int _level) {
|
||||
Switch sw = switches.get(_nodeId);
|
||||
if ((sw == null) || !sw.isPrimary())
|
||||
return;
|
||||
sw.setLevel(_level);
|
||||
if (!sw.isThermostat()) {
|
||||
setGroupSwitchLevel(_nodeId, _level, sw.isMultilevel());
|
||||
} else if (sw.isZWaveThermostat()) {
|
||||
controller.send(new ThermostatSetPointSetRequest((byte) sw.getNodeId(), sw.getThermostatMode() == ThermostatMode.COOL ? ThermostatSetPointIndex.COOLING : ThermostatSetPointIndex.HEATING, _level));
|
||||
} else {
|
||||
if (timer != null)
|
||||
timer.schedule(new ThermostatTask(), 0);
|
||||
persistConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public void setThermostatMode(int _nodeId, ThermostatMode _mode) {
|
||||
Switch sw = switches.get(_nodeId);
|
||||
if ((sw == null) || !sw.isPrimary() || !sw.isZWaveThermostat())
|
||||
return;
|
||||
controller.send(new ThermostatModeSetRequest((byte) sw.getNodeId(), com.lanternsoftware.zwave.message.thermostat.ThermostatMode.fromByte(_mode.data)));
|
||||
sw.setThermostatMode(_mode);
|
||||
persistConfig();
|
||||
}
|
||||
|
||||
public void setSwitchSchedule(int _nodeId, List<SwitchSchedule> _transitions) {
|
||||
Switch sw = switches.get(_nodeId);
|
||||
if ((sw == null) || !sw.isPrimary())
|
||||
return;
|
||||
sw.setSchedule(_transitions);
|
||||
persistConfig();
|
||||
scheduleNextTransition();
|
||||
}
|
||||
|
||||
public void setSwitchHold(int _nodeId, boolean _hold) {
|
||||
Switch sw = switches.get(_nodeId);
|
||||
if ((sw == null) || !sw.isPrimary())
|
||||
return;
|
||||
sw.setHold(_hold);
|
||||
persistConfig();
|
||||
}
|
||||
|
||||
private void persistConfig() {
|
||||
synchronized (this) {
|
||||
dao.putConfig(config);
|
||||
}
|
||||
}
|
||||
|
||||
public int getSwitchLevel(int _nodeId) {
|
||||
Switch sw = switches.get(_nodeId);
|
||||
return (sw != null) ? sw.getLevel() : 0;
|
||||
}
|
||||
|
||||
public ZWaveConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
controller.stop();
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
timer = null;
|
||||
}
|
||||
if (pool != null) {
|
||||
pool.shutdown();
|
||||
pool = null;
|
||||
}
|
||||
if (dao != null) {
|
||||
dao.shutdown();
|
||||
dao = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setGroupSwitchLevel(int _primary, int _level, boolean _multilevel) {
|
||||
List<Integer> nodes = CollectionUtils.asArrayList(_primary);
|
||||
nodes.addAll(CollectionUtils.makeNotNull(peers.get(_primary)));
|
||||
for (int node : nodes) {
|
||||
controller.send(_multilevel ? new MultilevelSwitchSetRequest((byte) node, _level) : new BinarySwitchSetRequest((byte) node, _level > 0));
|
||||
}
|
||||
}
|
||||
|
||||
private class ThermostatTask extends TimerTask {
|
||||
@Override
|
||||
public void run() {
|
||||
for (Switch sw : switches.values()) {
|
||||
try {
|
||||
if (sw.isUrlThermostat() && !sw.isThermometer()) {
|
||||
double tempF = getTemperatureCelsius(sw) * 1.8 + 32;
|
||||
if (tempF > sw.getLevel() + 0.4) {
|
||||
setGroupSwitchLevel(sw.getNodeId(), 0, false);
|
||||
logger.info("Turning {} {} off, temp is: {} set to: {}", sw.getRoom(), sw.getName(), tempF + " set to: ", sw.getLevel());
|
||||
} else if (tempF < sw.getLevel() - 0.4) {
|
||||
setGroupSwitchLevel(sw.getNodeId(), (byte) 0xf, false);
|
||||
logger.info("Turning {} {} on, temp is: {} set to: {}", sw.getRoom(), sw.getName(), tempF + " set to: ", sw.getLevel());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
logger.error("Failed to check temperature for thermostat {}", sw.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SwitchScheduleTask extends TimerTask {
|
||||
private final List<SwitchTransition> transitions;
|
||||
|
||||
SwitchScheduleTask(List<SwitchTransition> _transitions) {
|
||||
transitions = _transitions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (SwitchTransition tr : transitions) {
|
||||
if (!tr.getSwitch().isHold()) {
|
||||
logger.info("Executing scheduled transition of node {} to level {}", tr.getSwitch().getNodeId(), tr.getLevel());
|
||||
Globals.app.setSwitchLevel(tr.getSwitch().getNodeId(), tr.getLevel());
|
||||
}
|
||||
else
|
||||
logger.info("Skipping scheduled transition of node {} to level {}, switch is on hold", tr.getSwitch().getNodeId(), tr.getLevel());
|
||||
ConcurrencyUtils.sleep(100);
|
||||
}
|
||||
nextScheduleTask = null;
|
||||
Globals.app.scheduleNextTransition();
|
||||
}
|
||||
}
|
||||
|
||||
public double getTemperatureCelsius(int _nodeId) {
|
||||
return getTemperatureCelsius(switches.get(_nodeId));
|
||||
}
|
||||
|
||||
private double getTemperatureCelsius(Switch _sw) {
|
||||
if ((pool == null) || (_sw == null) || !(_sw.isThermometer() || _sw.isThermostat()))
|
||||
return 0.0;
|
||||
if (_sw.isUrlThermostat())
|
||||
return DaoSerializer.getDouble(DaoSerializer.parse(pool.executeToString(new HttpGet(_sw.getThermostatSource()))), "temp");
|
||||
else if (_sw.isZWaveThermostat()) {
|
||||
synchronized (ZWAVE_MUTEX) {
|
||||
synchronized (temperatures) {
|
||||
controller.send(new MultilevelSensorGetRequest((byte) _sw.getNodeId()));
|
||||
try {
|
||||
temperatures.wait(5000);
|
||||
} catch (InterruptedException _e) {
|
||||
_e.printStackTrace();
|
||||
}
|
||||
Double temp = temperatures.get(_sw.getNodeId());
|
||||
return (temp == null) ? 0.0 : temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
package com.lanternsoftware.zwave.context;
|
||||
|
||||
public class ZWaveSpring {
|
||||
/* private ZWaveConfig config;
|
||||
private static ZWaveSession session;
|
||||
private static Map<Integer, Switch> switches = new HashMap<>();
|
||||
private static Map<Integer, List<Integer>> peers = new HashMap<>();
|
||||
private static Timer timer;
|
||||
private static HttpPool pool;
|
||||
private static SwitchScheduleTask nextScheduleTask;
|
||||
|
||||
public void start() {
|
||||
try {
|
||||
// controller = new Controller();
|
||||
// controller.start("COM4");
|
||||
timer = new Timer("ZWaveApp Timer");
|
||||
pool = new HttpPool(10, 10, 30000, 10000, 10000);
|
||||
session = new LocalZwaveSession();
|
||||
session.connect();
|
||||
while (!session.isNetworkReady()) {
|
||||
System.out.println("Network not ready yet, sleeping");
|
||||
ConcurrencyUtils.sleep(1000);
|
||||
}
|
||||
// session.subscribe(new ZWaveEventListener());
|
||||
|
||||
// for (ZWaveNode node : session.getDeviceManager().getNodes()) {
|
||||
// for (CommandClass cc : node.getCommandClasses()) {
|
||||
// System.out.println(node.getNodeId() + " " + cc.getClassCode() + " " + cc.getLabel());
|
||||
// }
|
||||
// }
|
||||
|
||||
//// for (int node = 3; node < 7; node++) {
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 7, new byte[]{99}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 8, new byte[]{0, (byte) 1}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 9, new byte[]{99}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 10, new byte[]{0, (byte) 1}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 11, new byte[]{99}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// session.doAction(new ConfigurationSetAction(node, (byte) 12, new byte[]{0, (byte) 1}));
|
||||
// ConcurrencyUtils.sleep(100);
|
||||
// }
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
config = SerializationEngine.deserialize(ResourceLoader.loadFile(LanternFiles.OPS_PATH + "config.dat"), ZWaveConfig.class, SerializationEngine.SerializationType.JSON);
|
||||
Map<String, List<Integer>> groups = new HashMap<>();
|
||||
for (Switch sw : CollectionUtils.makeNotNull(config.getSwitches())) {
|
||||
switches.put(sw.getNodeId(), sw);
|
||||
CollectionUtils.addToMultiMap(sw.getRoom() + ":" + sw.getName(), sw.getNodeId(), groups);
|
||||
}
|
||||
if (CollectionUtils.filterOne(config.getSwitches(), _sw -> NullUtils.isNotEmpty(_sw.getThermostatSource())) != null) {
|
||||
timer.scheduleAtFixedRate(new ThermostatTask(), 0, 30000);
|
||||
}
|
||||
for (List<Integer> group : groups.values()) {
|
||||
for (Integer node : group) {
|
||||
peers.put(node, CollectionUtils.filter(group, _i -> !_i.equals(node)));
|
||||
}
|
||||
}
|
||||
scheduleNextTransition();
|
||||
}
|
||||
|
||||
public void scheduleNextTransition() {
|
||||
TimeZone tz = TimeZone.getTimeZone("America/Chicago");
|
||||
if (nextScheduleTask != null)
|
||||
nextScheduleTask.cancel();
|
||||
Switch next = null;
|
||||
SwitchTransition transition = null;
|
||||
Date transitionDate = null;
|
||||
for (Switch sw : switches.values()) {
|
||||
for (SwitchTransition t : CollectionUtils.makeNotNull(sw.getSchedule())) {
|
||||
Date nextTransition = t.getNextTransition(tz);
|
||||
if ((transitionDate == null) || nextTransition.before(transitionDate)) {
|
||||
transitionDate = nextTransition;
|
||||
transition = t;
|
||||
next = sw;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (transitionDate != null) {
|
||||
System.out.println("Next transition scheduled for node " + next.getNodeId() + " to level " + transition.getLevel() + " at " + DateUtils.format(tz, transitionDate, "hh:mm:ssa"));
|
||||
nextScheduleTask = new SwitchScheduleTask(next, transition);
|
||||
timer.schedule(nextScheduleTask, transitionDate);
|
||||
} else
|
||||
nextScheduleTask = null;
|
||||
}
|
||||
|
||||
public void setSwitchLevel(int _nodeId, int _level) {
|
||||
Switch sw = switches.get(_nodeId);
|
||||
if ((sw == null) || !sw.isPrimary())
|
||||
return;
|
||||
sw.setLevel(_level);
|
||||
if (NullUtils.isEmpty(sw.getThermostatSource())) {
|
||||
doGroupSwitchAction(_nodeId, _level, sw.isMultilevel());
|
||||
} else {
|
||||
if (timer != null)
|
||||
timer.schedule(new ThermostatTask(), 0);
|
||||
persistConfig();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setSwitchSchedule(int _nodeId, List<SwitchTransition> _transitions) {
|
||||
Switch sw = switches.get(_nodeId);
|
||||
if ((sw == null) || !sw.isPrimary())
|
||||
return;
|
||||
sw.setSchedule(_transitions);
|
||||
persistConfig();
|
||||
scheduleNextTransition();
|
||||
}
|
||||
|
||||
public void setSwitchHold(int _nodeId, boolean _hold) {
|
||||
Switch sw = switches.get(_nodeId);
|
||||
if ((sw == null) || !sw.isPrimary())
|
||||
return;
|
||||
sw.setHold(_hold);
|
||||
persistConfig();
|
||||
}
|
||||
|
||||
private void persistConfig() {
|
||||
synchronized (this) {
|
||||
ResourceLoader.writeFile(LanternFiles.OPS_PATH + "config.dat", SerializationEngine.serialize(config, SerializationEngine.SerializationType.JSON));
|
||||
}
|
||||
}
|
||||
|
||||
public int getSwitchLevel(int _nodeId) {
|
||||
Switch sw = switches.get(_nodeId);
|
||||
return (sw != null) ? sw.getLevel() : 0;
|
||||
}
|
||||
|
||||
public ZWaveConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
session.shutdown();
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
timer = null;
|
||||
}
|
||||
if (pool != null) {
|
||||
pool.shutdown();
|
||||
pool = null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public static class ZWaveEventListener implements EventHandler {
|
||||
@EventSubscribe
|
||||
public void receive(ZWaveEvent event) throws Exception {
|
||||
if (event instanceof ApplicationCommandEvent) {
|
||||
ApplicationCommandEvent ace = (ApplicationCommandEvent) event;
|
||||
if (ace.getCommandClass() == CommandClass.SWITCH_MULTILEVEL) {
|
||||
for (Integer node : CollectionUtils.makeNotNull(peers.get(ace.getNodeId()))) {
|
||||
Switch sw = switches.get(node);
|
||||
System.out.println("Mirror Event from node " + ((ApplicationCommandEvent) event).getNodeId() + " to node " + node);
|
||||
// session.doAction(new SwitchAction(node, ace.getPayload()[1], sw == null || sw.isMultilevel()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventSubscribe
|
||||
public void handleSensorEvent(DeviceSensorEvent sensorEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
private void doGroupSwitchAction(int _primary, int _level, boolean _multilevel) {
|
||||
List<Integer> nodes = CollectionUtils.asArrayList(_primary);
|
||||
nodes.addAll(CollectionUtils.makeNotNull(peers.get(_primary)));
|
||||
for (int node : nodes) {
|
||||
try {
|
||||
session.doAction(new SwitchAction(node, _level, _multilevel));
|
||||
} catch (HomeAutomationException _e) {
|
||||
_e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ThermostatTask extends TimerTask {
|
||||
@Override
|
||||
public void run() {
|
||||
for (Switch sw : switches.values()) {
|
||||
if (NullUtils.isNotEmpty(sw.getThermostatSource())) {
|
||||
double tempF = getTemperatureCelsius(sw) * 1.8 + 32;
|
||||
if (tempF > sw.getLevel() + 0.4) {
|
||||
doGroupSwitchAction(sw.getNodeId(), 0, false);
|
||||
System.out.println("Turning " + sw.getRoom() + " " + sw.getName() + " off, temp is: " + tempF + " set to: " + sw.getLevel());
|
||||
} else if (tempF < sw.getLevel() - 0.4) {
|
||||
doGroupSwitchAction(sw.getNodeId(), (byte) 0xf, false);
|
||||
System.out.println("Turning " + sw.getRoom() + " " + sw.getName() + " on, temp is: " + tempF + " set to: " + sw.getLevel());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SwitchScheduleTask extends TimerTask {
|
||||
private final Switch sw;
|
||||
private final SwitchTransition transition;
|
||||
|
||||
public SwitchScheduleTask(Switch _sw, SwitchTransition _transition) {
|
||||
sw = _sw;
|
||||
transition = _transition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("Executing scheduled transition of node " + sw.getNodeId() + " to level " + transition.getLevel());
|
||||
if (!sw.isHold()) {
|
||||
Globals.app.setSwitchLevel(sw.getNodeId(), transition.getLevel());
|
||||
}
|
||||
nextScheduleTask = null;
|
||||
Globals.app.scheduleNextTransition();
|
||||
}
|
||||
}
|
||||
|
||||
public double getTemperatureCelsius(int _nodeId) {
|
||||
return getTemperatureCelsius(switches.get(_nodeId));
|
||||
}
|
||||
|
||||
private static double getTemperatureCelsius(Switch _sw) {
|
||||
if ((pool == null) || (_sw == null) || NullUtils.isEmpty(_sw.getThermostatSource()))
|
||||
return 0.0;
|
||||
return BsonUtils.getDouble(BsonUtils.parse(pool.executeToString(new HttpGet(_sw.getThermostatSource()))), "temp");
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.lanternsoftware.zwave.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.zwave.ZWaveConfig;
|
||||
import com.lanternsoftware.util.dao.DaoQuery;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoProxy;
|
||||
|
||||
public class MongoZWaveDao implements ZWaveDao {
|
||||
private MongoProxy proxy;
|
||||
|
||||
public MongoZWaveDao(MongoConfig _config) {
|
||||
proxy = new MongoProxy(_config);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
proxy.shutdown();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void putConfig(ZWaveConfig _config) {
|
||||
proxy.save(_config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZWaveConfig getConfig(int _accountId) {
|
||||
return proxy.queryOne(ZWaveConfig.class, new DaoQuery("_id", String.valueOf(_accountId)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.lanternsoftware.zwave.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.zwave.ZWaveConfig;
|
||||
|
||||
public interface ZWaveDao {
|
||||
void putConfig(ZWaveConfig _config);
|
||||
ZWaveConfig getConfig(int _accountId);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.lanternsoftware.zwave.servlet;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
import com.lanternsoftware.zwave.context.Globals;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@WebServlet("/config")
|
||||
public class ConfigServlet extends SecureServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
jsonResponse(_rep, Globals.app.getConfig());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.lanternsoftware.zwave.servlet;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
import com.lanternsoftware.zwave.context.Globals;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public abstract class SecureServlet extends ZWaveServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
AuthCode authCode = Globals.cmDao.decryptAuthCode(_req.getHeader("auth_code"));
|
||||
if ((authCode == null) || (authCode.getAccountId() != 1)) {
|
||||
_rep.setStatus(401);
|
||||
return;
|
||||
}
|
||||
get(authCode, _req, _rep);
|
||||
}
|
||||
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
AuthCode authCode = Globals.cmDao.decryptAuthCode(_req.getHeader("auth_code"));
|
||||
if ((authCode == null) || (authCode.getAccountId() != 1)) {
|
||||
_rep.setStatus(401);
|
||||
return;
|
||||
}
|
||||
post(authCode, _req, _rep);
|
||||
}
|
||||
|
||||
protected void post(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.lanternsoftware.zwave.servlet;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
import com.lanternsoftware.datamodel.zwave.SwitchSchedule;
|
||||
import com.lanternsoftware.datamodel.zwave.ThermostatMode;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.zwave.context.Globals;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
@WebServlet("/switch/*")
|
||||
public class SwitchServlet extends SecureServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String[] path = path(_req);
|
||||
int nodeId = NullUtils.toInteger(CollectionUtils.get(path, 0));
|
||||
if (path.length == 1) {
|
||||
setResponseEntity(_rep, "application/json", "{level:" + Globals.app.getSwitchLevel(nodeId) + "}");
|
||||
} else {
|
||||
if (nodeId > 0) {
|
||||
String command = CollectionUtils.get(path, 1);
|
||||
if ("hold".equals(command))
|
||||
Globals.app.setSwitchHold(nodeId, true);
|
||||
else if ("run".equals(command))
|
||||
Globals.app.setSwitchHold(nodeId, false);
|
||||
else if ("mode".equals(command))
|
||||
Globals.app.setThermostatMode(nodeId, ThermostatMode.fromByte(Byte.parseByte(CollectionUtils.get(path, 2))));
|
||||
else {
|
||||
Globals.app.setSwitchLevel(nodeId, NullUtils.toInteger(command));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void post(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String[] path = path(_req);
|
||||
int nodeId = NullUtils.toInteger(CollectionUtils.get(path, 0));
|
||||
if (path.length > 1) {
|
||||
String command = CollectionUtils.get(path, 1);
|
||||
if ("schedule".equals(command)) {
|
||||
String json = getRequestPayloadAsString(_req);
|
||||
List<SwitchSchedule> transitions = DaoSerializer.parseList(json, SwitchSchedule.class);
|
||||
Globals.app.setSwitchSchedule(nodeId, transitions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.lanternsoftware.zwave.servlet;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
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.zwave.context.Globals;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/temperature/*")
|
||||
public class TemperatureServlet extends SecureServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String[] path = path(_req);
|
||||
DaoEntity json = new DaoEntity("temp", Globals.app.getTemperatureCelsius(NullUtils.toInteger(CollectionUtils.get(path, 0))));
|
||||
jsonResponse(_rep, DaoSerializer.toJson(json));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.lanternsoftware.zwave.servlet;
|
||||
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public abstract class ZWaveServlet 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);
|
||||
}
|
||||
}
|
||||
|
||||
protected void zipBsonResponse(HttpServletResponse _response, Object _object)
|
||||
{
|
||||
setResponseEntity(_response, 200, MediaType.APPLICATION_OCTET_STREAM, DaoSerializer.toZipBson(_object));
|
||||
}
|
||||
|
||||
protected void jsonResponse(HttpServletResponse _response, Object _object)
|
||||
{
|
||||
setResponseEntity(_response, 200, MediaType.APPLICATION_JSON, DaoSerializer.toJson(_object));
|
||||
}
|
||||
|
||||
protected void jsonResponse(HttpServletResponse _response, String _json)
|
||||
{
|
||||
setResponseEntity(_response, 200, MediaType.APPLICATION_JSON, _json);
|
||||
}
|
||||
|
||||
protected String getRequestPayloadAsString(HttpServletRequest _req) {
|
||||
return NullUtils.toString(getRequestPayload(_req));
|
||||
}
|
||||
|
||||
protected byte[] getRequestPayload(HttpServletRequest _req) {
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = _req.getInputStream();
|
||||
return IOUtils.toByteArray(is);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
finally {
|
||||
IOUtils.closeQuietly(is);
|
||||
}
|
||||
}
|
||||
|
||||
protected String[] path(HttpServletRequest _req) {
|
||||
return NullUtils.cleanSplit(NullUtils.makeNotNull(_req.getPathInfo()), "/");
|
||||
}
|
||||
}
|
||||
17
zwave/lantern-service-zwave/src/main/resources/logback.xml
Normal file
17
zwave/lantern-service-zwave/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<property name="log.pattern" value="%date %-5level %logger{0} - %message%n"/>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
||||
<logger name="com.lanternsoftware" level="INFO"/>
|
||||
|
||||
<root level="OFF">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1,59 @@
|
||||
Power,Mode,Temperature,Code
|
||||
Off,Heat,72,0000 006C 0000 0083 0010 00D1 0010 0010 0010 0011 0010 00F1 0010 0030 0010 0030 0010 0071 0010 0030 0010 0010 0010 0031 0010 0031 0010 0030 0010 0011 0010 01B2 0080 0041 0010 0031 0010 0030 0010 0011 0010 0010 0010 0011 0010 0031 0010 0010 0010 0010 0010 0031 0010 0031 0010 0011 0010 0031 0010 0011 0010 0011 0010 0031 0010 0031 0010 0010 0010 0031 0010 0031 0010 0010 0010 0011 0010 0031 0010 0010 0010 0010 0010 0031 0010 0011 0010 0010 0010 0010 0010 0071 0010 0091 0010 0011 0010 00B1 0010 0091 0010 0071 0010 0011 0010 0011 0010 0031 0010 0010 0010 0010 0010 0031 0010 0031 0010 0010 0010 0031 0010 0011 0010 0011 0010 0011 0010 0030 0010 0010 0010 0051 0010 0010 0010 0010 0010 0011 0010 0011 0010 0071 0010 0030 0010 0010 0010 0031 0010 0010 0010 0010 0010 0031 0010 0031 0010 0031 0010 0010 0010 0031 0010 0031 0010 0010 0010 0010 0010 0010 0010 0010 0010 0011 0010 0011 0010 0011 0010 0010 0010 0010 0010 0011 0010 0010 0010 0031 0010 0010 0010 0010 0010 0010 0010 0011 0010 0011 0010 0011 0010 0011 0010 0030 0010 0010 0010 0011 0010 0051 0010 0010 0010 0010 0010 0010 0010 0031 0010 0011 0010 0010 0010 0030 0010 0010 0010 0031 0010 0010 0010 0010 0010 0010 0010 0071 0010 0010 0010 0031 0010 0031 0010 0010 0010 0011 0010 0010 0010 0010 0010 0030 0010 0031 0010 0010 0010 0030 0010 0031 0010 0031 0010 0011 0010 02CF
|
||||
On,Heat,61,
|
||||
On,Heat,62,
|
||||
On,Heat,63,
|
||||
On,Heat,64,
|
||||
On,Heat,65,
|
||||
On,Heat,66,0000 006D 0000 00BF 0080 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 01B1 0080 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0F8E
|
||||
On,Heat,67,0000 006D 0000 00BF 007F 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0030 0010 0030 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 01AF 007F 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0F83
|
||||
On,Heat,68,0000 006D 0000 00BF 0080 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0030 0010 0030 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 01B0 0080 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0F8D
|
||||
On,Heat,69,0000 006D 0000 00BF 0080 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0030 0010 0030 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 01B0 0080 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0F8B
|
||||
On,Heat,70,0000 006D 0000 00BF 0080 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 01B0 0080 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0F8A
|
||||
On,Heat,71,0000 006D 0000 00BF 0080 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 01AF 007F 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0F86
|
||||
On,Heat,72,0000 006D 0000 00BF 0080 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 01B0 007F 0040 0010 0030 0010 0030 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0F89
|
||||
On,Heat,73,
|
||||
On,Heat,74,
|
||||
On,Heat,75,
|
||||
On,Heat,76,
|
||||
On,Heat,77,
|
||||
On,Heat,78,
|
||||
On,Heat,79,
|
||||
On,Heat,80,
|
||||
On,Heat,81,
|
||||
On,Heat,82,
|
||||
On,Heat,83,
|
||||
On,Heat,84,
|
||||
On,Heat,85,
|
||||
On,Heat,86,
|
||||
On,Heat,87,
|
||||
On,Heat,88,
|
||||
Off,Cool,72,
|
||||
On,Cool,61,
|
||||
On,Cool,62,
|
||||
On,Cool,63,
|
||||
On,Cool,64,
|
||||
On,Cool,65,
|
||||
On,Cool,66,
|
||||
On,Cool,67,
|
||||
On,Cool,68,
|
||||
On,Cool,69,
|
||||
On,Cool,70,
|
||||
On,Cool,71,
|
||||
On,Cool,72,
|
||||
On,Cool,73,
|
||||
On,Cool,74,
|
||||
On,Cool,75,
|
||||
On,Cool,76,
|
||||
On,Cool,77,
|
||||
On,Cool,78,
|
||||
On,Cool,79,
|
||||
On,Cool,80,
|
||||
On,Cool,81,
|
||||
On,Cool,82,
|
||||
On,Cool,83,
|
||||
On,Cool,84,
|
||||
On,Cool,85,
|
||||
On,Cool,86,
|
||||
On,Cool,87,
|
||||
On,Cool,88,
|
||||
|
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE web-app PUBLIC
|
||||
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
|
||||
"http://java.sun.com/dtd/web-app_2_3.dtd" >
|
||||
|
||||
<web-app>
|
||||
<listener>
|
||||
<listener-class>com.lanternsoftware.zwave.context.Globals</listener-class>
|
||||
</listener>
|
||||
</web-app>
|
||||
Reference in New Issue
Block a user