diff --git a/currentmonitor/lantern-currentmonitor/pom.xml b/currentmonitor/lantern-currentmonitor/pom.xml index ee749c4..2d2dd5d 100644 --- a/currentmonitor/lantern-currentmonitor/pom.xml +++ b/currentmonitor/lantern-currentmonitor/pom.xml @@ -3,7 +3,7 @@ com.lanternsoftware.currentmonitor lantern-currentmonitor jar - 0.9.6 + 1.0.1 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 f69d1a4..f11672a 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 @@ -101,7 +101,7 @@ public class CurrentMonitor { 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(_breakers, _b->String.valueOf(_b.getPort()))); + LOG.info("Starting to monitor ports {}", CollectionUtils.transformToCommaSeparated(validBreakers, _b->String.valueOf(_b.getPort()))); executor.submit(sampler); } 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 a70423c..45b385d 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 @@ -13,10 +13,12 @@ import com.lanternsoftware.datamodel.currentmonitor.BreakerPowerMinute; import com.lanternsoftware.datamodel.currentmonitor.HubConfigCharacteristic; import com.lanternsoftware.datamodel.currentmonitor.HubConfigService; import com.lanternsoftware.datamodel.currentmonitor.HubPowerMinute; +import com.lanternsoftware.datamodel.currentmonitor.NetworkStatus; import com.lanternsoftware.util.CollectionUtils; import com.lanternsoftware.util.DateUtils; import com.lanternsoftware.util.NullUtils; import com.lanternsoftware.util.ResourceLoader; +import com.lanternsoftware.util.ZipUtils; import com.lanternsoftware.util.concurrency.ConcurrencyUtils; import com.lanternsoftware.util.dao.DaoEntity; import com.lanternsoftware.util.dao.DaoSerializer; @@ -39,6 +41,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -165,20 +168,32 @@ public class MonitorApp { 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 = 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 > 10) + log = Arrays.copyOfRange(log, log.length-10, log.length); + return ZipUtils.zip(NullUtils.toByteArray(CollectionUtils.delimit(Arrays.asList(log), "\n"))); + } return null; } }); bluetoothConfig.start(); if (NullUtils.isNotEmpty(config.getAuthCode())) authCode = config.getAuthCode(); - else if (NullUtils.isNotEmpty(host)) { + else if (NullUtils.isNotEmpty(host) && NullUtils.isNotEmpty(config.getUsername()) && NullUtils.isNotEmpty(config.getPassword())) { HttpGet auth = new HttpGet(host + "auth"); HttpPool.addBasicAuthHeader(auth, config.getUsername(), config.getPassword()); authCode = DaoSerializer.getString(DaoSerializer.parse(pool.executeToString(auth)), "auth_code"); } if (NullUtils.isNotEmpty(config.getMqttBrokerUrl())) mqttPoster = new MqttPoster(config); - if (NullUtils.isNotEmpty(host)) { + if (NullUtils.isNotEmpty(host) && NullUtils.isNotEmpty(authCode)) { while (true) { HttpGet get = new HttpGet(host + "config"); get.addHeader("auth_code", authCode); @@ -209,24 +224,26 @@ public class MonitorApp { breakerConfig.getBreakerGroups().add(g); } } - LOG.info("Breaker Config loaded"); - BreakerHub hub = breakerConfig.getHub(config.getHub()); - if (hub != null) { - if (config.isNeedsCalibration() && (config.getAutoCalibrationVoltage() != 0.0)) { - double newCal = monitor.calibrateVoltage(hub.getVoltageCalibrationFactor(), config.getAutoCalibrationVoltage()); - if (newCal != 0.0) { - hub.setVoltageCalibrationFactor(newCal); - config.setNeedsCalibration(false); - ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config)); - post(DaoSerializer.toZipBson(breakerConfig), "config"); + if (breakerConfig != null) { + LOG.info("Breaker Config loaded"); + BreakerHub hub = breakerConfig.getHub(config.getHub()); + if (hub != null) { + if (config.isNeedsCalibration() && (config.getAutoCalibrationVoltage() != 0.0)) { + double newCal = monitor.calibrateVoltage(hub.getVoltageCalibrationFactor(), config.getAutoCalibrationVoltage()); + if (newCal != 0.0) { + hub.setVoltageCalibrationFactor(newCal); + config.setNeedsCalibration(false); + ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config)); + post(DaoSerializer.toZipBson(breakerConfig), "config"); + } } + List breakers = breakerConfig.getBreakersForHub(config.getHub()); + LOG.info("Monitoring {} breakers for hub {}", CollectionUtils.size(breakers), hub.getHub()); + if (CollectionUtils.size(breakers) > 0) + monitor.monitorPower(hub, breakers, 1000, logger); } - List breakers = breakerConfig.getBreakersForHub(config.getHub()); - LOG.info("Monitoring {} breakers for hub {}", CollectionUtils.size(breakers), hub.getHub()); - if (CollectionUtils.size(breakers) > 0) - monitor.monitorPower(hub, breakers, 1000, logger); + monitor.submit(new PowerPoster()); } - monitor.submit(new PowerPoster()); Runtime.getRuntime().addShutdownHook(new Thread(() -> { synchronized (running) { running.set(false); diff --git a/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/util/NetworkMonitor.java b/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/util/NetworkMonitor.java index 3130ef8..724ad40 100644 --- a/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/util/NetworkMonitor.java +++ b/currentmonitor/lantern-currentmonitor/src/main/java/com/lanternsoftware/currentmonitor/util/NetworkMonitor.java @@ -18,33 +18,46 @@ public abstract class NetworkMonitor { private static final Pattern wifiPattern = Pattern.compile(".*(wlan[0-9]):(.*)"); public static NetworkStatus getNetworkStatus() { - NetworkStatus status = new NetworkStatus(); String[] commands = {"ifconfig", "-a"}; InputStream is = null; try { is = Runtime.getRuntime().exec(commands).getInputStream(); - String ifconfig = IOUtils.toString(is); - status.setEthernetIPs(getIPs(ifconfig, ethernetPattern)); - status.setWifiIPs(getIPs(ifconfig, wifiPattern)); + return getNetworkStatus(IOUtils.toString(is)); } catch (Exception _e) { LOG.error("Failed to check network state", _e); + return new NetworkStatus(); } finally { IOUtils.closeQuietly(is); } + } + + public static NetworkStatus getNetworkStatus(String _ifconfig) { + NetworkStatus status = new NetworkStatus(); + status.setEthernetIPs(parseEthernetIp(_ifconfig)); + status.setWifiIPs(parseWifiIp(_ifconfig)); return status; } + public static List parseWifiIp(String _ifconfig) { + return getIPs(_ifconfig, wifiPattern); + } + + public static List parseEthernetIp(String _ifconfig) { + return getIPs(_ifconfig, ethernetPattern); + } + private static List getIPs(String _ifConfig, Pattern _pattern) { List ips = new ArrayList<>(); Matcher m = _pattern.matcher(_ifConfig); while (m.find()) { int start = m.start(0); int ipStart = _ifConfig.indexOf("inet ", start) + 5; + int deviceEnd = _ifConfig.indexOf("\n\n", start); if (ipStart > 4) { int ipEnd = _ifConfig.indexOf(" ", ipStart); - if (ipEnd > -1) + if ((ipEnd > -1) && ((deviceEnd < 0) || (ipEnd <= deviceEnd))) ips.add(_ifConfig.substring(ipStart, ipEnd)); } } 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 740a8f4..bf9c4d9 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 @@ -15,7 +15,9 @@ public enum HubConfigCharacteristic { AccountId(7, CharacteristicFlag.READ), NetworkState(8, CharacteristicFlag.READ), Flash(9, CharacteristicFlag.WRITE), - Host(10, CharacteristicFlag.WRITE); + Host(10, CharacteristicFlag.WRITE), + Log(11, CharacteristicFlag.READ), + NetworkDetails(12, CharacteristicFlag.READ); public final int idx; public final UUID uuid; diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/NetworkStatus.java b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/NetworkStatus.java index 75ab05a..34a497b 100644 --- a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/NetworkStatus.java +++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/NetworkStatus.java @@ -1,13 +1,16 @@ package com.lanternsoftware.datamodel.currentmonitor; import com.lanternsoftware.util.CollectionUtils; +import com.lanternsoftware.util.dao.annotations.DBSerializable; import java.util.EnumSet; import java.util.List; +@DBSerializable public class NetworkStatus { private List wifiIPs; private List ethernetIPs; + private boolean pingSuccessful = true; public List getWifiIPs() { return wifiIPs; @@ -25,6 +28,14 @@ public class NetworkStatus { ethernetIPs = _ethernetIPs; } + public boolean isPingSuccessful() { + return pingSuccessful; + } + + public void setPingSuccessful(boolean _pingSuccessful) { + pingSuccessful = _pingSuccessful; + } + public boolean isWifiConnected() { return CollectionUtils.isNotEmpty(wifiIPs); } @@ -35,9 +46,9 @@ public class NetworkStatus { public byte toMask() { EnumSet adapters = EnumSet.noneOf(NetworkAdapter.class); - if (isWifiConnected()) + if (isWifiConnected() && isPingSuccessful()) adapters.add(NetworkAdapter.WIFI); - if (isEthernetConnected()) + if (isEthernetConnected() && isPingSuccessful()) adapters.add(NetworkAdapter.ETHERNET); return NetworkAdapter.toMask(adapters); } diff --git a/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/NetworkStatusSerializer.java b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/NetworkStatusSerializer.java new file mode 100644 index 0000000..eab2f76 --- /dev/null +++ b/currentmonitor/lantern-datamodel-currentmonitor/src/main/java/com/lanternsoftware/datamodel/currentmonitor/dao/NetworkStatusSerializer.java @@ -0,0 +1,44 @@ +package com.lanternsoftware.datamodel.currentmonitor.dao; + +import com.lanternsoftware.datamodel.currentmonitor.NetworkStatus; +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.lang.String; +import java.util.Collections; +import java.util.List; + +public class NetworkStatusSerializer extends AbstractDaoSerializer +{ + @Override + public Class getSupportedClass() + { + return NetworkStatus.class; + } + + @Override + public List getSupportedProxies() { + return Collections.singletonList(DaoProxyType.MONGO); + } + + @Override + public DaoEntity toDaoEntity(NetworkStatus _o) + { + DaoEntity d = new DaoEntity(); + d.put("wifi_ips", _o.getWifiIPs()); + d.put("ethernet_ips", _o.getEthernetIPs()); + d.put("ping_successful", _o.isPingSuccessful()); + return d; + } + + @Override + public NetworkStatus fromDaoEntity(DaoEntity _d) + { + NetworkStatus o = new NetworkStatus(); + o.setWifiIPs(DaoSerializer.getList(_d, "wifi_ips", String.class)); + o.setEthernetIPs(DaoSerializer.getList(_d, "ethernet_ips", String.class)); + o.setPingSuccessful(DaoSerializer.getBoolean(_d, "ping_successful")); + 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 ece1bb1..55475d5 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 @@ -12,5 +12,6 @@ com.lanternsoftware.datamodel.currentmonitor.dao.BreakerSerializer com.lanternsoftware.datamodel.currentmonitor.dao.EnergyBlockSerializer com.lanternsoftware.datamodel.currentmonitor.dao.HubPowerMinuteSerializer com.lanternsoftware.datamodel.currentmonitor.dao.MeterSerializer +com.lanternsoftware.datamodel.currentmonitor.dao.NetworkStatusSerializer com.lanternsoftware.datamodel.currentmonitor.dao.SequenceSerializer com.lanternsoftware.datamodel.currentmonitor.dao.SignupResponseSerializer