diff --git a/case/3A+/LPM_Case_Flange_3A+.blend b/case/3A+/LPM_Case_Flange_3A+.blend
index 87157c2..be65a05 100644
Binary files a/case/3A+/LPM_Case_Flange_3A+.blend and b/case/3A+/LPM_Case_Flange_3A+.blend differ
diff --git a/case/3A+/LPM_Case_Flange_3A+.stl b/case/3A+/LPM_Case_Flange_3A+.stl
index 389066b..c9d0ffc 100644
Binary files a/case/3A+/LPM_Case_Flange_3A+.stl and b/case/3A+/LPM_Case_Flange_3A+.stl differ
diff --git a/case/3A+/LPM_Case_Lid_3A+.blend b/case/3A+/LPM_Case_Lid_3A+.blend
index 5b0d876..9b09dd0 100644
Binary files a/case/3A+/LPM_Case_Lid_3A+.blend and b/case/3A+/LPM_Case_Lid_3A+.blend differ
diff --git a/case/3A+/LPM_Case_Lid_3A+.stl b/case/3A+/LPM_Case_Lid_3A+.stl
index ef94caa..bff7777 100644
Binary files a/case/3A+/LPM_Case_Lid_3A+.stl and b/case/3A+/LPM_Case_Lid_3A+.stl differ
diff --git a/case/Z2/LPM_Case_Z2_Base_Flange.blend b/case/Z2/LPM_Case_Z2_Base_Flange.blend
index fe5085f..f3e3f3a 100644
Binary files a/case/Z2/LPM_Case_Z2_Base_Flange.blend and b/case/Z2/LPM_Case_Z2_Base_Flange.blend differ
diff --git a/case/Z2/LPM_Case_Z2_Base_Flange.stl b/case/Z2/LPM_Case_Z2_Base_Flange.stl
index aec6d62..80263ba 100644
Binary files a/case/Z2/LPM_Case_Z2_Base_Flange.stl and b/case/Z2/LPM_Case_Z2_Base_Flange.stl differ
diff --git a/case/Z2/LPM_Case_Z2_Lid.blend b/case/Z2/LPM_Case_Z2_Lid.blend
index d50c95e..77281ee 100644
Binary files a/case/Z2/LPM_Case_Z2_Lid.blend and b/case/Z2/LPM_Case_Z2_Lid.blend differ
diff --git a/case/Z2/LPM_Case_Z2_Lid.stl b/case/Z2/LPM_Case_Z2_Lid.stl
index de5cf92..b80ffaf 100644
Binary files a/case/Z2/LPM_Case_Z2_Lid.stl and b/case/Z2/LPM_Case_Z2_Lid.stl differ
diff --git a/case/Z2/LPM_Case_Z2_Middle.blend b/case/Z2/LPM_Case_Z2_Middle.blend
index 36e3ed4..de18e2a 100644
Binary files a/case/Z2/LPM_Case_Z2_Middle.blend and b/case/Z2/LPM_Case_Z2_Middle.blend differ
diff --git a/case/Z2/LPM_Case_Z2_Middle.stl b/case/Z2/LPM_Case_Z2_Middle.stl
index 035f08d..40da7b1 100644
Binary files a/case/Z2/LPM_Case_Z2_Middle.stl and b/case/Z2/LPM_Case_Z2_Middle.stl differ
diff --git a/currentmonitor/lantern-currentmonitor/pom.xml b/currentmonitor/lantern-currentmonitor/pom.xml
index 0efbf53..c21dc13 100644
--- a/currentmonitor/lantern-currentmonitor/pom.xml
+++ b/currentmonitor/lantern-currentmonitor/pom.xml
@@ -3,7 +3,7 @@
com.lanternsoftware.currentmonitor
lantern-currentmonitor
jar
- 1.0.4
+ 1.0.6
lantern-currentmonitor
diff --git a/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/CurrentMonitor.java b/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/CurrentMonitor.java
index f11672a..4ea7013 100644
--- a/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/CurrentMonitor.java
+++ b/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/CurrentMonitor.java
@@ -97,12 +97,17 @@ public class CurrentMonitor {
}
public void monitorPower(BreakerHub _hub, List _breakers, int _intervalMs, PowerListener _listener) {
- stopMonitoring();
- listener = _listener;
- List validBreakers = CollectionUtils.filter(_breakers, _b->_b.getPort() > 0 && _b.getPort() < 16);
- sampler = new Sampler(_hub, validBreakers, _intervalMs, 2);
- LOG.info("Starting to monitor ports {}", CollectionUtils.transformToCommaSeparated(validBreakers, _b->String.valueOf(_b.getPort())));
- executor.submit(sampler);
+ try {
+ stopMonitoring();
+ listener = _listener;
+ List validBreakers = CollectionUtils.filter(_breakers, _b -> _b.getPort() > 0 && _b.getPort() < 16);
+ sampler = new Sampler(_hub, validBreakers, _intervalMs, 2);
+ LOG.info("Starting to monitor ports {}", CollectionUtils.transformToCommaSeparated(validBreakers, _b -> String.valueOf(_b.getPort())));
+ executor.submit(sampler);
+ }
+ catch (Throwable t) {
+ LOG.error("throwable", t);
+ }
}
private GpioPinAnalogInput getPin(int _chip, int _pin) {
@@ -182,8 +187,10 @@ public class CurrentMonitor {
try {
while (true) {
synchronized (this) {
- if (!running)
+ if (!running) {
+ LOG.error("Power Monitoring Stopped");
break;
+ }
}
final Date readTime = new Date();
final long intervalStart = (interval * intervalNs) + start;
diff --git a/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/MonitorApp.java b/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/MonitorApp.java
index ca90a0e..ab70184 100644
--- a/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/MonitorApp.java
+++ b/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/MonitorApp.java
@@ -10,6 +10,8 @@ import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
import com.lanternsoftware.datamodel.currentmonitor.BreakerHub;
import com.lanternsoftware.datamodel.currentmonitor.BreakerPower;
import com.lanternsoftware.datamodel.currentmonitor.BreakerPowerMinute;
+import com.lanternsoftware.datamodel.currentmonitor.HubCommand;
+import com.lanternsoftware.datamodel.currentmonitor.HubCommands;
import com.lanternsoftware.datamodel.currentmonitor.HubConfigCharacteristic;
import com.lanternsoftware.datamodel.currentmonitor.HubConfigService;
import com.lanternsoftware.datamodel.currentmonitor.HubPowerMinute;
@@ -25,6 +27,7 @@ import com.lanternsoftware.util.dao.DaoSerializer;
import com.lanternsoftware.util.http.HttpPool;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
@@ -39,10 +42,12 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.net.URL;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -64,7 +69,7 @@ public class MonitorApp {
private static final AtomicBoolean running = new AtomicBoolean(true);
private static final CurrentMonitor monitor = new CurrentMonitor();
private static final List readings = new ArrayList<>();
- private static final String version = getVersionNumber();
+ private static String version;
private static final PowerListener logger = _p -> {
if (!config.isDebug()) {
_p.setHubVersion(version);
@@ -76,9 +81,138 @@ public class MonitorApp {
} else
LOG.info("Panel{} - Space{} Power: {}W", _p.getPanel(), Breaker.toSpaceDisplay(_p.getSpace()), String.format("%.3f", _p.getPower()));
};
+ private static final BleCharacteristicListener bluetoothListener = new BleCharacteristicListener() {
+ @Override
+ public void write(String _name, byte[] _value) {
+ HubConfigCharacteristic ch = NullUtils.toEnum(HubConfigCharacteristic.class, _name);
+ LOG.info("Char Received, Name: {} Value: {}", _name, _value);
+ monitor.submit(()->{
+ synchronized (monitor) {
+ switch (ch) {
+ case Host:
+ if ((_value.length > 0)) {
+ config.setHost(NullUtils.terminateWith(NullUtils.toString(_value), "/") + "currentmonitor/");
+ ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config));
+ }
+ break;
+ case HubIndex:
+ if ((_value.length > 0)) {
+ config.setHub(_value[0]);
+ ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config));
+ }
+ break;
+ case AuthCode:
+ String value = NullUtils.toString(_value);
+ if (NullUtils.isNotEmpty(value)) {
+ authCode = value;
+ config.setAuthCode(value);
+ ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config));
+ }
+ break;
+ case WifiCredentials:
+ String ssid = HubConfigService.decryptWifiSSID(_value);
+ String pwd = HubConfigService.decryptWifiPassword(_value);
+ if (NullUtils.isNotEmpty(ssid) && NullUtils.isNotEmpty(pwd))
+ WifiConfig.setCredentials(ssid, pwd);
+ break;
+ case Flash:
+ if ((CollectionUtils.length(_value) == 0) || (_value[0] == 0)) {
+ if (flasher != null) {
+ flasher.stop();
+ flasher = null;
+ } else
+ LEDFlasher.setLEDOn(false);
+ } else {
+ if (flasher == null) {
+ flasher = new LEDFlasher();
+ monitor.submit(flasher);
+ }
+ }
+ break;
+ case Restart:
+ LOG.info("Restarting Current Monitor...");
+ try {
+ Runtime.getRuntime().exec(new String[]{"systemctl","restart","currentmonitor"});
+ } catch (IOException _e) {
+ LOG.error("Exception occurred while trying to restart", _e);
+ }
+ break;
+ case Reboot:
+ LOG.info("Rebooting Pi...");
+ try {
+ Runtime.getRuntime().exec(new String[]{"reboot","now"});
+ } catch (IOException _e) {
+ LOG.error("Exception occurred while trying to reboot", _e);
+ }
+ break;
+ case Shutdown:
+ LOG.info("Shutting down Pi...");
+ try {
+ Runtime.getRuntime().exec(new String[]{"shutdown","now"});
+ } catch (IOException _e) {
+ LOG.error("Exception occurred while trying to shutdown", _e);
+ }
+ break;
+ case Update:
+ monitor.submit(new UpdateChecker(true));
+ break;
+ case ReloadConfig:
+ HttpGet get = new HttpGet(host + "config");
+ get.addHeader("auth_code", authCode);
+ BreakerConfig newConfig = DaoSerializer.parse(pool.executeToString(get), BreakerConfig.class);
+ if (newConfig != null) {
+ breakerConfig = newConfig;
+ List breakers = breakerConfig.getBreakersForHub(config.getHub());
+ BreakerHub hub = breakerConfig.getHub(config.getHub());
+ if (hub != null) {
+ LOG.info("Monitoring {} breakers for hub {}", CollectionUtils.size(breakers), hub.getHub());
+ if (CollectionUtils.size(breakers) > 0)
+ monitor.monitorPower(hub, breakers, 1000, logger);
+ }
+ }
+ break;
+ }
+ }
+ });
+ }
+
+ @Override
+ public byte[] read(String _name) {
+ HubConfigCharacteristic ch = NullUtils.toEnum(HubConfigCharacteristic.class, _name);
+ if (HubConfigCharacteristic.HubIndex == ch)
+ return new byte[]{(byte)(config == null?0:config.getHub())};
+ if (HubConfigCharacteristic.AccountId == ch)
+ return ByteBuffer.allocate(4).putInt(breakerConfig == null?0:breakerConfig.getAccountId()).array();
+ if (HubConfigCharacteristic.NetworkState == ch)
+ return new byte[]{NetworkMonitor.getNetworkStatus().toMask()};
+ if (HubConfigCharacteristic.NetworkDetails == ch) {
+ NetworkStatus status = NetworkMonitor.getNetworkStatus();
+ DaoEntity meta = (host == null)?null:DaoSerializer.fromZipBson(pool.executeToByteArray(new HttpGet(host + "update/version")));
+ status.setPingSuccessful(CollectionUtils.isNotEmpty(meta));
+ return DaoSerializer.toZipBson(status);
+ }
+ if (HubConfigCharacteristic.Log == ch) {
+ String[] log = NullUtils.cleanSplit(ResourceLoader.loadFileAsString(WORKING_DIR + "log/log.txt"), "\n");
+ if (log.length > 15)
+ log = Arrays.copyOfRange(log, log.length-15, log.length);
+ return ZipUtils.zip(NullUtils.toByteArray(CollectionUtils.delimit(Arrays.asList(log), "\n")));
+ }
+ if (HubConfigCharacteristic.Version == ch)
+ return NullUtils.toByteArray(version);
+ return null;
+ }
+ };
+ private static BluetoothConfig bluetoothConfig;
private static MqttPoster mqttPoster;
public static void main(String[] args) {
+ try {
+ Runtime.getRuntime().exec(new String[]{"systemctl","restart","dbus"});
+ ConcurrencyUtils.sleep(500);
+ } catch (IOException _e) {
+ LOG.error("Exception occurred while trying to restart", _e);
+ }
+ version = getVersionNumber();
config = DaoSerializer.parse(ResourceLoader.loadFileAsString(WORKING_DIR + "config.json"), MonitorConfig.class);
if (config == null) {
LOG.error("Failed to load config file from {}", WORKING_DIR + "config.json");
@@ -90,107 +224,7 @@ public class MonitorApp {
monitor.setDebug(config.isDebug());
monitor.start();
LEDFlasher.setLEDOn(false);
- final BluetoothConfig bluetoothConfig = new BluetoothConfig("Lantern Hub", new BleCharacteristicListener() {
- @Override
- public void write(String _name, byte[] _value) {
- HubConfigCharacteristic ch = NullUtils.toEnum(HubConfigCharacteristic.class, _name);
- LOG.info("Char Received, Name: {} Value: {}", _name, _value);
- monitor.submit(()->{
- synchronized (monitor) {
- switch (ch) {
- case Host:
- if ((_value.length > 0)) {
- config.setHost(NullUtils.terminateWith(NullUtils.toString(_value), "/") + "currentmonitor/");
- ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config));
- }
- break;
- case HubIndex:
- if ((_value.length > 0)) {
- config.setHub(_value[0]);
- ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config));
- }
- break;
- case AuthCode:
- String value = NullUtils.toString(_value);
- if (NullUtils.isNotEmpty(value)) {
- authCode = value;
- config.setAuthCode(value);
- ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config));
- }
- break;
- case WifiCredentials:
- String ssid = HubConfigService.decryptWifiSSID(_value);
- String pwd = HubConfigService.decryptWifiPassword(_value);
- if (NullUtils.isNotEmpty(ssid) && NullUtils.isNotEmpty(pwd))
- WifiConfig.setCredentials(ssid, pwd);
- break;
- case Flash:
- if ((CollectionUtils.length(_value) == 0) || (_value[0] == 0)) {
- if (flasher != null) {
- flasher.stop();
- flasher = null;
- } else
- LEDFlasher.setLEDOn(false);
- } else {
- if (flasher == null) {
- flasher = new LEDFlasher();
- monitor.submit(flasher);
- }
- }
- break;
- case Restart:
- LOG.info("Restarting Current Monitor...");
- try {
- Runtime.getRuntime().exec(new String[]{"systemctl","restart","currentmonitor"});
- } catch (IOException _e) {
- LOG.error("Exception occurred while trying to restart", _e);
- }
- break;
- case Reboot:
- LOG.info("Rebooting Pi...");
- try {
- Runtime.getRuntime().exec(new String[]{"reboot","now"});
- } catch (IOException _e) {
- LOG.error("Exception occurred while trying to reboot", _e);
- }
- break;
- case Shutdown:
- LOG.info("Shutting down Pi...");
- try {
- Runtime.getRuntime().exec(new String[]{"shutdown","now"});
- } catch (IOException _e) {
- LOG.error("Exception occurred while trying to shutdown", _e);
- }
- break;
- }
- }
- });
- }
-
- @Override
- public byte[] read(String _name) {
- HubConfigCharacteristic ch = NullUtils.toEnum(HubConfigCharacteristic.class, _name);
- if (HubConfigCharacteristic.HubIndex == ch)
- return new byte[]{(byte)(config == null?0:config.getHub())};
- if (HubConfigCharacteristic.AccountId == ch)
- return ByteBuffer.allocate(4).putInt(breakerConfig == null?0:breakerConfig.getAccountId()).array();
- if (HubConfigCharacteristic.NetworkState == ch)
- return new byte[]{NetworkMonitor.getNetworkStatus().toMask()};
- if (HubConfigCharacteristic.NetworkDetails == ch) {
- NetworkStatus status = NetworkMonitor.getNetworkStatus();
- DaoEntity meta = (host == null)?null:DaoSerializer.fromZipBson(pool.executeToByteArray(new HttpGet(host + "update/version")));
- status.setPingSuccessful(CollectionUtils.isNotEmpty(meta));
- return DaoSerializer.toZipBson(status);
- }
- if (HubConfigCharacteristic.Log == ch) {
- String[] log = NullUtils.cleanSplit(ResourceLoader.loadFileAsString(WORKING_DIR + "log/log.txt"), "\n");
- if (log.length > 15)
- log = Arrays.copyOfRange(log, log.length-15, log.length);
- return ZipUtils.zip(NullUtils.toByteArray(CollectionUtils.delimit(Arrays.asList(log), "\n")));
- }
- return null;
- }
- });
+ bluetoothConfig = new BluetoothConfig("Lantern Hub", bluetoothListener);
bluetoothConfig.start();
if (NullUtils.isNotEmpty(config.getAuthCode()))
authCode = config.getAuthCode();
@@ -303,6 +337,7 @@ public class MonitorApp {
if (!readings.isEmpty()) {
mqttReadings.addAll(readings);
post = new DaoEntity("readings", DaoSerializer.toDaoEntities(readings));
+ post.put("hub", config.getHub());
if (curMinute != lastMinute) {
HubPowerMinute minute = new HubPowerMinute();
minute.setAccountId(breakerConfig.getAccountId());
@@ -336,7 +371,8 @@ public class MonitorApp {
}
if (post != null) {
byte[] payload = DaoSerializer.toZipBson(post);
- if (post(payload, "power/batch")) {
+ PostResponse resp = post(payload, "power/batch", HubCommands.class);
+ if (resp.success) {
File[] files = new File(WORKING_DIR + "cache").listFiles();
if (files != null) {
for (File file : files) {
@@ -347,6 +383,11 @@ public class MonitorApp {
break;
}
}
+ if (resp.t != null) {
+ for (HubCommand command : resp.t.getCommands()) {
+ bluetoothListener.write(command.getCharacteristic().name(), command.getData());
+ }
+ }
}
}
}
@@ -355,7 +396,6 @@ public class MonitorApp {
if (DateUtils.diffInSeconds(new Date(), lastUpdateCheck) >= config.getUpdateInterval()) {
lastUpdateCheck = new Date();
monitor.submit(new UpdateChecker());
- monitor.submit(new CommandChecker());
}
long now = new Date().getTime();
long duration = (now - firstPost)%1000;
@@ -371,34 +411,65 @@ public class MonitorApp {
}
}
- private static void uploadLog() {
- LOG.info("Commanded to upload log file, preparing...");
- String log = ResourceLoader.loadFileAsString(WORKING_DIR + "log/log.txt");
- if (NullUtils.isNotEmpty(log)) {
- DaoEntity payload = new DaoEntity("command", "log").and("payload", log);
- post(DaoSerializer.toZipBson(payload), "command");
- }
+ private static boolean post(byte[] _payload, String _path) {
+ return post(_payload, _path, Boolean.class).success;
}
- private static boolean post(byte[] _payload, String _path) {
+ private static PostResponse post(byte[] _payload, String _path, Class _class) {
if (NullUtils.isEmpty(host))
- return false;
+ return new PostResponse<>(false, null);
HttpPost post = new HttpPost(host + _path);
post.addHeader("auth_code", authCode);
post.setEntity(new ByteArrayEntity(_payload, ContentType.APPLICATION_OCTET_STREAM));
+ InputStream is = null;
CloseableHttpResponse resp = pool.execute(post);
try {
- return ((resp != null) && (resp.getStatusLine() != null) && (resp.getStatusLine().getStatusCode() == 200));
- } finally {
+ if ((resp != null) && (resp.getStatusLine() != null) && (resp.getStatusLine().getStatusCode() == 200)) {
+ T t = null;
+ HttpEntity entity = resp.getEntity();
+ if (entity != null) {
+ is = entity.getContent();
+ byte[] payload = IOUtils.toByteArray(is);
+ if (CollectionUtils.length(payload) > 0)
+ t = DaoSerializer.fromZipBson(payload, _class);
+ }
+ return new PostResponse<>(true, t);
+ }
+ }
+ catch (Exception _e) {
+ LOG.error("Failed to make http request to " + post.getURI().toString(), _e);
+ }
+ finally {
+ IOUtils.closeQuietly(is);
IOUtils.closeQuietly(resp);
}
+ return new PostResponse<>(false, null);
+ }
+
+ private static class PostResponse {
+ public final boolean success;
+ public final T t;
+
+ public PostResponse(boolean _success, T _t) {
+ success = _success;
+ t = _t;
+ }
}
-
private static final class UpdateChecker implements Runnable {
+ private final boolean force;
+
+ public UpdateChecker() {
+ force = false;
+ }
+
+ public UpdateChecker(boolean _force) {
+ force = _force;
+ }
+
@Override
public void run() {
- if (NullUtils.isNotEmpty(host) && config.isAutoUpdate()) {
+ if (NullUtils.isNotEmpty(host) && (force || config.isAutoUpdate())) {
DaoEntity meta = DaoSerializer.fromZipBson(pool.executeToByteArray(new HttpGet(host + "update/version")));
String newVersion = DaoSerializer.getString(meta, "version");
if (NullUtils.isNotEqual(newVersion, version)) {
@@ -407,9 +478,14 @@ public class MonitorApp {
if (CollectionUtils.length(jar) == DaoSerializer.getInteger(meta, "size") && NullUtils.isEqual(DigestUtils.md5Hex(jar), DaoSerializer.getString(meta, "checksum"))) {
LOG.info("Update downloaded, writing jar and restarting...");
ResourceLoader.writeFile(WORKING_DIR + "lantern-currentmonitor.jar", jar);
- ConcurrencyUtils.sleep(10000);
+ synchronized (running) {
+ running.set(false);
+ }
+ monitor.stopMonitoring();
+ bluetoothConfig.stop();
+ pool.shutdown();
try {
- Runtime.getRuntime().exec(new String[]{"systemctl", "restart", "currentmonitor"});
+ Runtime.getRuntime().exec(new String[]{"systemctl","restart","currentmonitor"});
} catch (IOException _e) {
LOG.error("Exception occurred while trying to restart", _e);
}
@@ -419,65 +495,29 @@ public class MonitorApp {
}
}
- private static final class CommandChecker implements Runnable {
- @Override
- public void run() {
- if (NullUtils.isNotEmpty(host)) {
- HttpGet get = new HttpGet(host + "command");
- get.addHeader("auth_code", authCode);
- DaoEntity meta = DaoSerializer.fromZipBson(pool.executeToByteArray(get));
- for (String command : DaoSerializer.getList(meta, "commands", String.class)) {
- if (NullUtils.isEqual(command, "log")) {
- uploadLog();
- } else if (NullUtils.makeNotNull(command).startsWith("timeout")) {
- LOG.info("Updating timeouts...");
- String[] timeouts = NullUtils.cleanSplit(command, "-");
- if (CollectionUtils.size(timeouts) != 3)
- continue;
- config.setConnectTimeout(DaoSerializer.toInteger(timeouts[1]));
- config.setSocketTimeout(DaoSerializer.toInteger(timeouts[2]));
- HttpPool old = pool;
- pool = new HttpPool(10, 10, config.getSocketTimeout(), config.getConnectTimeout(), config.getSocketTimeout());
- old.shutdown();
- ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config));
- } else if (NullUtils.isEqual(command, "extend_filesystem")) {
- LOG.info("Extending filesystem and rebooting");
- try {
- Runtime.getRuntime().exec(new String[]{"sudo", "raspi-config", "--expand-rootfs"});
- ConcurrencyUtils.sleep(5000);
- Runtime.getRuntime().exec(new String[]{"reboot", "now"});
- } catch (IOException _e) {
- LOG.error("Exception occurred while trying to extend filesystem", _e);
- }
- } else if (NullUtils.isEqual(command, "restart")) {
- LOG.info("Restarting...");
- try {
- Runtime.getRuntime().exec(new String[]{"systemctl", "restart", "currentmonitor"});
- } catch (IOException _e) {
- LOG.error("Exception occurred while trying to restart", _e);
- }
- }
- }
- }
- }
- }
-
- private static String getVersionNumber() {
- InputStream is = null;
+ public static String getVersionNumber() {
try {
- is = MonitorApp.class.getResourceAsStream("/META-INF/MANIFEST.MF");
- Manifest manifest = new Manifest(is);
- Attributes attr = manifest.getMainAttributes();
- String version = attr.getValue("Specification-Version");
- LOG.info("Current Version: {}", version);
- return version;
+ Enumeration resources = MonitorApp.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
+ while (resources.hasMoreElements()) {
+ InputStream is = null;
+ try {
+ is = resources.nextElement().openStream();
+ Manifest manifest = new Manifest(is);
+ Attributes attr = manifest.getMainAttributes();
+ if (NullUtils.isEqual(attr.getValue("Specification-Title"), "Lantern Power Monitor")) {
+ String version = attr.getValue("Specification-Version");
+ LOG.info("Current Version: {}", version);
+ return version;
+ }
+ }
+ finally {
+ IOUtils.closeQuietly(is);
+ }
+ }
}
catch (Exception _e) {
LOG.error("Failed to get current version number", _e);
- return "";
- }
- finally {
- IOUtils.closeQuietly(is);
}
+ return "";
}
}
diff --git a/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/Backup.java b/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/Backup.java
index 69bdb65..a382bdb 100644
--- a/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/Backup.java
+++ b/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/Backup.java
@@ -2,6 +2,8 @@ package com.lanternsoftware.dataaccess.currentmonitor;
import com.lanternsoftware.datamodel.currentmonitor.Account;
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
+import com.lanternsoftware.datamodel.currentmonitor.ChargeSummary;
+import com.lanternsoftware.datamodel.currentmonitor.ChargeTotal;
import com.lanternsoftware.datamodel.currentmonitor.EnergySummary;
import com.lanternsoftware.datamodel.currentmonitor.EnergyTotal;
import com.lanternsoftware.datamodel.currentmonitor.Sequence;
@@ -10,14 +12,15 @@ import com.lanternsoftware.datamodel.rules.FcmDevice;
import com.lanternsoftware.datamodel.rules.Rule;
import com.lanternsoftware.util.DebugTimer;
import com.lanternsoftware.util.LanternFiles;
+import com.lanternsoftware.util.dao.DaoQuery;
import com.lanternsoftware.util.dao.mongo.MongoConfig;
import java.util.List;
public class Backup {
public static void main(String[] args) {
- CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
- CurrentMonitorDao backupDao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.BACKUP_PATH + "mongo.cfg"));
+ CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.BACKUP_SOURCE + "mongo.cfg"));
+ CurrentMonitorDao backupDao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.BACKUP_DEST + "mongo.cfg"));
DebugTimer t1 = new DebugTimer("Query Accounts");
List accounts = dao.getProxy().queryAll(Account.class);
@@ -34,17 +37,39 @@ public class Backup {
t4.stop();
DebugTimer t5 = new DebugTimer("Query Energy");
- List energy = dao.getProxy().queryAll(EnergySummary.class);
+ for (Account a : accounts) {
+ List energy = dao.getProxy().query(EnergySummary.class, new DaoQuery("account_id", a.getId()));
+ DebugTimer t = new DebugTimer("Save Energy");
+ backupDao.getProxy().save(energy);
+ t.stop();
+ }
t5.stop();
- DebugTimer t6 = new DebugTimer("Save Energy");
- backupDao.getProxy().save(energy);
+
+ DebugTimer t6 = new DebugTimer("Query Energy Totals");
+ for (Account a : accounts) {
+ List total = dao.getProxy().query(EnergyTotal.class, new DaoQuery("account_id", a.getId()));
+ DebugTimer t = new DebugTimer("Save Summary");
+ backupDao.getProxy().save(total);
+ t.stop();
+ }
t6.stop();
- DebugTimer t7 = new DebugTimer("Query Summaries");
- List summary = dao.getProxy().queryAll(EnergyTotal.class);
+ DebugTimer t7 = new DebugTimer("Query Charges");
+ for (Account a : accounts) {
+ List charges = dao.getProxy().query(ChargeSummary.class, new DaoQuery("account_id", a.getId()));
+ DebugTimer t = new DebugTimer("Save Charges");
+ backupDao.getProxy().save(charges);
+ t.stop();
+ }
t7.stop();
- DebugTimer t8 = new DebugTimer("Save Summaries");
- backupDao.getProxy().save(summary);
+
+ DebugTimer t8 = new DebugTimer("Query Charge Totals");
+ for (Account a : accounts) {
+ List charges = dao.getProxy().query(ChargeTotal.class, new DaoQuery("account_id", a.getId()));
+ DebugTimer t = new DebugTimer("Save Charge Totals");
+ backupDao.getProxy().save(charges);
+ t.stop();
+ }
t8.stop();
DebugTimer t9 = new DebugTimer("Query Events");
diff --git a/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/BackupMinutes.java b/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/BackupMinutes.java
index 0a3478a..2565504 100644
--- a/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/BackupMinutes.java
+++ b/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/BackupMinutes.java
@@ -16,8 +16,8 @@ import java.util.TimeZone;
public class BackupMinutes {
public static void main(String[] args) {
- CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
- CurrentMonitorDao backupDao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.BACKUP_PATH + "mongo.cfg"));
+ CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.BACKUP_SOURCE + "mongo.cfg"));
+ CurrentMonitorDao backupDao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.BACKUP_DEST + "mongo.cfg"));
Date now = new Date();
for (Account a : dao.getProxy().queryAll(Account.class)) {
if (a.getId() == 0)
@@ -30,12 +30,11 @@ public class BackupMinutes {
HubPowerMinute minute = dao.getProxy().queryOne(HubPowerMinute.class, new DaoQuery("account_id", a.getId()), DaoSort.sort("minute"));
if (minute == null)
continue;
- Date minStart = DateUtils.addDays(DateUtils.getMidnightBeforeNow(tz), -60, tz);
- Date start = DateUtils.getMidnightBefore(minute.getMinuteAsDate(), tz);
- if (minStart.after(start))
- start = minStart;
+ HubPowerMinute lastBackup = backupDao.getProxy().queryOne(HubPowerMinute.class, new DaoQuery("account_id", a.getId()), DaoSort.sortDesc("minute"));
+ Date start = lastBackup == null ? DateUtils.getMidnightBefore(minute.getMinuteAsDate(), tz) : lastBackup.getMinuteAsDate();
+// Date start = DateUtils.date(10,16,2021,tz);
Date end = DateUtils.addDays(start, 1, tz);
- while (end.before(now)) {
+ while (start.before(now)) {
DebugTimer t2 = new DebugTimer("Account Id: " + a.getId() + " Query Day " + DateUtils.format("MM/dd/yyyy", tz, start));
List minutes = dao.getProxy().query(HubPowerMinute.class, new DaoQuery("account_id", a.getId()).andBetweenInclusiveExclusive("minute", (int) (start.getTime() / 60000), (int) (end.getTime() / 60000)));
t2.stop();
diff --git a/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/CurrentMonitorDao.java b/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/CurrentMonitorDao.java
index 6b2203e..6c8171d 100644
--- a/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/CurrentMonitorDao.java
+++ b/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/CurrentMonitorDao.java
@@ -5,6 +5,7 @@ import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
import com.lanternsoftware.datamodel.currentmonitor.BreakerPower;
import com.lanternsoftware.datamodel.currentmonitor.EnergySummary;
import com.lanternsoftware.datamodel.currentmonitor.EnergyViewMode;
+import com.lanternsoftware.datamodel.currentmonitor.HubCommand;
import com.lanternsoftware.datamodel.currentmonitor.HubPowerMinute;
import com.lanternsoftware.util.dao.auth.AuthCode;
import com.lanternsoftware.util.dao.mongo.MongoProxy;
@@ -48,5 +49,9 @@ public interface CurrentMonitorDao {
TimeZone getTimeZoneForAccount(int _accountId);
String getTimeZoneForAccount(String _authCode);
+ void putHubCommand(HubCommand _command);
+ List getAllHubCommands();
+ void deleteHubCommand(String _id);
+
MongoProxy getProxy();
}
diff --git a/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/MongoCurrentMonitorDao.java b/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/MongoCurrentMonitorDao.java
index fe4637a..ad17f4f 100644
--- a/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/MongoCurrentMonitorDao.java
+++ b/currentmonitor/lantern-dataaccess-currentmonitor/src/main/java/com/lanternsoftware/dataaccess/currentmonitor/MongoCurrentMonitorDao.java
@@ -6,12 +6,14 @@ import com.lanternsoftware.datamodel.currentmonitor.BillingRate;
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
+import com.lanternsoftware.datamodel.currentmonitor.BreakerHub;
import com.lanternsoftware.datamodel.currentmonitor.BreakerPower;
import com.lanternsoftware.datamodel.currentmonitor.ChargeSummary;
import com.lanternsoftware.datamodel.currentmonitor.ChargeTotal;
import com.lanternsoftware.datamodel.currentmonitor.EnergySummary;
import com.lanternsoftware.datamodel.currentmonitor.EnergyTotal;
import com.lanternsoftware.datamodel.currentmonitor.EnergyViewMode;
+import com.lanternsoftware.datamodel.currentmonitor.HubCommand;
import com.lanternsoftware.datamodel.currentmonitor.HubPowerMinute;
import com.lanternsoftware.datamodel.currentmonitor.Sequence;
import com.lanternsoftware.util.CollectionUtils;
@@ -404,6 +406,7 @@ public class MongoCurrentMonitorDao implements CurrentMonitorDao {
if (config == null) {
config = new BreakerConfig();
config.setAccountId(_authCode.getAccountId());
+ config.setVersion(config.getVersion());
return config;
}
}
@@ -416,6 +419,7 @@ public class MongoCurrentMonitorDao implements CurrentMonitorDao {
config.setMeters(CollectionUtils.aggregate(configs, BreakerConfig::getMeters));
config.setBillingPlans(CollectionUtils.aggregate(configs, BreakerConfig::getBillingPlans));
config.setBillingRates(CollectionUtils.aggregate(configs, BreakerConfig::getBillingRates));
+ config.setVersion(CollectionUtils.getLargest(CollectionUtils.transform(configs, BreakerConfig::getVersion)));
return config;
}
@@ -424,6 +428,16 @@ public class MongoCurrentMonitorDao implements CurrentMonitorDao {
DaoQuery configQuery = new DaoQuery("_id", String.valueOf(_config.getAccountId()));
BreakerConfig oldConfig = proxy.queryOne(BreakerConfig.class, configQuery);
if (oldConfig != null) {
+ logger.info("old version: {}, new version: {}", oldConfig.getVersion(), _config.getVersion());
+ if (oldConfig.getVersion() > _config.getVersion()) {
+ for (BreakerHub hub : CollectionUtils.makeNotNull(_config.getBreakerHubs())) {
+ BreakerHub oldHub = oldConfig.getHub(hub.getHub());
+ if (oldHub != null) {
+ logger.info("Prevent overwrite of voltage calibration");
+ hub.setVoltageCalibrationFactor(oldHub.getRawVoltageCalibrationFactor());
+ }
+ }
+ }
_config.setVersion(oldConfig.getVersion() + 1);
if (NullUtils.isNotIdentical(_config, oldConfig)) {
DaoEntity oldEntity = DaoSerializer.toDaoEntity(oldConfig);
@@ -441,6 +455,9 @@ public class MongoCurrentMonitorDao implements CurrentMonitorDao {
});
}
}
+ for (BreakerHub hub : CollectionUtils.makeNotNull(_config.getBreakerHubs())) {
+ logger.info("voltage calibration hub {}: {}", hub.getHub(), hub.getVoltageCalibrationFactor());
+ }
proxy.save(_config);
}
@@ -459,7 +476,7 @@ public class MongoCurrentMonitorDao implements CurrentMonitorDao {
AuthCode code = decryptAuthCode(_authCode);
if (code == null)
return null;
- return proxy.queryOne(Account.class, new DaoQuery("_id", code.getAccountId()));
+ return proxy.queryOne(Account.class, new DaoQuery("_id", String.valueOf(code.getAccountId())));
}
@Override
@@ -572,6 +589,23 @@ public class MongoCurrentMonitorDao implements CurrentMonitorDao {
return true;
}
+ @Override
+ public void putHubCommand(HubCommand _command) {
+ BreakerConfig config = getConfig(_command.getAccountId());
+ if (config != null)
+ proxy.save(_command.forAllHubs(config));
+ }
+
+ @Override
+ public List getAllHubCommands() {
+ return proxy.queryAll(HubCommand.class);
+ }
+
+ @Override
+ public void deleteHubCommand(String _id) {
+ proxy.delete(HubCommand.class, new DaoQuery("_id", _id));
+ }
+
@Override
public MongoProxy getProxy() {
return proxy;
diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/BreakerConfig.java b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/BreakerConfig.java
index b9f5826..9e97ec4 100644
--- a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/BreakerConfig.java
+++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/BreakerConfig.java
@@ -209,7 +209,7 @@ public class BreakerConfig implements IIdentical {
@Override
public boolean isIdentical(BreakerConfig _o) {
if (this == _o) return true;
- return accountId == _o.accountId && CollectionUtils.isIdentical(meters, _o.meters) && CollectionUtils.isIdentical(panels, _o.panels) && CollectionUtils.isIdentical(breakerHubs, _o.breakerHubs) && CollectionUtils.isIdentical(breakerGroups, _o.breakerGroups) && CollectionUtils.isEqual(billingPlans, _o.billingPlans);
+ return accountId == _o.accountId && CollectionUtils.isIdentical(meters, _o.meters) && CollectionUtils.isIdentical(panels, _o.panels) && CollectionUtils.isIdentical(breakerHubs, _o.breakerHubs) && CollectionUtils.isIdentical(breakerGroups, _o.breakerGroups) && CollectionUtils.isIdentical(billingPlans, _o.billingPlans);
}
@Override
diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/BreakerHub.java b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/BreakerHub.java
index bb47fcd..d54251b 100644
--- a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/BreakerHub.java
+++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/BreakerHub.java
@@ -6,7 +6,7 @@ import com.lanternsoftware.util.dao.annotations.DBSerializable;
import java.util.Objects;
-@DBSerializable
+@DBSerializable(autogen = false)
public class BreakerHub implements IIdentical {
private int hub;
private double voltageCalibrationFactor;
@@ -22,16 +22,24 @@ public class BreakerHub implements IIdentical {
hub = _hub;
}
+ public double getRawVoltageCalibrationFactor() {
+ return voltageCalibrationFactor;
+ }
+
public double getVoltageCalibrationFactor() {
- return voltageCalibrationFactor == 0.0?1.0:voltageCalibrationFactor;
+ return voltageCalibrationFactor == 0.0?0.3445:voltageCalibrationFactor;
}
public void setVoltageCalibrationFactor(double _voltageCalibrationFactor) {
voltageCalibrationFactor = _voltageCalibrationFactor;
}
+ public double getRawPortCalibrationFactor() {
+ return portCalibrationFactor;
+ }
+
public double getPortCalibrationFactor() {
- return portCalibrationFactor == 0.0?1.0:portCalibrationFactor;
+ return portCalibrationFactor == 0.0?1.25:portCalibrationFactor;
}
public void setPortCalibrationFactor(double _portCalibrationFactor) {
diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/HubCommand.java b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/HubCommand.java
new file mode 100644
index 0000000..05e4a23
--- /dev/null
+++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/HubCommand.java
@@ -0,0 +1,104 @@
+package com.lanternsoftware.datamodel.currentmonitor;
+
+import com.lanternsoftware.util.CollectionUtils;
+import com.lanternsoftware.util.dao.annotations.DBSerializable;
+import com.lanternsoftware.util.dao.annotations.PrimaryKey;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+@DBSerializable
+public class HubCommand {
+ @PrimaryKey private String id;
+ private int accountId;
+ private int hub;
+ private Date created;
+ private HubConfigCharacteristic characteristic;
+ private byte[] data;
+
+ public HubCommand() {
+ }
+
+ public HubCommand(int _accountId, HubConfigCharacteristic _characteristic, byte[] _data) {
+ accountId = _accountId;
+ created = new Date();
+ characteristic = _characteristic;
+ data = _data;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String _id) {
+ id = _id;
+ }
+
+ public int getAccountId() {
+ return accountId;
+ }
+
+ public void setAccountId(int _accountId) {
+ accountId = _accountId;
+ }
+
+ public int getHub() {
+ return hub;
+ }
+
+ public void setHub(int _hub) {
+ hub = _hub;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+
+ public void setCreated(Date _created) {
+ created = _created;
+ }
+
+ public HubConfigCharacteristic getCharacteristic() {
+ return characteristic;
+ }
+
+ public void setCharacteristic(HubConfigCharacteristic _characteristic) {
+ characteristic = _characteristic;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ public void setData(byte[] _data) {
+ data = _data;
+ }
+
+ public List forAllHubs(BreakerConfig _config) {
+ return CollectionUtils.transform(_config.getBreakerHubs(), _h->forHub(_h.getHub()));
+ }
+
+ public HubCommand forHub(int _hub) {
+ HubCommand c = new HubCommand();
+ c.setAccountId(accountId);
+ c.setHub(_hub);
+ c.setCreated(created);
+ c.setCharacteristic(characteristic);
+ c.setData(data);
+ return c;
+ }
+
+ @Override
+ public boolean equals(Object _o) {
+ if (this == _o) return true;
+ if (_o == null || getClass() != _o.getClass()) return false;
+ HubCommand that = (HubCommand) _o;
+ return Objects.equals(id, that.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id);
+ }
+}
diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/HubCommands.java b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/HubCommands.java
new file mode 100644
index 0000000..0c8fce8
--- /dev/null
+++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/HubCommands.java
@@ -0,0 +1,25 @@
+package com.lanternsoftware.datamodel.currentmonitor;
+
+import com.lanternsoftware.util.dao.annotations.DBSerializable;
+
+import java.util.List;
+
+@DBSerializable
+public class HubCommands {
+ private List commands;
+
+ public HubCommands() {
+ }
+
+ public HubCommands(List _commands) {
+ commands = _commands;
+ }
+
+ public List getCommands() {
+ return commands;
+ }
+
+ public void setCommands(List _commands) {
+ commands = _commands;
+ }
+}
diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/HubConfigCharacteristic.java b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/HubConfigCharacteristic.java
index f3e4c73..221b5c4 100644
--- a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/HubConfigCharacteristic.java
+++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/HubConfigCharacteristic.java
@@ -18,7 +18,10 @@ public enum HubConfigCharacteristic {
Host(10, CharacteristicFlag.WRITE),
Log(11, CharacteristicFlag.READ),
NetworkDetails(12, CharacteristicFlag.READ),
- Shutdown(13, CharacteristicFlag.WRITE);
+ Shutdown(13, CharacteristicFlag.WRITE),
+ Version(14, CharacteristicFlag.READ),
+ Update(15, CharacteristicFlag.WRITE),
+ ReloadConfig(15, CharacteristicFlag.WRITE);
public final int idx;
public final UUID uuid;
diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/BillingRateSerializer.java b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/BillingRateSerializer.java
index 66d98f8..9062774 100644
--- a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/BillingRateSerializer.java
+++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/BillingRateSerializer.java
@@ -7,7 +7,6 @@ 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;
@@ -31,7 +30,6 @@ public class BillingRateSerializer extends AbstractDaoSerializer
d.put("meter", _o.getMeter());
d.put("flow", DaoSerializer.toEnumName(_o.getFlow()));
d.put("rate", _o.getRate());
- d.put("unit", DaoSerializer.toEnumName(_o.getCurrency())); //TODO: Remove post migration
d.put("currency", DaoSerializer.toEnumName(_o.getCurrency()));
d.put("time_of_day_start", _o.getTimeOfDayStart());
d.put("time_of_day_end", _o.getTimeOfDayEnd());
@@ -51,8 +49,6 @@ public class BillingRateSerializer extends AbstractDaoSerializer
o.setFlow(DaoSerializer.getEnum(_d, "flow", GridFlow.class));
o.setRate(DaoSerializer.getDouble(_d, "rate"));
o.setCurrency(DaoSerializer.getEnum(_d, "currency", BillingCurrency.class));
- if (o.getCurrency() == null)
- o.setCurrency(DaoSerializer.getEnum(_d, "unit", BillingCurrency.class));
o.setTimeOfDayStart(DaoSerializer.getInteger(_d, "time_of_day_start"));
o.setTimeOfDayEnd(DaoSerializer.getInteger(_d, "time_of_day_end"));
o.setMonthKWhStart(DaoSerializer.getDouble(_d, "month_kwh_start"));
diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/BreakerHubSerializer.java b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/BreakerHubSerializer.java
index 180926d..776059b 100644
--- a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/BreakerHubSerializer.java
+++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/BreakerHubSerializer.java
@@ -26,8 +26,8 @@ public class BreakerHubSerializer extends AbstractDaoSerializer
{
DaoEntity d = new DaoEntity();
d.put("hub", _o.getHub());
- d.put("voltage_calibration_factor", _o.getVoltageCalibrationFactor());
- d.put("port_calibration_factor", _o.getPortCalibrationFactor());
+ d.put("voltage_calibration_factor", _o.getRawVoltageCalibrationFactor());
+ d.put("port_calibration_factor", _o.getRawPortCalibrationFactor());
d.put("frequency", _o.getFrequency());
d.put("bluetooth_mac", _o.getBluetoothMac());
return d;
diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/HubCommandSerializer.java b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/HubCommandSerializer.java
new file mode 100644
index 0000000..a4c0b0b
--- /dev/null
+++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/HubCommandSerializer.java
@@ -0,0 +1,51 @@
+package com.lanternsoftware.datamodel.currentmonitor.dao;
+
+import com.lanternsoftware.datamodel.currentmonitor.HubCommand;
+import com.lanternsoftware.datamodel.currentmonitor.HubConfigCharacteristic;
+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 HubCommandSerializer extends AbstractDaoSerializer
+{
+ @Override
+ public Class getSupportedClass()
+ {
+ return HubCommand.class;
+ }
+
+ @Override
+ public List getSupportedProxies() {
+ return Collections.singletonList(DaoProxyType.MONGO);
+ }
+
+ @Override
+ public DaoEntity toDaoEntity(HubCommand _o)
+ {
+ DaoEntity d = new DaoEntity();
+ if (_o.getId() != null)
+ d.put("_id", _o.getId());
+ d.put("account_id", _o.getAccountId());
+ d.put("hub", _o.getHub());
+ d.put("created", DaoSerializer.toLong(_o.getCreated()));
+ d.put("characteristic", DaoSerializer.toEnumName(_o.getCharacteristic()));
+ d.put("data", _o.getData());
+ return d;
+ }
+
+ @Override
+ public HubCommand fromDaoEntity(DaoEntity _d)
+ {
+ HubCommand o = new HubCommand();
+ o.setId(DaoSerializer.getString(_d, "_id"));
+ o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
+ o.setHub(DaoSerializer.getInteger(_d, "hub"));
+ o.setCreated(DaoSerializer.getDate(_d, "created"));
+ o.setCharacteristic(DaoSerializer.getEnum(_d, "characteristic", HubConfigCharacteristic.class));
+ o.setData(DaoSerializer.getByteArray(_d, "data"));
+ return o;
+ }
+}
\ No newline at end of file
diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/HubCommandsSerializer.java b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/HubCommandsSerializer.java
new file mode 100644
index 0000000..fac22df
--- /dev/null
+++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/HubCommandsSerializer.java
@@ -0,0 +1,40 @@
+package com.lanternsoftware.datamodel.currentmonitor.dao;
+
+import com.lanternsoftware.datamodel.currentmonitor.HubCommand;
+import com.lanternsoftware.datamodel.currentmonitor.HubCommands;
+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 HubCommandsSerializer extends AbstractDaoSerializer
+{
+ @Override
+ public Class getSupportedClass()
+ {
+ return HubCommands.class;
+ }
+
+ @Override
+ public List getSupportedProxies() {
+ return Collections.singletonList(DaoProxyType.MONGO);
+ }
+
+ @Override
+ public DaoEntity toDaoEntity(HubCommands _o)
+ {
+ DaoEntity d = new DaoEntity();
+ d.put("commands", DaoSerializer.toDaoEntities(_o.getCommands(), DaoProxyType.MONGO));
+ return d;
+ }
+
+ @Override
+ public HubCommands fromDaoEntity(DaoEntity _d)
+ {
+ HubCommands o = new HubCommands();
+ o.setCommands(DaoSerializer.getList(_d, "commands", HubCommand.class));
+ return o;
+ }
+}
\ No newline at end of file
diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/resources/META-INF/services/com.lanternsoftware.util.dao.IDaoSerializer b/currentmonitor/lantern-datamodel-currentmonitor/src/main/resources/META-INF/services/com.lanternsoftware.util.dao.IDaoSerializer
index e2de4e0..3a3f460 100644
--- a/currentmonitor/lantern-datamodel-currentmonitor/src/main/resources/META-INF/services/com.lanternsoftware.util.dao.IDaoSerializer
+++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/resources/META-INF/services/com.lanternsoftware.util.dao.IDaoSerializer
@@ -14,6 +14,8 @@ com.lanternsoftware.datamodel.currentmonitor.dao.ChargeTotalSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.EnergyBlockSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.EnergySummarySerializer
com.lanternsoftware.datamodel.currentmonitor.dao.EnergyTotalSerializer
+com.lanternsoftware.datamodel.currentmonitor.dao.HubCommandSerializer
+com.lanternsoftware.datamodel.currentmonitor.dao.HubCommandsSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.HubPowerMinuteSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.MeterSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.NetworkStatusSerializer
diff --git a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/context/Globals.java b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/context/Globals.java
index 890724d..e4f387c 100644
--- a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/context/Globals.java
+++ b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/context/Globals.java
@@ -2,20 +2,31 @@ package com.lanternsoftware.currentmonitor.context;
import com.lanternsoftware.dataaccess.currentmonitor.CurrentMonitorDao;
import com.lanternsoftware.dataaccess.currentmonitor.MongoCurrentMonitorDao;
+import com.lanternsoftware.datamodel.currentmonitor.HubCommand;
+import com.lanternsoftware.datamodel.currentmonitor.HubCommands;
import com.lanternsoftware.rules.RulesEngine;
+import com.lanternsoftware.util.DateUtils;
import com.lanternsoftware.util.LanternFiles;
import com.lanternsoftware.util.dao.mongo.MongoConfig;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimerTask;
public class Globals implements ServletContextListener {
public static CurrentMonitorDao dao;
+ private static final Map>> commands = new HashMap<>();
@Override
public void contextInitialized(ServletContextEvent sce) {
dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
RulesEngine.instance().start();
+ RulesEngine.instance().schedule(new CommandTask(), 0);
}
@Override
@@ -23,4 +34,38 @@ public class Globals implements ServletContextListener {
dao.shutdown();
RulesEngine.shutdown();
}
+
+ public static HubCommands getCommandsForHub(int _accountId, int _hub) {
+ List c = null;
+ synchronized (commands) {
+ Map> hubCommands = commands.get(_accountId);
+ if (hubCommands != null)
+ c = hubCommands.remove(_hub);
+ }
+ if (c != null) {
+ for (HubCommand command : c) {
+ dao.deleteHubCommand(command.getId());
+ }
+ return new HubCommands(c);
+ }
+ return null;
+ }
+
+ private static final class CommandTask extends TimerTask {
+ @Override
+ public void run() {
+ List c = Globals.dao.getAllHubCommands();
+ Date stale = DateUtils.addMinutes(new Date(), -5);
+ synchronized (commands) {
+ commands.clear();
+ for (HubCommand command : c) {
+ if (DateUtils.isBefore(command.getCreated(), stale))
+ dao.deleteHubCommand(command.getId());
+ else
+ commands.computeIfAbsent(command.getAccountId(), _t -> new HashMap<>()).computeIfAbsent(command.getHub(), _h->new ArrayList<>()).add(command);
+ }
+ }
+ RulesEngine.instance().schedule(new CommandTask(), 1000);
+ }
+ }
}
diff --git a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/AuthServlet.java b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/AuthServlet.java
index d770bbc..ccab743 100644
--- a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/AuthServlet.java
+++ b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/AuthServlet.java
@@ -44,11 +44,8 @@ public class AuthServlet extends LanternServlet {
GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(transport, new GsonFactory(), "https://oauth2.googleapis.com/token", googleClientId, googleClientSecret, auth.getPassword(), "").execute();
if (tokenResponse != null) {
GoogleIdToken idToken = tokenResponse.parseIdToken();
- if (idToken != null) {
- logger.info("Successfully received google id token");
+ if (idToken != null)
authCode = Globals.dao.getAuthCodeForEmail(idToken.getPayload().getEmail(), DateUtils.fromTimeZoneId(_req.getHeader("timezone")));
- logger.info("Auth code for google user is valid: " + (authCode != null));
- }
}
} catch (Exception _e) {
logger.error("Failed to validate google auth code", _e);
diff --git a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/CommandServlet.java b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/CommandServlet.java
index 0672fc8..a58aad0 100644
--- a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/CommandServlet.java
+++ b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/CommandServlet.java
@@ -1,49 +1,19 @@
package com.lanternsoftware.currentmonitor.servlet;
import com.lanternsoftware.util.dao.auth.AuthCode;
-import com.lanternsoftware.util.CollectionUtils;
-import com.lanternsoftware.util.LanternFiles;
-import com.lanternsoftware.util.NullUtils;
-import com.lanternsoftware.util.ResourceLoader;
-import com.lanternsoftware.util.dao.DaoEntity;
-import com.lanternsoftware.util.dao.DaoSerializer;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
@WebServlet("/command")
public class CommandServlet extends SecureServlet {
@Override
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
- File folder = new File(LanternFiles.OPS_PATH + _authCode.getAccountId());
- List commands = new ArrayList<>();
- if (folder.exists() && folder.isDirectory()) {
- for (File command : CollectionUtils.asArrayList(folder.listFiles())) {
- if (command.isDirectory())
- continue;
- String c = command.getName();
- String extension = NullUtils.after(c, ".");
- if (NullUtils.isNotEmpty(extension))
- c = c.replace("." + extension, "");
- commands.add(c);
- }
- }
- zipBsonResponse(_rep, new DaoEntity("commands", commands));
}
@Override
protected void post(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
- DaoEntity payload = getRequestZipBson(_req);
- if (payload == null)
- return;
- String command = DaoSerializer.getString(payload, "command");
- String path = LanternFiles.OPS_PATH + _authCode.getAccountId() + File.separator + "payload" + File.separator;
- new File(path).mkdirs();
- ResourceLoader.writeFile(path+ command + ".txt", DaoSerializer.getString(payload, "payload"));
}
}
diff --git a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/ConfigServlet.java b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/ConfigServlet.java
index e22df18..d746628 100644
--- a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/ConfigServlet.java
+++ b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/ConfigServlet.java
@@ -2,6 +2,8 @@ package com.lanternsoftware.currentmonitor.servlet;
import com.lanternsoftware.currentmonitor.context.Globals;
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
+import com.lanternsoftware.datamodel.currentmonitor.HubCommand;
+import com.lanternsoftware.datamodel.currentmonitor.HubConfigCharacteristic;
import com.lanternsoftware.util.dao.auth.AuthCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,6 +36,10 @@ public class ConfigServlet extends SecureServlet {
return;
}
logger.info("Received config for account {}", config.getAccountId());
+ BreakerConfig oldConfig = Globals.dao.getConfig(config.getAccountId());
+ if ((oldConfig == null) || !oldConfig.isIdentical(config))
+ Globals.dao.putHubCommand(new HubCommand(config.getAccountId(), HubConfigCharacteristic.ReloadConfig, null));
Globals.dao.putConfig(config);
+ zipBsonResponse(_rep, Globals.dao.getMergedConfig(_authCode));
}
}
diff --git a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/PowerServlet.java b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/PowerServlet.java
index 3abca86..f159626 100644
--- a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/PowerServlet.java
+++ b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/PowerServlet.java
@@ -1,12 +1,17 @@
package com.lanternsoftware.currentmonitor.servlet;
import com.lanternsoftware.currentmonitor.context.Globals;
+import com.lanternsoftware.dataaccess.currentmonitor.MongoCurrentMonitorDao;
+import com.lanternsoftware.datamodel.currentmonitor.HubCommands;
+import com.lanternsoftware.util.dao.DaoEntity;
import com.lanternsoftware.util.dao.auth.AuthCode;
import com.lanternsoftware.datamodel.currentmonitor.BreakerPower;
import com.lanternsoftware.datamodel.currentmonitor.HubPowerMinute;
import com.lanternsoftware.util.CollectionUtils;
import com.lanternsoftware.util.NullUtils;
import com.lanternsoftware.util.dao.DaoSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
@@ -15,6 +20,8 @@ import java.util.List;
@WebServlet("/power/*")
public class PowerServlet extends SecureServlet {
+ private static final Logger logger = LoggerFactory.getLogger(MongoCurrentMonitorDao.class);
+
@Override
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
String[] path = path(_req);
@@ -32,19 +39,29 @@ public class PowerServlet extends SecureServlet {
String[] path = path(_req);
if ((path.length > 0) && NullUtils.isEqual(CollectionUtils.get(path, 0), "hub")) {
HubPowerMinute m = getRequestPayload(_req, HubPowerMinute.class);
+ if (m == null)
+ return;
+ logger.info("Hub Power from ip {}, account {}, hub {}", _req.getRemoteAddr(), m.getAccountId(), m.getHub());
m.setAccountId(_authCode.getAccountId());
Globals.dao.putHubPowerMinute(m);
return;
}
if ((path.length > 0) && NullUtils.isEqual(CollectionUtils.get(path, 0), "batch")) {
- List powers = DaoSerializer.getList(getRequestZipBson(_req), "readings", BreakerPower.class);
+ DaoEntity payload = getRequestZipBson(_req);
+ List powers = DaoSerializer.getList(payload, "readings", BreakerPower.class);
if (!powers.isEmpty()) {
CollectionUtils.edit(powers, _p->_p.setAccountId(_authCode.getAccountId()));
Globals.dao.getProxy().save(powers);
+ int hub = DaoSerializer.getInteger(payload, "hub");
+ HubCommands commands = Globals.getCommandsForHub(_authCode.getAccountId(), hub);
+ if (commands != null)
+ zipBsonResponse(_rep, commands);
}
return;
}
BreakerPower power = getRequestPayload(_req, BreakerPower.class);
+ if (power == null)
+ return;
power.setAccountId(_authCode.getAccountId());
Globals.dao.putBreakerPower(power);
}
diff --git a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/RebuildSummariesServlet.java b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/RebuildSummariesServlet.java
index 05cf8f2..2719412 100644
--- a/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/RebuildSummariesServlet.java
+++ b/currentmonitor/lantern-service-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/servlet/RebuildSummariesServlet.java
@@ -2,6 +2,8 @@ package com.lanternsoftware.currentmonitor.servlet;
import com.lanternsoftware.currentmonitor.context.Globals;
import com.lanternsoftware.datamodel.currentmonitor.Account;
+import com.lanternsoftware.util.CollectionUtils;
+import com.lanternsoftware.util.NullUtils;
import com.lanternsoftware.util.dao.DaoSerializer;
import com.lanternsoftware.util.dao.auth.AuthCode;
@@ -9,15 +11,21 @@ import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-@WebServlet("/rebuildSummaries")
+@WebServlet("/rebuildSummaries/*")
public class RebuildSummariesServlet extends SecureServlet {
@Override
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
if (_authCode.getAccountId() == 100) {
- for (String sId : Globals.dao.getProxy().queryForField(Account.class, null, "_id")) {
- int id = DaoSerializer.toInteger(sId);
- if (id != 0)
- Globals.dao.rebuildSummariesAsync(id);
+ String[] path = path(_req);
+ if (path.length > 0) {
+ Globals.dao.rebuildSummariesAsync(DaoSerializer.toInteger(CollectionUtils.get(path, 0)));
+ }
+ else {
+ for (String sId : Globals.dao.getProxy().queryForField(Account.class, null, "_id")) {
+ int id = DaoSerializer.toInteger(sId);
+ if (id != 0)
+ Globals.dao.rebuildSummariesAsync(id);
+ }
}
}
else
diff --git a/currentmonitor/lantern-service-currentmonitor/src/main/resources/logback.xml b/currentmonitor/lantern-service-currentmonitor/src/main/resources/logback.xml
index ece41c5..6f04b4c 100644
--- a/currentmonitor/lantern-service-currentmonitor/src/main/resources/logback.xml
+++ b/currentmonitor/lantern-service-currentmonitor/src/main/resources/logback.xml
@@ -2,16 +2,21 @@
-
+
+ /opt/tomcat/logs/log.txt
+
+ /opt/tomcat/log/log.%d{yyyy-MM-dd}.%i.txt
+ 20MB
+ 20
+
${log.pattern}
-
-
+
\ No newline at end of file
diff --git a/currentmonitor/lantern-service-currentmonitor/src/test/resources/logback.xml b/currentmonitor/lantern-service-currentmonitor/src/test/resources/logback.xml
index ece41c5..6f04b4c 100644
--- a/currentmonitor/lantern-service-currentmonitor/src/test/resources/logback.xml
+++ b/currentmonitor/lantern-service-currentmonitor/src/test/resources/logback.xml
@@ -2,16 +2,21 @@
-
+
+ /opt/tomcat/logs/log.txt
+
+ /opt/tomcat/log/log.%d{yyyy-MM-dd}.%i.txt
+ 20MB
+ 20
+
${log.pattern}
-
-
+
\ No newline at end of file
diff --git a/rules/lantern-service-rules/src/main/java/com/lanternsoftware/rules/RulesEngine.java b/rules/lantern-service-rules/src/main/java/com/lanternsoftware/rules/RulesEngine.java
index b06a2b8..2a94532 100644
--- a/rules/lantern-service-rules/src/main/java/com/lanternsoftware/rules/RulesEngine.java
+++ b/rules/lantern-service-rules/src/main/java/com/lanternsoftware/rules/RulesEngine.java
@@ -113,6 +113,12 @@ public class RulesEngine {
timer.schedule(nextTask, nextDate);
}
+ public void schedule(TimerTask _task, long _delay) {
+ if (timer == null)
+ return;
+ timer.schedule(_task, _delay);
+ }
+
public static void shutdown() {
if (INSTANCE == null)
return;
diff --git a/util/lantern-util-common/src/main/java/com/lanternsoftware/util/LanternFiles.java b/util/lantern-util-common/src/main/java/com/lanternsoftware/util/LanternFiles.java
index cfb4294..b71952b 100644
--- a/util/lantern-util-common/src/main/java/com/lanternsoftware/util/LanternFiles.java
+++ b/util/lantern-util-common/src/main/java/com/lanternsoftware/util/LanternFiles.java
@@ -2,9 +2,9 @@ package com.lanternsoftware.util;
public abstract class LanternFiles {
public static final String SOURCE_PATH = "C:\\lantern\\LanternPowerMonitor\\";
-// public static final String OPS_PATH = "D:\\zwave\\localhost\\";
-// public static final String OPS_PATH = "D:\\zwave\\mark4770\\";
-// public static final String OPS_PATH = "D:\\zwave\\prodremote\\";
public static final String OPS_PATH = "/opt/tomcat/";
- public static final String BACKUP_PATH = "D:\\zwave\\localhost\\";
+// public static final String OPS_PATH = "D:\\zwave\\prodremote\\";
+// public static final String OPS_PATH = "D:\\zwave\\localhost\\";
+ public static final String BACKUP_SOURCE = "D:\\zwave\\prodremote\\";
+ public static final String BACKUP_DEST = "D:\\zwave\\localhost\\";
}
diff --git a/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/security/SecurityController.java b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/security/SecurityController.java
index 449379f..07b13db 100644
--- a/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/security/SecurityController.java
+++ b/zwave/lantern-service-zwave/src/main/java/com/lanternsoftware/zwave/security/SecurityController.java
@@ -46,7 +46,7 @@ public class SecurityController {
LOG.info("handling event {} pin {} most recent event is {}", eventIdx, _sw.getGpioPin(), high);
if (high == null)
return;
- _listener.onStateChanged(_sw.getNodeId(), high);
+ _listener.onStateChanged(_sw.getNodeId(), pin.isHigh());
});
});
}