mirror of
https://github.com/zyphlar/LanternPowerMonitor.git
synced 2024-03-08 14:07:47 +00:00
Initial Commit
This commit is contained in:
parent
21c28201c5
commit
1334c110ff
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
*.iml
|
||||
*.project
|
||||
*.classpath
|
||||
.idea/
|
||||
.gradle/
|
||||
*.settings/
|
||||
*target/
|
||||
build/
|
||||
release/
|
105
currentmonitor/lantern-currentmonitor/pom.xml
Normal file
105
currentmonitor/lantern-currentmonitor/pom.xml
Normal file
|
@ -0,0 +1,105 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.lanternsoftware.currentmonitor</groupId>
|
||||
<artifactId>lantern-currentmonitor</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0.0</version>
|
||||
<name>lantern-currentmonitor</name>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.29</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pi4j</groupId>
|
||||
<artifactId>pi4j-gpio-extension</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.hypfvieh</groupId>
|
||||
<artifactId>bluez-dbus</artifactId>
|
||||
<version>0.1.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.lanternsoftware.currentmonitor</groupId>
|
||||
<artifactId>lantern-datamodel-currentmonitor</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.lanternsoftware.util</groupId>
|
||||
<artifactId>lantern-util-http</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
<phase>compile</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<optimize>true</optimize>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<finalName>lantern-currentmonitor</finalName>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<manifestEntries>
|
||||
<Main-Class>com.lanternsoftware.currentmonitor.MonitorApp</Main-Class>
|
||||
<Specification-Title>Lantern Power Monitor</Specification-Title>
|
||||
<Specification-Version>${project.version}</Specification-Version>
|
||||
<Specification-Vendor>Lantern Software, Inc.</Specification-Vendor>
|
||||
</manifestEntries>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,39 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.bluetooth.BleApplication;
|
||||
import com.lanternsoftware.currentmonitor.bluetooth.BleCharacteristic;
|
||||
import com.lanternsoftware.currentmonitor.bluetooth.BleCharacteristicListener;
|
||||
import com.lanternsoftware.currentmonitor.bluetooth.BleHelper;
|
||||
import com.lanternsoftware.currentmonitor.bluetooth.BleService;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.HubConfigService;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class BluetoothConfig implements Runnable {
|
||||
private final AtomicBoolean running = new AtomicBoolean(true);
|
||||
private final BleApplication app;
|
||||
|
||||
public BluetoothConfig(String _hubName, BleCharacteristicListener _listener) {
|
||||
BleHelper.getAdapter().setPowered(true);
|
||||
BleHelper.requestBusName("com.lanternsoftware");
|
||||
BleHelper.setBasePath("/com/lanternsoftware");
|
||||
HubConfigService service = new HubConfigService();
|
||||
List<BleCharacteristic> chars = CollectionUtils.transform(service.getCharacteristics(), _c->new BleCharacteristic("HubConfig", _c.getUUID(), _c.name(), _c.getFlags()));
|
||||
chars.forEach(_c->_c.setListener(_listener));
|
||||
app = new BleApplication("Lantern", _hubName, new BleService("HubConfig", service.getServiceUUID(), chars));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
app.start();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
synchronized (running) {
|
||||
running.set(false);
|
||||
}
|
||||
app.stop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
||||
import com.pi4j.io.gpio.GpioPinAnalogInput;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BreakerSamples {
|
||||
private final Breaker breaker;
|
||||
private final GpioPinAnalogInput voltagePin;
|
||||
private final GpioPinAnalogInput currentPin;
|
||||
private final List<PowerSample> samples;
|
||||
private int sampleCnt;
|
||||
|
||||
public BreakerSamples(Breaker _breaker, GpioPinAnalogInput _voltagePin, GpioPinAnalogInput _currentPin, List<PowerSample> _samples) {
|
||||
breaker = _breaker;
|
||||
voltagePin = _voltagePin;
|
||||
currentPin = _currentPin;
|
||||
samples = _samples;
|
||||
}
|
||||
|
||||
public Breaker getBreaker() {
|
||||
return breaker;
|
||||
}
|
||||
|
||||
public GpioPinAnalogInput getVoltagePin() {
|
||||
return voltagePin;
|
||||
}
|
||||
|
||||
public GpioPinAnalogInput getCurrentPin() {
|
||||
return currentPin;
|
||||
}
|
||||
|
||||
public List<PowerSample> getSamples() {
|
||||
return samples;
|
||||
}
|
||||
|
||||
public PowerSample getSample(int _sample) {
|
||||
return samples.get(_sample);
|
||||
}
|
||||
|
||||
public int getSampleCnt() {
|
||||
return sampleCnt;
|
||||
}
|
||||
|
||||
public void setSampleCnt(int _sampleCnt) {
|
||||
sampleCnt = _sampleCnt;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public interface CurrentListener {
|
||||
void onCurrentEvent(int _chip, int _pin, double _currentAmps, Date _start);
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerHub;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPolarity;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPower;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.concurrency.ConcurrencyUtils;
|
||||
import com.pi4j.gpio.extension.base.AdcGpioProvider;
|
||||
import com.pi4j.gpio.extension.mcp.MCP3008GpioProvider;
|
||||
import com.pi4j.gpio.extension.mcp.MCP3008Pin;
|
||||
import com.pi4j.io.gpio.GpioController;
|
||||
import com.pi4j.io.gpio.GpioFactory;
|
||||
import com.pi4j.io.gpio.GpioPinAnalogInput;
|
||||
import com.pi4j.io.spi.SpiChannel;
|
||||
import com.pi4j.io.spi.SpiDevice;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class CurrentMonitor {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CurrentMonitor.class);
|
||||
private static final int BATCH_CNT = 4;
|
||||
private GpioController gpio;
|
||||
private final ExecutorService executor = Executors.newCachedThreadPool();
|
||||
private final Map<Integer, AdcGpioProvider> chips = new HashMap<>();
|
||||
private final Map<Integer, GpioPinAnalogInput> pins = new HashMap<>();
|
||||
private Sampler sampler;
|
||||
private PowerListener listener;
|
||||
private boolean debug = false;
|
||||
|
||||
public void start() {
|
||||
try {
|
||||
gpio = GpioFactory.getInstance();
|
||||
LOG.info("Current Monitor Started");
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.info("Failed to get gpio factory", t);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
stopMonitoring();
|
||||
ConcurrencyUtils.sleep(1000);
|
||||
executor.shutdownNow();
|
||||
chips.clear();
|
||||
pins.clear();
|
||||
gpio.shutdown();
|
||||
LOG.info("Current Monitor Stopped");
|
||||
}
|
||||
|
||||
public void setDebug(boolean _debug) {
|
||||
debug = _debug;
|
||||
}
|
||||
|
||||
public void monitorPower(BreakerHub _hub, List<Breaker> _breakers, int _intervalMs, PowerListener _listener) {
|
||||
stopMonitoring();
|
||||
listener = _listener;
|
||||
sampler = new Sampler(_hub, _breakers, _intervalMs, 2);
|
||||
LOG.info("Starting to monitor ports {}", CollectionUtils.transformToCommaSeparated(_breakers, _b->String.valueOf(_b.getPort())));
|
||||
executor.submit(sampler);
|
||||
}
|
||||
|
||||
private GpioPinAnalogInput getPin(int _chip, int _pin) {
|
||||
GpioPinAnalogInput pin;
|
||||
synchronized (pins) {
|
||||
AdcGpioProvider chip = chips.get(_chip);
|
||||
if (chip == null) {
|
||||
SpiChannel channel = SpiChannel.getByNumber(_chip);
|
||||
if (channel == null)
|
||||
return null;
|
||||
try {
|
||||
chip = new MCP3008GpioProvider(channel, 1250000, SpiDevice.DEFAULT_SPI_MODE, false);
|
||||
chips.put(_chip, chip);
|
||||
} catch (IOException _e) {
|
||||
LOG.error("Failed to connect to chip {}", _chip, _e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
int pinKey = pinKey(_chip, _pin);
|
||||
pin = pins.get(pinKey);
|
||||
if (pin == null) {
|
||||
pin = gpio.provisionAnalogInputPin(chip, MCP3008Pin.ALL[_pin], String.valueOf(pinKey));
|
||||
pins.put(pinKey, pin);
|
||||
}
|
||||
}
|
||||
return pin;
|
||||
}
|
||||
|
||||
private Integer pinKey(int _chip, int _pin) {
|
||||
return (_chip*8)+_pin;
|
||||
}
|
||||
|
||||
public void submit(Runnable _runnable) {
|
||||
executor.submit(_runnable);
|
||||
}
|
||||
|
||||
public void stopMonitoring() {
|
||||
if (sampler != null) {
|
||||
sampler.stop();
|
||||
sampler = null;
|
||||
}
|
||||
}
|
||||
|
||||
private class Sampler implements Runnable {
|
||||
private boolean running = true;
|
||||
private final BreakerHub hub;
|
||||
private final List<List<BreakerSamples>> breakers;
|
||||
private final int intervalNs;
|
||||
private final int concurrentBreakerCnt;
|
||||
|
||||
public Sampler(BreakerHub _hub, List<Breaker> _breakers, int _intervalMs, int _concurrentBreakerCnt) {
|
||||
hub = _hub;
|
||||
GpioPinAnalogInput voltagePin = getPin(0, 0);
|
||||
breakers = CollectionUtils.transform(_breakers, _b->{
|
||||
LOG.info("Getting Chip {}, Pin {} for port {}", _b.getChip(), _b.getPin(), _b.getPort());
|
||||
GpioPinAnalogInput currentPin = getPin(_b.getChip(), _b.getPin());
|
||||
List<BreakerSamples> batches = new ArrayList<>(BATCH_CNT);
|
||||
for (int i=0; i<BATCH_CNT; i++) {
|
||||
List<PowerSample> samples = new ArrayList<>(30000/_breakers.size());
|
||||
for (int j=0; j<30000/_breakers.size(); j++) {
|
||||
samples.add(new PowerSample());
|
||||
}
|
||||
batches.add(new BreakerSamples(_b, voltagePin, currentPin, samples));
|
||||
}
|
||||
return batches;
|
||||
});
|
||||
intervalNs = _intervalMs*1000000;
|
||||
concurrentBreakerCnt = Math.min(_breakers.size(), _concurrentBreakerCnt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long start = System.nanoTime();
|
||||
long interval = 0;
|
||||
int cycle;
|
||||
BreakerSamples[] cycleBreakers = new BreakerSamples[concurrentBreakerCnt];
|
||||
try {
|
||||
while (true) {
|
||||
synchronized (this) {
|
||||
if (!running)
|
||||
break;
|
||||
}
|
||||
final Date readTime = new Date();
|
||||
final long intervalStart = (interval * intervalNs) + start;
|
||||
long intervalEnd = intervalStart + intervalNs;
|
||||
cycle = 0;
|
||||
final int batch = (int) (interval % BATCH_CNT);
|
||||
int curBreaker;
|
||||
for (curBreaker = 0; curBreaker < breakers.size(); curBreaker++) {
|
||||
breakers.get(curBreaker).get(batch).setSampleCnt(0);
|
||||
}
|
||||
while (System.nanoTime() < intervalEnd) {
|
||||
for (curBreaker = 0; curBreaker < concurrentBreakerCnt; curBreaker++) {
|
||||
cycleBreakers[curBreaker] = breakers.get(((cycle * concurrentBreakerCnt) + curBreaker) % breakers.size()).get(batch);
|
||||
}
|
||||
cycle++;
|
||||
long cycleEnd = intervalStart + (cycle * (intervalNs / hub.getFrequency()));
|
||||
while (System.nanoTime() < cycleEnd) {
|
||||
for (curBreaker = 0; curBreaker < concurrentBreakerCnt; curBreaker++) {
|
||||
PowerSample sample = cycleBreakers[curBreaker].getSample(cycleBreakers[curBreaker].getSampleCnt());
|
||||
sample.voltage = cycleBreakers[curBreaker].getVoltagePin().getValue();
|
||||
sample.current = cycleBreakers[curBreaker].getCurrentPin().getValue();
|
||||
cycleBreakers[curBreaker].setSampleCnt(cycleBreakers[curBreaker].getSampleCnt()+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
interval++;
|
||||
executor.submit(() -> {
|
||||
for (List<BreakerSamples> breaker : breakers) {
|
||||
double vOffset = 0.0;
|
||||
double iOffset = 0.0;
|
||||
BreakerSamples samples = breaker.get(batch);
|
||||
List<PowerSample> validSamples = samples.getSamples().subList(0, samples.getSampleCnt());
|
||||
for (PowerSample sample : validSamples) {
|
||||
vOffset += sample.voltage;
|
||||
iOffset += sample.current;
|
||||
}
|
||||
vOffset /= samples.getSampleCnt();
|
||||
iOffset /= samples.getSampleCnt();
|
||||
int lowSamples = 0;
|
||||
double pSum = 0.0;
|
||||
double vRms = 0.0;
|
||||
double lowPassFilter = samples.getBreaker().getLowPassFilter();
|
||||
for (PowerSample sample : validSamples) {
|
||||
sample.current -= iOffset;
|
||||
if (Math.abs(sample.current) < lowPassFilter)
|
||||
lowSamples++;
|
||||
sample.voltage -= vOffset;
|
||||
pSum += sample.current * sample.voltage;
|
||||
vRms += sample.voltage * sample.voltage;
|
||||
}
|
||||
vRms /= validSamples.size();
|
||||
vRms = hub.getVoltageCalibrationFactor() * Math.sqrt(vRms);
|
||||
int lowSampleRatio = (lowSamples * 100) / samples.getSampleCnt();
|
||||
double realPower = Math.abs((hub.getVoltageCalibrationFactor() * samples.getBreaker().getFinalCalibrationFactor() * pSum) / samples.getSampleCnt());
|
||||
if ((lowSampleRatio > 75) && realPower < 13.0)
|
||||
realPower = 0.0;
|
||||
if (samples.getBreaker().getPolarity() == BreakerPolarity.SOLAR)
|
||||
realPower = -realPower;
|
||||
if (debug) {
|
||||
synchronized (CurrentMonitor.this) {
|
||||
LOG.info("===========================Start Port {}", samples.getBreaker().getPort());
|
||||
LOG.info("Samples: {}", samples.getSampleCnt());
|
||||
LOG.info("vMin: {}, vMax: {}, vOffset: {}", String.format("%.3f", CollectionUtils.getSmallest(validSamples, Comparator.comparing(_v -> _v.voltage)).voltage), String.format("%.3f", CollectionUtils.getLargest(validSamples, Comparator.comparing(_v -> _v.voltage)).voltage), String.format("%.3f", vOffset));
|
||||
LOG.info("iMin: {}, iMax: {}, iOffset: {}", String.format("%.3f", CollectionUtils.getSmallest(validSamples, Comparator.comparing(_v -> _v.current)).current), String.format("%.3f", CollectionUtils.getLargest(validSamples, Comparator.comparing(_v -> _v.current)).current), String.format("%.3f", iOffset));
|
||||
double iRms = samples.getBreaker().getFinalCalibrationFactor() * Math.sqrt(CollectionUtils.mean(CollectionUtils.transform(validSamples, _p -> _p.current * _p.current)));
|
||||
LOG.info("vRms: {}", String.format("%.3f", vRms));
|
||||
LOG.info("iRms: {}", String.format("%.3f", iRms));
|
||||
double apparentPower = vRms * iRms;
|
||||
LOG.info("Apparent Power: {} watts", String.format("%.3f", apparentPower));
|
||||
LOG.info("Real Power: {} watts", String.format("%.3f", realPower));
|
||||
double powerFactor = realPower / apparentPower;
|
||||
LOG.info("Power Factor: {}", String.format("%.3f", powerFactor));
|
||||
LOG.info("===========================End Port {}", samples.getBreaker().getPort());
|
||||
}
|
||||
}
|
||||
listener.onPowerEvent(new BreakerPower(samples.getBreaker().getPanel(), samples.getBreaker().getSpace(), readTime, realPower, vRms));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.error("Exception while monitoring power", t);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void stop() {
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,409 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.bluetooth.BleCharacteristicListener;
|
||||
import com.lanternsoftware.currentmonitor.led.LEDFlasher;
|
||||
import com.lanternsoftware.currentmonitor.util.NetworkMonitor;
|
||||
import com.lanternsoftware.currentmonitor.wifi.WifiConfig;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerHub;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPower;
|
||||
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.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.DateUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.concurrency.ConcurrencyUtils;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
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.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.Console;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
public class MonitorApp {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MonitorApp.class);
|
||||
private static final String WORKING_DIR = "/opt/currentmonitor/";
|
||||
private static String authCode;
|
||||
private static MonitorConfig config;
|
||||
private static BreakerConfig breakerConfig;
|
||||
private static String host;
|
||||
private static Date lastUpdateCheck = new Date();
|
||||
private static HttpPool pool;
|
||||
private static LEDFlasher flasher = null;
|
||||
private static final AtomicBoolean running = new AtomicBoolean(true);
|
||||
private static final CurrentMonitor monitor = new CurrentMonitor();
|
||||
private static final List<BreakerPower> readings = new ArrayList<>();
|
||||
private static final String version = getVersionNumber();
|
||||
private static final PowerListener logger = _p -> {
|
||||
if (!config.isDebug()) {
|
||||
_p.setHubVersion(version);
|
||||
if (breakerConfig != null)
|
||||
_p.setAccountId(breakerConfig.getAccountId());
|
||||
synchronized (readings) {
|
||||
readings.add(_p);
|
||||
}
|
||||
} else
|
||||
LOG.info("Panel{} - Space{} Power: {}W", _p.getPanel(), Breaker.toSpaceDisplay(_p.getSpace()), String.format("%.3f", _p.getPower()));
|
||||
};
|
||||
|
||||
public static void main(String[] args) {
|
||||
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");
|
||||
return;
|
||||
}
|
||||
pool = new HttpPool(10, 10, config.getSocketTimeout(), config.getConnectTimeout(), config.getSocketTimeout());
|
||||
host = NullUtils.terminateWith(config.getHost(), "/");
|
||||
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(()->{
|
||||
switch (ch) {
|
||||
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("service currentmonitor restart");
|
||||
} catch (IOException _e) {
|
||||
LOG.error("Exception occurred while trying to restart", _e);
|
||||
}
|
||||
break;
|
||||
case Reboot:
|
||||
LOG.info("Rebooting Pi...");
|
||||
try {
|
||||
Runtime.getRuntime().exec("reboot now");
|
||||
} catch (IOException _e) {
|
||||
LOG.error("Exception occurred while trying to reboot", _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()};
|
||||
return null;
|
||||
}
|
||||
});
|
||||
monitor.submit(bluetoothConfig);
|
||||
if (NullUtils.isNotEmpty(config.getAuthCode())) {
|
||||
authCode = config.getAuthCode();
|
||||
//TODO: check auth code validity
|
||||
}
|
||||
else {
|
||||
HttpGet auth = new HttpGet(host + "auth");
|
||||
HttpPool.addBasicAuthHeader(auth, config.getUsername(), config.getPassword());
|
||||
authCode = DaoSerializer.getString(DaoSerializer.parse(pool.executeToString(auth)), "auth_code");
|
||||
}
|
||||
while (true) {
|
||||
HttpGet get = new HttpGet(host + "config");
|
||||
get.addHeader("auth_code", authCode);
|
||||
breakerConfig = DaoSerializer.parse(pool.executeToString(get), BreakerConfig.class);
|
||||
if (breakerConfig != null)
|
||||
break;
|
||||
LOG.error("Failed to load breaker config. Retrying in 5 seconds...");
|
||||
ConcurrencyUtils.sleep(5000);
|
||||
}
|
||||
LOG.info("Breaker Config loaded");
|
||||
LOG.debug(DaoSerializer.toJson(breakerConfig));
|
||||
BreakerHub hub = breakerConfig.getHub(config.getHub());
|
||||
if (hub != null) {
|
||||
List<Breaker> breakers = breakerConfig.getBreakersForHub(config.getHub());
|
||||
LOG.info("Monitoring {} breakers for hub {}", CollectionUtils.size(breakers), hub.getHub());
|
||||
monitor.monitorPower(hub, breakers, 1000, logger);
|
||||
}
|
||||
monitor.submit(new PowerPoster());
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
synchronized (running) {
|
||||
running.set(false);
|
||||
}
|
||||
bluetoothConfig.stop();
|
||||
monitor.stop();
|
||||
pool.shutdown();
|
||||
}, "Monitor Shutdown"));
|
||||
Console c = System.console();
|
||||
BufferedReader reader = (c == null)?new BufferedReader(new InputStreamReader(System.in)):null;
|
||||
while (running.get()) {
|
||||
try {
|
||||
String command = c != null ? c.readLine() : reader.readLine();
|
||||
if (NullUtils.isEqual("exit", command))
|
||||
break;
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Exception while reading from console input", _e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class PowerPoster implements Runnable {
|
||||
private final long firstPost;
|
||||
private long lastPost;
|
||||
private int lastMinute;
|
||||
private final Map<Integer, Float[]> breakers = new HashMap<>();
|
||||
|
||||
public PowerPoster() {
|
||||
firstPost = (new Date().getTime()/1000)*1000;
|
||||
lastPost = new Date().getTime();
|
||||
lastMinute = (int)(new Date().getTime()/60000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (true) {
|
||||
synchronized (running) {
|
||||
if (!running.get())
|
||||
break;
|
||||
}
|
||||
DaoEntity post = null;
|
||||
DaoEntity minutePost = null;
|
||||
int curMinute = (int) (new Date().getTime() / 60000);
|
||||
synchronized (readings) {
|
||||
if (!readings.isEmpty()) {
|
||||
post = new DaoEntity("readings", DaoSerializer.toDaoEntities(readings));
|
||||
if (curMinute != lastMinute) {
|
||||
HubPowerMinute minute = new HubPowerMinute();
|
||||
minute.setAccountId(breakerConfig.getAccountId());
|
||||
minute.setHub(config.getHub());
|
||||
minute.setMinute(lastMinute);
|
||||
minute.setBreakers(CollectionUtils.transform(breakers.entrySet(), _e -> {
|
||||
BreakerPowerMinute breaker = new BreakerPowerMinute();
|
||||
breaker.setPanel(Breaker.toPanel(_e.getKey()));
|
||||
breaker.setSpace(Breaker.toSpace(_e.getKey()));
|
||||
breaker.setReadings(CollectionUtils.asArrayList(_e.getValue()));
|
||||
return breaker;
|
||||
}));
|
||||
breakers.clear();
|
||||
minutePost = DaoSerializer.toDaoEntity(minute);
|
||||
lastMinute = curMinute;
|
||||
}
|
||||
for (BreakerPower power : readings) {
|
||||
Float[] breakerReadings = breakers.computeIfAbsent(Breaker.toId(power.getPanel(), power.getSpace()), _i -> new Float[60]);
|
||||
breakerReadings[(int) ((power.getReadTime().getTime() / 1000)%60)] = (float) power.getPower();
|
||||
}
|
||||
readings.clear();
|
||||
}
|
||||
}
|
||||
if (minutePost != null) {
|
||||
byte[] payload = DaoSerializer.toZipBson(minutePost);
|
||||
if (!post(payload, "power/hub")) {
|
||||
LOG.info("Failed Posting HubPowerMinute, writing cache");
|
||||
ResourceLoader.writeFile(WORKING_DIR + "cache/" + UUID.randomUUID().toString() + ".min", payload);
|
||||
}
|
||||
}
|
||||
if (post != null) {
|
||||
byte[] payload = DaoSerializer.toZipBson(post);
|
||||
if (post(payload, "power/batch")) {
|
||||
File[] files = new File(WORKING_DIR + "cache").listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
payload = ResourceLoader.loadFile(file.getAbsolutePath());
|
||||
if (post(payload, file.getName().endsWith("dat") ? "power/batch" : "power/hub"))
|
||||
file.delete();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
if (now - lastPost < 1000) {
|
||||
ConcurrencyUtils.sleep(1000 - duration);
|
||||
}
|
||||
lastPost = now;
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.error("Exception in PowerPoster", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
HttpPost post = new HttpPost(host + _path);
|
||||
post.addHeader("auth_code", authCode);
|
||||
post.setEntity(new ByteArrayEntity(_payload, ContentType.APPLICATION_OCTET_STREAM));
|
||||
CloseableHttpResponse resp = pool.execute(post);
|
||||
try {
|
||||
return ((resp != null) && (resp.getStatusLine() != null) && (resp.getStatusLine().getStatusCode() == 200));
|
||||
} finally {
|
||||
IOUtils.closeQuietly(resp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final class UpdateChecker implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
DaoEntity meta = DaoSerializer.fromZipBson(pool.executeToByteArray(new HttpGet(host + "update/version")));
|
||||
String newVersion = DaoSerializer.getString(meta, "version");
|
||||
if (NullUtils.isNotEqual(newVersion, version)) {
|
||||
LOG.info("New version found, {}, downloading...", newVersion);
|
||||
byte[] jar = pool.executeToByteArray(new HttpGet(host + "update"));
|
||||
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);
|
||||
try {
|
||||
Runtime.getRuntime().exec("service currentmonitor restart");
|
||||
} catch (IOException _e) {
|
||||
LOG.error("Exception occurred while trying to restart", _e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CommandChecker implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
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("raspi-config --expand-rootfs");
|
||||
ConcurrencyUtils.sleep(3000);
|
||||
Runtime.getRuntime().exec("reboot");
|
||||
} 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("service currentmonitor restart");
|
||||
} catch (IOException _e) {
|
||||
LOG.error("Exception occurred while trying to restart", _e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getVersionNumber() {
|
||||
InputStream is = null;
|
||||
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;
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to get current version number", _e);
|
||||
return "";
|
||||
}
|
||||
finally {
|
||||
IOUtils.closeQuietly(is);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
@DBSerializable
|
||||
public class MonitorConfig {
|
||||
private String host;
|
||||
private String authCode;
|
||||
private String username;
|
||||
private String password;
|
||||
private int hub;
|
||||
private boolean debug;
|
||||
private int connectTimeout;
|
||||
private int socketTimeout;
|
||||
private int updateInterval;
|
||||
|
||||
public MonitorConfig() {
|
||||
}
|
||||
|
||||
public MonitorConfig(int _hub, String _host) {
|
||||
hub = _hub;
|
||||
host = _host;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String _host) {
|
||||
host = _host;
|
||||
}
|
||||
|
||||
public String getAuthCode() {
|
||||
return authCode;
|
||||
}
|
||||
|
||||
public void setAuthCode(String _authCode) {
|
||||
authCode = _authCode;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String _username) {
|
||||
username = _username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String _password) {
|
||||
password = _password;
|
||||
}
|
||||
|
||||
public int getHub() {
|
||||
return hub;
|
||||
}
|
||||
|
||||
public void setHub(int _hub) {
|
||||
hub = _hub;
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
public void setDebug(boolean _debug) {
|
||||
debug = _debug;
|
||||
}
|
||||
|
||||
public int getConnectTimeout() {
|
||||
return connectTimeout == 0?3000:connectTimeout;
|
||||
}
|
||||
|
||||
public void setConnectTimeout(int _connectTimeout) {
|
||||
connectTimeout = _connectTimeout;
|
||||
}
|
||||
|
||||
public int getSocketTimeout() {
|
||||
return socketTimeout == 0?5000:socketTimeout;
|
||||
}
|
||||
|
||||
public void setSocketTimeout(int _socketTimeout) {
|
||||
socketTimeout = _socketTimeout;
|
||||
}
|
||||
|
||||
public int getUpdateInterval() {
|
||||
return updateInterval == 0?300:updateInterval;
|
||||
}
|
||||
|
||||
public void setUpdateInterval(int _updateInterval) {
|
||||
updateInterval = _updateInterval;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPower;
|
||||
|
||||
public interface PowerListener {
|
||||
void onPowerEvent(BreakerPower _power);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
public class PowerSample {
|
||||
public double voltage;
|
||||
public double current;
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package com.lanternsoftware.currentmonitor.bluetooth;
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import org.freedesktop.dbus.DBusPath;
|
||||
import org.freedesktop.dbus.interfaces.DBusInterface;
|
||||
import org.freedesktop.dbus.interfaces.Properties;
|
||||
import org.freedesktop.dbus.types.Variant;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class AbstractProperties implements Properties {
|
||||
protected final String interfaceName;
|
||||
protected final Map<String, Variant<?>> properties = new HashMap<>();
|
||||
|
||||
public AbstractProperties(Class<? extends DBusInterface> _bleClass) {
|
||||
interfaceName = _bleClass.getCanonicalName();
|
||||
}
|
||||
|
||||
public String getInterfaceName() {
|
||||
return interfaceName;
|
||||
}
|
||||
|
||||
public abstract DBusPath getPath();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <A> A Get(String _interface, String _propertyName) {
|
||||
if (NullUtils.isNotEqual(_interface, interfaceName))
|
||||
return null;
|
||||
Variant<?> var = properties.get(_propertyName);
|
||||
try {
|
||||
return (A) var.getValue();
|
||||
}
|
||||
catch (ClassCastException _e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <A> void Set(String _interface, String _propertyName, A _value) {
|
||||
if ((_value == null) || NullUtils.isNotEqual(_interface, interfaceName))
|
||||
return;
|
||||
properties.put(_propertyName, new Variant(_value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Variant<?>> GetAll(String _interfaceName) {
|
||||
if (NullUtils.isNotEqual(_interfaceName, getInterfaceName()))
|
||||
return new HashMap<>();
|
||||
return getProperties();
|
||||
}
|
||||
|
||||
public Map<String, Variant<?>> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public List<AbstractProperties> getAllObjects() {
|
||||
List<AbstractProperties> objects = new ArrayList<>();
|
||||
getAllObjects(objects);
|
||||
return objects;
|
||||
}
|
||||
|
||||
public void getAllObjects(List<AbstractProperties> _objects) {
|
||||
_objects.add(this);
|
||||
for (AbstractProperties o : CollectionUtils.makeNotNull(getChildObjects())) {
|
||||
o.getAllObjects(_objects);
|
||||
}
|
||||
}
|
||||
|
||||
public List<? extends AbstractProperties> getChildObjects() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<DBusPath, Map<String, Map<String, Variant<?>>>> getAllManagedObjects() {
|
||||
return getAllManagedObjects(getAllObjects());
|
||||
}
|
||||
|
||||
public static Map<DBusPath, Map<String, Map<String, Variant<?>>>> getAllManagedObjects(List<AbstractProperties> _objects) {
|
||||
Map<DBusPath, Map<String, Map<String, Variant<?>>>> objects = new HashMap<>();
|
||||
for (AbstractProperties o : _objects) {
|
||||
objects.put(o.getPath(), CollectionUtils.asHashMap(o.getInterfaceName(), o.getProperties()));
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package com.lanternsoftware.currentmonitor.bluetooth;
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import org.bluez.LEAdvertisement1;
|
||||
import org.bluez.LEAdvertisingManager1;
|
||||
import org.freedesktop.dbus.DBusPath;
|
||||
import org.freedesktop.dbus.interfaces.Properties;
|
||||
import org.freedesktop.dbus.types.Variant;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class BleAdvertisement extends AbstractProperties implements LEAdvertisement1, Properties {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BleAdvertisement.class);
|
||||
|
||||
private final LEAdvertisingManager1 advertiser;
|
||||
private final DBusPath advertisementPath;
|
||||
|
||||
public BleAdvertisement(String _name, BleApplication _app) {
|
||||
super(LEAdvertisement1.class);
|
||||
String[] serviceUUIDs = CollectionUtils.transform(_app.getServices(), _s->_s.getUuid().toString()).toArray(new String[0]);
|
||||
advertisementPath = new DBusPath(BleHelper.advertismentPath(_app.getName()));
|
||||
advertiser = BleHelper.getRemoteObject(BleHelper.getAdapter().getDbusPath(), LEAdvertisingManager1.class);
|
||||
properties.put("Type", new Variant<>("peripheral"));
|
||||
properties.put("ServiceUUIDs", new Variant<>(serviceUUIDs));
|
||||
properties.put("LocalName", new Variant<>(_name));
|
||||
properties.put("Includes", new Variant<>(new String[]{"tx-power"}));
|
||||
BleHelper.unExportObject(this);
|
||||
BleHelper.exportObject(this);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
try {
|
||||
advertiser.RegisterAdvertisement(advertisementPath, new HashMap<>());
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to register advertisement", _e);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
try {
|
||||
advertiser.UnregisterAdvertisement(advertisementPath);
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to unregister advertisement", _e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemote() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObjectPath() {
|
||||
return advertisementPath.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBusPath getPath() {
|
||||
return advertisementPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Release() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package com.lanternsoftware.currentmonitor.bluetooth;
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import org.bluez.GattApplication1;
|
||||
import org.bluez.GattManager1;
|
||||
import org.freedesktop.dbus.DBusPath;
|
||||
import org.freedesktop.dbus.interfaces.ObjectManager;
|
||||
import org.freedesktop.dbus.types.Variant;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BleApplication implements GattApplication1, ObjectManager {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BleApplication.class);
|
||||
|
||||
private final String name;
|
||||
private final DBusPath appPath;
|
||||
private final GattManager1 appManager;
|
||||
private final List<BleService> services;
|
||||
private final BleAdvertisement advertisement;
|
||||
|
||||
public BleApplication(String _name, String _advertisedName, BleService... _services) {
|
||||
this(_name, _advertisedName, CollectionUtils.asArrayList(_services));
|
||||
}
|
||||
|
||||
public BleApplication(String _name, String _advertisedName, List<BleService> _services) {
|
||||
name = _name;
|
||||
appPath = new DBusPath(BleHelper.applicationPath(_name));
|
||||
appManager = BleHelper.getRemoteObject(BleHelper.getAdapter().getDbusPath(), GattManager1.class);
|
||||
services = _services;
|
||||
advertisement = new BleAdvertisement(_advertisedName, this);
|
||||
List<AbstractProperties> objects = getManagedObjects();
|
||||
BleHelper.unExportObject(this);
|
||||
objects.forEach(BleHelper::unExportObject);
|
||||
BleHelper.exportObject(this);
|
||||
objects.forEach(BleHelper::exportObject);
|
||||
}
|
||||
|
||||
public List<AbstractProperties> getManagedObjects() {
|
||||
return CollectionUtils.aggregate(services, AbstractProperties::getAllObjects);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<BleService> getServices() {
|
||||
return services;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<DBusPath, Map<String, Map<String, Variant<?>>>> GetManagedObjects() {
|
||||
return AbstractProperties.getAllManagedObjects(getManagedObjects());
|
||||
}
|
||||
|
||||
public void start() {
|
||||
try {
|
||||
appManager.RegisterApplication(appPath, new HashMap<>());
|
||||
advertisement.start();
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to register application", _e);
|
||||
_e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
try {
|
||||
advertisement.stop();
|
||||
appManager.UnregisterApplication(appPath);
|
||||
BleHelper.connection.disconnect();
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to unregister application", _e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemote() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObjectPath() {
|
||||
return appPath.getPath();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package com.lanternsoftware.currentmonitor.bluetooth;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.CharacteristicFlag;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import org.bluez.GattCharacteristic1;
|
||||
import org.bluez.datatypes.TwoTuple;
|
||||
import org.freedesktop.dbus.DBusPath;
|
||||
import org.freedesktop.dbus.FileDescriptor;
|
||||
import org.freedesktop.dbus.types.UInt16;
|
||||
import org.freedesktop.dbus.types.Variant;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BleCharacteristic extends AbstractProperties implements GattCharacteristic1 {
|
||||
private final String charName;
|
||||
private final DBusPath charPath;
|
||||
private final UUID uuid;
|
||||
private final List<BleDescriptor> descriptors;
|
||||
private BleCharacteristicListener listener;
|
||||
|
||||
public BleCharacteristic(String _serviceName, UUID _uuid, String _characteristicName, Collection<CharacteristicFlag> _flags) {
|
||||
this(_serviceName, _uuid, _characteristicName, _flags, null);
|
||||
}
|
||||
|
||||
public BleCharacteristic(String _serviceName, UUID _uuid, String _characteristicName, Collection<CharacteristicFlag> _flags, List<BleDescriptor> _descriptors) {
|
||||
super(GattCharacteristic1.class);
|
||||
charName = _characteristicName;
|
||||
charPath = new DBusPath(BleHelper.characteristicPath(_serviceName, _characteristicName));
|
||||
uuid = _uuid;
|
||||
descriptors = _descriptors;
|
||||
properties.put("Service", new Variant<>(new DBusPath(BleHelper.servicePath(_serviceName))));
|
||||
if (uuid != null)
|
||||
properties.put("UUID", new Variant<>(uuid.toString()));
|
||||
if (CollectionUtils.isNotEmpty(_flags))
|
||||
properties.put("Flags", new Variant<>(CharacteristicFlag.toArray(_flags)));
|
||||
if (CollectionUtils.isNotEmpty(descriptors))
|
||||
properties.put("Descriptors", new Variant<>(BleHelper.toPaths(descriptors)));
|
||||
}
|
||||
|
||||
public void setListener(BleCharacteristicListener _listener) {
|
||||
listener = _listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends AbstractProperties> getChildObjects() {
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemote() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public DBusPath getPath() {
|
||||
return charPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObjectPath() {
|
||||
return charPath.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] ReadValue(Map<String, Variant<?>> _options) {
|
||||
if (listener == null)
|
||||
return null;
|
||||
int offset = 0;
|
||||
Variant<?> voffset = _options.get("offset");
|
||||
if (voffset != null) {
|
||||
if (voffset.getValue() instanceof UInt16)
|
||||
offset = ((UInt16)voffset.getValue()).intValue();
|
||||
}
|
||||
byte[] ret = listener.read(charName);
|
||||
if (ret == null)
|
||||
return null;
|
||||
return offset > 0?Arrays.copyOfRange(ret, offset, ret.length):ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void WriteValue(byte[] _bytes, Map<String, Variant<?>> _map) {
|
||||
if (listener != null)
|
||||
listener.write(charName, _bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TwoTuple<FileDescriptor, UInt16> AcquireWrite(Map<String, Variant<?>> _map) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TwoTuple<FileDescriptor, UInt16> AcquireNotify(Map<String, Variant<?>> _map) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void StartNotify() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void StopNotify() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Confirm() {
|
||||
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public List<BleDescriptor> getDescriptors() {
|
||||
return descriptors;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package com.lanternsoftware.currentmonitor.bluetooth;
|
||||
|
||||
public interface BleCharacteristicListener {
|
||||
void write(String _name, byte[] _value);
|
||||
byte[] read(String _name);
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.lanternsoftware.currentmonitor.bluetooth;
|
||||
|
||||
import org.bluez.GattDescriptor1;
|
||||
import org.freedesktop.dbus.DBusPath;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BleDescriptor extends AbstractProperties {
|
||||
private final DBusPath charPath;
|
||||
private final UUID uuid;
|
||||
|
||||
public BleDescriptor(String _serviceName, String _characteristicName, String _descriptorName, UUID _uuid) {
|
||||
super(GattDescriptor1.class);
|
||||
charPath = new DBusPath(BleHelper.descriptorPath(_serviceName, _characteristicName, _descriptorName));
|
||||
uuid = _uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBusPath getPath() {
|
||||
return charPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemote() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObjectPath() {
|
||||
return charPath.getPath();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package com.lanternsoftware.currentmonitor.bluetooth;
|
||||
|
||||
import com.github.hypfvieh.bluetooth.DeviceManager;
|
||||
import com.github.hypfvieh.bluetooth.wrapper.BluetoothAdapter;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import org.freedesktop.dbus.connections.impl.DBusConnection;
|
||||
import org.freedesktop.dbus.exceptions.DBusException;
|
||||
import org.freedesktop.dbus.interfaces.DBusInterface;
|
||||
import org.freedesktop.dbus.interfaces.Properties;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BleHelper {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BleHelper.class);
|
||||
|
||||
private static String basePath;
|
||||
private static final DeviceManager deviceManager;
|
||||
public static final DBusConnection connection;
|
||||
static {
|
||||
DeviceManager m = null;
|
||||
DBusConnection c = null;
|
||||
try {
|
||||
DeviceManager.createInstance(false);
|
||||
m = DeviceManager.getInstance();
|
||||
c = m.getDbusConnection();
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to get dbus connection", _e);
|
||||
}
|
||||
deviceManager = m;
|
||||
connection = c;
|
||||
}
|
||||
|
||||
public static void setBasePath(String _basePath) {
|
||||
basePath = _basePath;
|
||||
}
|
||||
|
||||
public static String getBasePath() {
|
||||
return basePath;
|
||||
}
|
||||
|
||||
public static String advertismentPath(String _advertisementName) {
|
||||
return BleHelper.getBasePath() + "/advertisement/" + _advertisementName;
|
||||
}
|
||||
|
||||
public static String applicationPath(String _appPath) {
|
||||
return BleHelper.getBasePath() + "/application/" + _appPath;
|
||||
}
|
||||
|
||||
public static String servicePath(String _serviceName) {
|
||||
return BleHelper.getBasePath() + "/service/" + _serviceName;
|
||||
}
|
||||
|
||||
public static String characteristicPath(String _serviceName, String _characteristicName) {
|
||||
return servicePath(_serviceName) + "/" + _characteristicName;
|
||||
}
|
||||
|
||||
public static String descriptorPath(String _serviceName, String _characteristicName, String _descriptorPath) {
|
||||
return servicePath(_serviceName) + "/" + _characteristicName + "/" + _descriptorPath;
|
||||
}
|
||||
|
||||
public static String[] toPaths(List<? extends AbstractProperties> _properties) {
|
||||
return CollectionUtils.transform(_properties, Properties::getObjectPath).toArray(new String[0]);
|
||||
}
|
||||
|
||||
public static BluetoothAdapter getAdapter() {
|
||||
return (deviceManager != null)?deviceManager.getAdapter():null;
|
||||
}
|
||||
|
||||
public static void requestBusName(String _name) {
|
||||
try {
|
||||
if (connection != null)
|
||||
connection.requestBusName(_name);
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to request bus name", _e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends DBusInterface> T getRemoteObject(String _path, Class<T> _objClass) {
|
||||
try {
|
||||
return connection.getRemoteObject("org.bluez", _path, _objClass);
|
||||
} catch (DBusException _e) {
|
||||
LOG.error("Failed to get remote object", _e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportObject(DBusInterface _object) {
|
||||
try {
|
||||
if (connection != null)
|
||||
connection.exportObject(_object.getObjectPath(), _object);
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to export object", _e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void unExportObject(DBusInterface _object) {
|
||||
if (_object != null)
|
||||
unExportObject(_object.getObjectPath());
|
||||
}
|
||||
|
||||
public static void unExportObject(String _objectPath) {
|
||||
try {
|
||||
if (connection != null)
|
||||
connection.unExportObject(_objectPath);
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to unexport object", _e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.lanternsoftware.currentmonitor.bluetooth;
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import org.bluez.GattService1;
|
||||
import org.freedesktop.dbus.DBusPath;
|
||||
import org.freedesktop.dbus.types.Variant;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
public class BleService extends AbstractProperties implements GattService1 {
|
||||
private final DBusPath servicePath;
|
||||
private final UUID uuid;
|
||||
private final List<BleCharacteristic> characteristics;
|
||||
|
||||
public BleService(String _serviceName, UUID _uuid, List<BleCharacteristic> _characteristics) {
|
||||
super(GattService1.class);
|
||||
servicePath = new DBusPath(BleHelper.servicePath(_serviceName));
|
||||
uuid = _uuid;
|
||||
characteristics = _characteristics;
|
||||
if (uuid != null)
|
||||
properties.put("UUID", new Variant<>(uuid.toString()));
|
||||
properties.put("Primary", new Variant<>(Boolean.TRUE));
|
||||
if (CollectionUtils.isNotEmpty(characteristics))
|
||||
properties.put("Characteristics", new Variant<>(BleHelper.toPaths(characteristics)));
|
||||
}
|
||||
|
||||
public DBusPath getPath() {
|
||||
return servicePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemote() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObjectPath() {
|
||||
return getPath().getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends AbstractProperties> getChildObjects() {
|
||||
return characteristics;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public List<BleCharacteristic> getCharacteristics() {
|
||||
return characteristics;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.lanternsoftware.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.MonitorConfig;
|
||||
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 MonitorConfigSerializer extends AbstractDaoSerializer<MonitorConfig>
|
||||
{
|
||||
@Override
|
||||
public Class<MonitorConfig> getSupportedClass()
|
||||
{
|
||||
return MonitorConfig.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(MonitorConfig _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("host", _o.getHost());
|
||||
d.put("auth_code", _o.getAuthCode());
|
||||
d.put("username", _o.getUsername());
|
||||
d.put("password", _o.getPassword());
|
||||
d.put("hub", _o.getHub());
|
||||
d.put("debug", _o.isDebug());
|
||||
d.put("socket_timeout", _o.getSocketTimeout());
|
||||
d.put("connect_timeout", _o.getConnectTimeout());
|
||||
d.put("update_interval", _o.getUpdateInterval());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MonitorConfig fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
MonitorConfig o = new MonitorConfig();
|
||||
o.setHost(DaoSerializer.getString(_d, "host"));
|
||||
o.setAuthCode(DaoSerializer.getString(_d, "auth_code"));
|
||||
o.setUsername(DaoSerializer.getString(_d, "username"));
|
||||
o.setPassword(DaoSerializer.getString(_d, "password"));
|
||||
o.setHub(DaoSerializer.getInteger(_d, "hub"));
|
||||
o.setDebug(DaoSerializer.getBoolean(_d, "debug"));
|
||||
o.setSocketTimeout(DaoSerializer.getInteger(_d, "socket_timeout"));
|
||||
o.setConnectTimeout(DaoSerializer.getInteger(_d, "connect_timeout"));
|
||||
o.setUpdateInterval(DaoSerializer.getInteger(_d, "update_interval"));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.lanternsoftware.currentmonitor.led;
|
||||
|
||||
import com.lanternsoftware.util.concurrency.ConcurrencyUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class LEDFlasher implements Runnable {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(LEDFlasher.class);
|
||||
|
||||
private final AtomicBoolean running = new AtomicBoolean(true);
|
||||
private boolean on = false;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (running.get()) {
|
||||
on = !on;
|
||||
setLEDOn(on);
|
||||
ConcurrencyUtils.sleep(250);
|
||||
}
|
||||
setLEDOn(false);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
running.set(false);
|
||||
}
|
||||
|
||||
public static void setLEDOn(boolean _on) {
|
||||
try {
|
||||
if (_on)
|
||||
Runtime.getRuntime().exec(new String[]{"sh", "-c", "echo default-on > /sys/class/leds/led1/trigger"});
|
||||
else
|
||||
Runtime.getRuntime().exec(new String[]{"sh", "-c", "echo none > /sys/class/leds/led1/trigger"});
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to change LED state", _e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.lanternsoftware.currentmonitor.util;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.NetworkStatus;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class NetworkMonitor {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(NetworkMonitor.class);
|
||||
|
||||
private static final Pattern ethernetPattern = Pattern.compile(".*(eth[0-9]):(.*)");
|
||||
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));
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to check network state", _e);
|
||||
}
|
||||
finally {
|
||||
IOUtils.closeQuietly(is);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
private static List<String> getIPs(String _ifConfig, Pattern _pattern) {
|
||||
List<String> ips = new ArrayList<>();
|
||||
Matcher m = _pattern.matcher(_ifConfig);
|
||||
while (m.find()) {
|
||||
int start = m.start(0);
|
||||
int ipStart = _ifConfig.indexOf("inet ", start) + 5;
|
||||
if (ipStart > 4) {
|
||||
int ipEnd = _ifConfig.indexOf(" ", ipStart);
|
||||
if (ipEnd > -1)
|
||||
ips.add(_ifConfig.substring(ipStart, ipEnd));
|
||||
}
|
||||
}
|
||||
return ips;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.lanternsoftware.currentmonitor.wifi;
|
||||
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public abstract class WifiConfig {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WifiConfig.class);
|
||||
|
||||
private static final String WIFI_CONFIG_PATH = "/etc/wpa_supplicant/wpa_supplicant.conf";
|
||||
private static final String CONF_FORMAT = "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\nupdate_config=1\ncountry=US\nnetwork={\n\tssid=\"%s\"\n\t%s\n}\n";
|
||||
|
||||
public static void setCredentials(String _ssid, String _password) {
|
||||
String[] commands = {"wpa_passphrase", _ssid, _password};
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = Runtime.getRuntime().exec(commands).getInputStream();
|
||||
String newConf = IOUtils.toString(is);
|
||||
if (newConf == null)
|
||||
return;
|
||||
int idx = newConf.indexOf("psk=");
|
||||
if (idx > 0) {
|
||||
if (newConf.charAt(idx-1) == '#')
|
||||
idx = newConf.indexOf("psk=", idx+1);
|
||||
if (idx > 0) {
|
||||
int endIdx = newConf.indexOf("\n", idx);
|
||||
if (endIdx > 0) {
|
||||
String finalConf = String.format(CONF_FORMAT, _ssid, newConf.substring(idx, endIdx));
|
||||
ResourceLoader.writeFile(WIFI_CONFIG_PATH, finalConf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception _e) {
|
||||
LOG.error("Failed to write wifi credentials", _e);
|
||||
}
|
||||
finally {
|
||||
IOUtils.closeQuietly(is);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package org.bluez;
|
||||
|
||||
import org.freedesktop.dbus.interfaces.DBusInterface;
|
||||
|
||||
public interface GattApplication1 extends DBusInterface {
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
com.lanternsoftware.currentmonitor.dao.MonitorConfigSerializer
|
|
@ -0,0 +1,28 @@
|
|||
<?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>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>/opt/currentmonitor/log/log.txt</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>/opt/currentmonitor/log/log.%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
<maxHistory>20</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="com.lanternsoftware" level="INFO"/>
|
||||
|
||||
<root level="OFF">
|
||||
<appender-ref ref="FILE"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,15 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
|
||||
public class CreateConfig {
|
||||
public static void main(String[] args) {
|
||||
// MonitorConfig c = new MonitorConfig(0, "https://mark.lanternsoftware.com/currentmonitor");
|
||||
MonitorConfig c = new MonitorConfig(1, "https://mark.lanternsoftware.com/currentmonitor");
|
||||
c.setDebug(true);
|
||||
ResourceLoader.writeFile(LanternFiles.OPS_PATH + "hub1.json", DaoSerializer.toJson(c));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.cryptography.AESTool;
|
||||
|
||||
public class CreateSSIDKey {
|
||||
public static void main(String[] args) {
|
||||
AESTool.printRandomSecretKey();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.generator.DaoSerializerGenerator;
|
||||
|
||||
public class CurrentMonitorAppSerializers {
|
||||
public static void main(String[] args) {
|
||||
DaoSerializerGenerator.generateSerializers(LanternFiles.SOURCE_PATH + "currentmonitor", true, null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.util.NetworkMonitor;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.NetworkStatus;
|
||||
|
||||
public class NetworkTest {
|
||||
public static void main(String[] args) {
|
||||
NetworkStatus status = NetworkMonitor.getNetworkStatus();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.xml.XmlNode;
|
||||
import com.lanternsoftware.util.xml.XmlParser;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
public class ReleaseCurrentMonitor {
|
||||
public static void main(String[] args) {
|
||||
XmlNode pom = XmlParser.loadXmlFile(LanternFiles.SOURCE_PATH + "currentmonitor" + File.separator + "lantern-currentmonitor" + File.separator + "pom.xml");
|
||||
if (pom == null)
|
||||
return;
|
||||
XmlNode versionNode = pom.getChild(Collections.singletonList("version"));
|
||||
String version = versionNode.getContent();
|
||||
ProcessBuilder builder = new ProcessBuilder();
|
||||
builder.directory(new File(LanternFiles.SOURCE_PATH));
|
||||
builder.command("cmd.exe", "/c", "mvn clean install");
|
||||
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
||||
try {
|
||||
Process process = builder.start();
|
||||
int exitCode = process.waitFor();
|
||||
assert exitCode == 0;
|
||||
} catch (Exception _e) {
|
||||
_e.printStackTrace();
|
||||
}
|
||||
byte[] jar = ResourceLoader.loadFile(LanternFiles.SOURCE_PATH + "currentmonitor" + File.separator + "lantern-currentmonitor" + File.separator + "target" + File.separator + "lantern-currentmonitor.jar");
|
||||
DaoEntity meta = new DaoEntity("version", version).and("size", jar.length).and("checksum", DigestUtils.md5Hex(jar));
|
||||
ResourceLoader.writeFile(LanternFiles.OPS_PATH + "release" + File.separator + "lantern-currentmonitor.jar", jar);
|
||||
ResourceLoader.writeFile(LanternFiles.OPS_PATH + "release" + File.separator + "version.json", DaoSerializer.toJson(meta));
|
||||
}
|
||||
}
|
83
currentmonitor/lantern-dataaccess-currentmonitor/pom.xml
Normal file
83
currentmonitor/lantern-dataaccess-currentmonitor/pom.xml
Normal file
|
@ -0,0 +1,83 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.lanternsoftware.currentmonitor</groupId>
|
||||
<artifactId>lantern-dataaccess-currentmonitor</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0.0</version>
|
||||
<name>lantern-dataaccess-currentmonitor</name>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.lanternsoftware.currentmonitor</groupId>
|
||||
<artifactId>lantern-datamodel-currentmonitor</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.lanternsoftware.util</groupId>
|
||||
<artifactId>lantern-util-dao-mongo</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mindrot</groupId>
|
||||
<artifactId>jbcrypt</artifactId>
|
||||
<version>0.4</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
<phase>compile</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<optimize>true</optimize>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<index>true</index>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,45 @@
|
|||
package com.lanternsoftware.dataaccess.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Account;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroupEnergy;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPower;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.EnergyBlockViewMode;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.HubPowerMinute;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoProxy;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public interface CurrentMonitorDao {
|
||||
void shutdown();
|
||||
|
||||
void putBreakerPower(BreakerPower _current);
|
||||
List<BreakerPower> getBreakerPowerForAccount(int _accountId);
|
||||
BreakerPower getLatestBreakerPower(int _accountId, int _hub, int _port);
|
||||
BreakerGroupEnergy getBreakerGroupEnergy(int _accountId, String _groupId, EnergyBlockViewMode _viewMode, Date _start);
|
||||
void putBreakerGroupEnergy(BreakerGroupEnergy _energy);
|
||||
|
||||
void putHubPowerMinute(HubPowerMinute _power);
|
||||
|
||||
BreakerConfig getConfig(int _accountId);
|
||||
BreakerConfig getMergedConfig(AuthCode _authCode);
|
||||
void putConfig(BreakerConfig _config);
|
||||
|
||||
void updateSummaries(BreakerGroup _rootGroup, Set<Date> _daysToSummarize, TimeZone _tz);
|
||||
|
||||
String authenticateAccount(String _username, String _password);
|
||||
String getAuthCodeForEmail(String _email);
|
||||
Account authCodeToAccount(String _authCode);
|
||||
AuthCode decryptAuthCode(String _authCode);
|
||||
|
||||
Account putAccount(Account _account);
|
||||
Account getAccount(int _accountId);
|
||||
Account getAccountByUsername(String _username);
|
||||
|
||||
MongoProxy getProxy();
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package com.lanternsoftware.dataaccess.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@DBSerializable(autogen = false)
|
||||
public class DirtyMinute {
|
||||
private int accountId;
|
||||
private int minute;
|
||||
private Date posted;
|
||||
|
||||
public DirtyMinute() {
|
||||
}
|
||||
|
||||
public DirtyMinute(int _accountId, int _minute, Date _posted) {
|
||||
accountId = _accountId;
|
||||
minute = _minute;
|
||||
posted = _posted;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return accountId + "-" + minute;
|
||||
}
|
||||
|
||||
public int getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(int _accountId) {
|
||||
accountId = _accountId;
|
||||
}
|
||||
|
||||
public Date getMinuteAsDate() {
|
||||
return new Date(((long)minute)*60000);
|
||||
}
|
||||
|
||||
public int getMinute() {
|
||||
return minute;
|
||||
}
|
||||
|
||||
public void setMinute(int _minute) {
|
||||
minute = _minute;
|
||||
}
|
||||
|
||||
public void setMinute(Date _minute) {
|
||||
minute = (int)(_minute.getTime()/60000);
|
||||
}
|
||||
|
||||
public Date getPosted() {
|
||||
return posted;
|
||||
}
|
||||
|
||||
public void setPosted(Date _posted) {
|
||||
posted = _posted;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,273 @@
|
|||
package com.lanternsoftware.dataaccess.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Account;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroupEnergy;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroupSummary;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPower;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.EnergyBlockViewMode;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.HubPowerMinute;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Sequence;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.DateUtils;
|
||||
import com.lanternsoftware.util.DebugTimer;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.cryptography.AESTool;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
import com.lanternsoftware.util.dao.DaoQuery;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.DaoSort;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoProxy;
|
||||
import org.mindrot.jbcrypt.BCrypt;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class MongoCurrentMonitorDao implements CurrentMonitorDao {
|
||||
private static final Logger logger = LoggerFactory.getLogger(MongoCurrentMonitorDao.class);
|
||||
private static final AESTool aes = new AESTool(ResourceLoader.loadFile(LanternFiles.OPS_PATH + "authKey.dat"));
|
||||
private static final int BCRYPT_ROUNDS = 11;
|
||||
private final Timer delayTimer = new Timer();
|
||||
private final ExecutorService executor = Executors.newCachedThreadPool();
|
||||
|
||||
private final MongoProxy proxy;
|
||||
|
||||
public MongoCurrentMonitorDao(MongoConfig _config) {
|
||||
proxy = new MongoProxy(_config);
|
||||
proxy.ensureIndex(BreakerPower.class, DaoSort.sort("account_id").then("key"));
|
||||
proxy.ensureIndex(HubPowerMinute.class, DaoSort.sort("account_id").then("minute"));
|
||||
proxy.ensureIndex(BreakerGroupEnergy.class, DaoSort.sort("account_id").then("group_id").then("view_mode"));
|
||||
proxy.ensureIndex(BreakerGroupSummary.class, DaoSort.sort("account_id").then("group_id").then("view_mode"));
|
||||
proxy.ensureIndex(DirtyMinute.class, DaoSort.sort("posted"));
|
||||
for (DirtyMinute minute : proxy.queryAll(DirtyMinute.class)) {
|
||||
updateSummaries(minute);
|
||||
}
|
||||
proxy.delete(DirtyMinute.class, new DaoQuery());
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
delayTimer.cancel();
|
||||
executor.shutdownNow();
|
||||
proxy.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBreakerPower(BreakerPower _power) {
|
||||
proxy.save(_power);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putHubPowerMinute(HubPowerMinute _power) {
|
||||
if (_power == null)
|
||||
return;
|
||||
proxy.save(_power);
|
||||
DirtyMinute minute = new DirtyMinute(_power.getAccountId(), _power.getMinute(), new Date());
|
||||
proxy.save(minute);
|
||||
delayTimer.schedule(new TimerTask(){
|
||||
@Override
|
||||
public void run() {
|
||||
executor.submit(()->{
|
||||
if (proxy.queryOneAndDelete(DirtyMinute.class, new DaoQuery("_id", minute.getId())) != null)
|
||||
updateSummaries(new DirtyMinute(_power.getAccountId(), _power.getMinute(), new Date()));
|
||||
});
|
||||
}
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
private void updateSummaries(DirtyMinute _minute) {
|
||||
DebugTimer timer = new DebugTimer("Updating summaries", logger);
|
||||
List<HubPowerMinute> minutes = proxy.query(HubPowerMinute.class, new DaoQuery("account_id", _minute.getAccountId()).and("minute", _minute.getMinute()));
|
||||
TimeZone tz = TimeZone.getTimeZone("America/Chicago");
|
||||
BreakerConfig config = getConfig(_minute.getAccountId());
|
||||
BreakerGroup group = CollectionUtils.getFirst(config.getBreakerGroups());
|
||||
Date day = DateUtils.getMidnightBefore(_minute.getMinuteAsDate(), tz);
|
||||
BreakerGroupEnergy summary = getBreakerGroupEnergy(_minute.getAccountId(), group.getId(), EnergyBlockViewMode.DAY, day);
|
||||
if (summary == null)
|
||||
summary = new BreakerGroupEnergy(group, minutes, EnergyBlockViewMode.DAY, day, tz);
|
||||
else
|
||||
summary.addEnergy(group, minutes, tz);
|
||||
putBreakerGroupEnergy(summary);
|
||||
updateSummaries(group, CollectionUtils.asHashSet(day), tz);
|
||||
timer.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BreakerPower> getBreakerPowerForAccount(int _accountId) {
|
||||
return proxy.query(BreakerPower.class, new DaoQuery("account_id", _accountId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerPower getLatestBreakerPower(int _accountId, int _panel, int _space) {
|
||||
return proxy.queryOne(BreakerPower.class, new DaoQuery("account_id", _accountId).and("key", Breaker.key(_panel, _space)), DaoSort.sortDesc("read_time"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerGroupEnergy getBreakerGroupEnergy(int _accountId, String _groupId, EnergyBlockViewMode _viewMode, Date _start) {
|
||||
return proxy.queryOne(BreakerGroupEnergy.class, new DaoQuery("_id", BreakerGroupEnergy.toId(_accountId, _groupId, _viewMode, _start)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSummaries(BreakerGroup _rootGroup, Set<Date> _daysToSummarize, TimeZone _tz) {
|
||||
Set<Date> monthsToSummarize = CollectionUtils.transformToSet(_daysToSummarize, _c -> DateUtils.getStartOfMonth(_c, _tz));
|
||||
Set<Date> yearsToSummarize = CollectionUtils.transformToSet(monthsToSummarize, _c -> DateUtils.getStartOfYear(_c, _tz));
|
||||
for (Date month : monthsToSummarize) {
|
||||
Calendar calDayStart = DateUtils.toCalendar(month, _tz);
|
||||
Calendar end = DateUtils.getEndOfMonthCal(month, _tz);
|
||||
List<String> groupEnergyIds = new ArrayList<>();
|
||||
while (calDayStart.before(end)) {
|
||||
groupEnergyIds.add(BreakerGroupEnergy.toId(_rootGroup.getAccountId(), _rootGroup.getId(), EnergyBlockViewMode.DAY, calDayStart.getTime()));
|
||||
calDayStart.add(Calendar.DAY_OF_YEAR, 1);
|
||||
}
|
||||
List<BreakerGroupSummary> groupEnergies = CollectionUtils.aggregate(proxy.query(BreakerGroupSummary.class, DaoQuery.in("_id", groupEnergyIds)), BreakerGroupSummary::getAllGroups);
|
||||
Map<String, List<BreakerGroupSummary>> energies = CollectionUtils.transformToMultiMap(groupEnergies, BreakerGroupSummary::getGroupId);
|
||||
BreakerGroupEnergy summary = BreakerGroupEnergy.summary(_rootGroup, energies, EnergyBlockViewMode.MONTH, month, _tz);
|
||||
putBreakerGroupEnergy(summary);
|
||||
}
|
||||
for (Date year : yearsToSummarize) {
|
||||
Calendar calMonthStart = DateUtils.toCalendar(year, _tz);
|
||||
Calendar end = DateUtils.getEndOfYearCal(year, _tz);
|
||||
List<String> groupEnergyIds = new ArrayList<>();
|
||||
while (calMonthStart.before(end)) {
|
||||
groupEnergyIds.add(BreakerGroupEnergy.toId(_rootGroup.getAccountId(), _rootGroup.getId(), EnergyBlockViewMode.MONTH, calMonthStart.getTime()));
|
||||
calMonthStart.add(Calendar.DAY_OF_YEAR, 1);
|
||||
}
|
||||
List<BreakerGroupSummary> groupEnergies = CollectionUtils.aggregate(proxy.query(BreakerGroupSummary.class, DaoQuery.in("_id", groupEnergyIds)), BreakerGroupSummary::getAllGroups);
|
||||
Map<String, List<BreakerGroupSummary>> energies = CollectionUtils.transformToMultiMap(groupEnergies, BreakerGroupSummary::getGroupId);
|
||||
BreakerGroupEnergy summary = BreakerGroupEnergy.summary(_rootGroup, energies, EnergyBlockViewMode.YEAR, year, _tz);
|
||||
putBreakerGroupEnergy(summary);
|
||||
}
|
||||
List<BreakerGroupSummary> groupEnergies = CollectionUtils.aggregate(proxy.query(BreakerGroupSummary.class, new DaoQuery("group_id", _rootGroup.getId()).and("view_mode", EnergyBlockViewMode.YEAR.name())), BreakerGroupSummary::getAllGroups);
|
||||
Map<String, List<BreakerGroupSummary>> energies = CollectionUtils.transformToMultiMap(groupEnergies, BreakerGroupSummary::getGroupId);
|
||||
BreakerGroupEnergy summary = BreakerGroupEnergy.summary(_rootGroup, energies, EnergyBlockViewMode.ALL, new Date(0), _tz);
|
||||
putBreakerGroupEnergy(summary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBreakerGroupEnergy(BreakerGroupEnergy _energy) {
|
||||
proxy.save(_energy);
|
||||
proxy.save(new BreakerGroupSummary(_energy));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerConfig getConfig(int _accountId) {
|
||||
return proxy.queryOne(BreakerConfig.class, new DaoQuery("_id", String.valueOf(_accountId)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerConfig getMergedConfig(AuthCode _authCode) {
|
||||
if (_authCode == null)
|
||||
return null;
|
||||
List<BreakerConfig> configs = CollectionUtils.transform(_authCode.getAllAccountIds(), this::getConfig, true);
|
||||
BreakerConfig config = new BreakerConfig();
|
||||
config.setAccountId(_authCode.getAccountId());
|
||||
config.setBreakerHubs(CollectionUtils.aggregate(configs, BreakerConfig::getBreakerHubs));
|
||||
config.setBreakerGroups(CollectionUtils.aggregate(configs, BreakerConfig::getBreakerGroups));
|
||||
config.setPanels(CollectionUtils.aggregate(configs, BreakerConfig::getPanels));
|
||||
config.setMeters(CollectionUtils.aggregate(configs, BreakerConfig::getMeters));
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putConfig(BreakerConfig _config) {
|
||||
DaoQuery configQuery = new DaoQuery("_id", String.valueOf(_config.getAccountId()));
|
||||
BreakerConfig oldConfig = proxy.queryOne(BreakerConfig.class, configQuery);
|
||||
if (oldConfig != null)
|
||||
proxy.delete(BreakerGroup.class, DaoQuery.in("_id", oldConfig.getAllBreakerGroupIds()));
|
||||
proxy.save(_config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String authenticateAccount(String _username, String _password) {
|
||||
Account acct = proxy.queryOne(Account.class, new DaoQuery("username", _username));
|
||||
if ((acct == null) || !BCrypt.checkpw(_password, acct.getPassword()))
|
||||
return null;
|
||||
return aes.encryptToBase64(DaoSerializer.toZipBson(new AuthCode(acct.getId(), acct.getAuxiliaryAccountIds())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account authCodeToAccount(String _authCode) {
|
||||
AuthCode code = decryptAuthCode(_authCode);
|
||||
if (code == null)
|
||||
return null;
|
||||
return proxy.queryOne(Account.class, new DaoQuery("_id", code.getAccountId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthCode decryptAuthCode(String _authCode) {
|
||||
return DaoSerializer.fromZipBson(aes.decryptFromBase64(_authCode), AuthCode.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthCodeForEmail(String _email) {
|
||||
_email = _email.toLowerCase().trim();
|
||||
Account account = getAccountByUsername(_email);
|
||||
if (account == null) {
|
||||
account = new Account();
|
||||
account.setUsername(_email);
|
||||
putAccount(account);
|
||||
}
|
||||
return aes.encryptToBase64(DaoSerializer.toZipBson(new AuthCode(account.getId(), account.getAuxiliaryAccountIds())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account putAccount(Account _account) {
|
||||
if (_account == null)
|
||||
return null;
|
||||
_account.setUsername(NullUtils.makeNotNull(_account.getUsername()).toLowerCase().trim());
|
||||
Account account = getAccountByUsername(_account.getUsername());
|
||||
if (account != null) {
|
||||
_account.setId(account.getId());
|
||||
if (NullUtils.isEmpty(_account.getPassword()))
|
||||
_account.setPassword(account.getPassword());
|
||||
else
|
||||
_account.setPassword(BCrypt.hashpw(_account.getPassword(), BCrypt.gensalt(BCRYPT_ROUNDS)));
|
||||
}
|
||||
else if (NullUtils.isNotEmpty(_account.getPassword())) {
|
||||
_account.setPassword(BCrypt.hashpw(_account.getPassword(), BCrypt.gensalt(BCRYPT_ROUNDS)));
|
||||
}
|
||||
if (_account.getId() == 0)
|
||||
_account.setId(proxy.updateOne(Sequence.class, null, new DaoEntity("$inc", new DaoEntity("sequence", 1))).getSequence());
|
||||
proxy.save(_account);
|
||||
return clearPassword(_account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account getAccount(int _accountId) {
|
||||
return clearPassword(proxy.queryOne(Account.class, new DaoQuery("_id", String.valueOf(_accountId))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account getAccountByUsername(String _username) {
|
||||
return clearPassword(proxy.queryOne(Account.class, new DaoQuery("username", NullUtils.makeNotNull(_username).toLowerCase().trim())));
|
||||
}
|
||||
|
||||
private Account clearPassword(Account _account) {
|
||||
if (_account == null)
|
||||
return null;
|
||||
_account.setPassword(null);
|
||||
return _account;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoProxy getProxy() {
|
||||
return proxy;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.lanternsoftware.dataaccess.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.DirtyMinute;
|
||||
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 DirtyMinuteSerializer extends AbstractDaoSerializer<DirtyMinute>
|
||||
{
|
||||
@Override
|
||||
public Class<DirtyMinute> getSupportedClass()
|
||||
{
|
||||
return DirtyMinute.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(DirtyMinute _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("_id", _o.getId());
|
||||
d.put("account_id", _o.getAccountId());
|
||||
d.put("minute", _o.getMinute());
|
||||
d.put("posted", DaoSerializer.toLong(_o.getPosted()));
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DirtyMinute fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
DirtyMinute o = new DirtyMinute();
|
||||
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
|
||||
o.setMinute(DaoSerializer.getInteger(_d, "minute"));
|
||||
o.setPosted(DaoSerializer.getDate(_d, "posted"));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
com.lanternsoftware.dataaccess.currentmonitor.dao.DirtyMinuteSerializer
|
73
currentmonitor/lantern-datamodel-currentmonitor/pom.xml
Normal file
73
currentmonitor/lantern-datamodel-currentmonitor/pom.xml
Normal file
|
@ -0,0 +1,73 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.lanternsoftware.currentmonitor</groupId>
|
||||
<artifactId>lantern-datamodel-currentmonitor</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0.0</version>
|
||||
<name>lantern-datamodel-currentmonitor</name>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.lanternsoftware.util</groupId>
|
||||
<artifactId>lantern-util-dao</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
<phase>compile</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<optimize>true</optimize>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<index>true</index>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,46 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
import com.lanternsoftware.util.dao.annotations.PrimaryKey;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@DBSerializable(autogen = false)
|
||||
public class Account {
|
||||
@PrimaryKey private int id;
|
||||
private String username;
|
||||
private String password;
|
||||
private List<Integer> auxiliaryAccountIds;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int _id) {
|
||||
id = _id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String _username) {
|
||||
username = _username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String _password) {
|
||||
password = _password;
|
||||
}
|
||||
|
||||
public List<Integer> getAuxiliaryAccountIds() {
|
||||
return auxiliaryAccountIds;
|
||||
}
|
||||
|
||||
public void setAuxiliaryAccountIds(List<Integer> _auxiliaryAccountIds) {
|
||||
auxiliaryAccountIds = _auxiliaryAccountIds;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@DBSerializable(autogen = false)
|
||||
public class AuthCode {
|
||||
private int accountId;
|
||||
private List<Integer> auxiliaryAccountIds;
|
||||
|
||||
public AuthCode() {
|
||||
}
|
||||
|
||||
public AuthCode(int _accountId, List<Integer> _auxiliaryAccountIds) {
|
||||
accountId = _accountId;
|
||||
auxiliaryAccountIds = _auxiliaryAccountIds;
|
||||
}
|
||||
|
||||
public int getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(int _accountId) {
|
||||
accountId = _accountId;
|
||||
}
|
||||
|
||||
public List<Integer> getAuxiliaryAccountIds() {
|
||||
return auxiliaryAccountIds;
|
||||
}
|
||||
|
||||
public void setAuxiliaryAccountIds(List<Integer> _auxiliaryAccountIds) {
|
||||
auxiliaryAccountIds = _auxiliaryAccountIds;
|
||||
}
|
||||
|
||||
public List<Integer> getAllAccountIds() {
|
||||
List<Integer> ids = new ArrayList<>();
|
||||
ids.add(accountId);
|
||||
if (auxiliaryAccountIds != null)
|
||||
ids.addAll(auxiliaryAccountIds);
|
||||
return ids;
|
||||
}
|
||||
|
||||
public boolean isAuthorized(int _accountId) {
|
||||
return accountId == _accountId || CollectionUtils.contains(auxiliaryAccountIds, _accountId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,232 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
@DBSerializable()
|
||||
public class Breaker {
|
||||
private static final int TANDEM_BREAKER_MASK = 3072;
|
||||
private static final int SPACE_MASK = 1023;
|
||||
private static final int TANDEM_BREAKER_A_MASK = 1024;
|
||||
private static final int TANDEM_BREAKER_B_MASK = 2048;
|
||||
|
||||
private int panel;
|
||||
private int space;
|
||||
private int meter;
|
||||
private int hub;
|
||||
private int port;
|
||||
private String name;
|
||||
private String description;
|
||||
private int sizeAmps;
|
||||
private double calibrationFactor;
|
||||
private double lowPassFilter;
|
||||
private BreakerPolarity polarity;
|
||||
private BreakerType type;
|
||||
private transient String key;
|
||||
|
||||
public Breaker() {
|
||||
}
|
||||
|
||||
public Breaker(String _name, int _panel, int _space, int _hub, int _port, int _sizeAmps, double _lowPassFilter) {
|
||||
name = _name;
|
||||
panel = _panel;
|
||||
space = _space;
|
||||
hub = _hub;
|
||||
port = _port;
|
||||
sizeAmps = _sizeAmps;
|
||||
lowPassFilter = _lowPassFilter;
|
||||
}
|
||||
|
||||
public int getPanel() {
|
||||
return panel;
|
||||
}
|
||||
|
||||
public void setPanel(int _panel) {
|
||||
panel = _panel;
|
||||
key = null;
|
||||
}
|
||||
|
||||
public int getSpace() {
|
||||
return space;
|
||||
}
|
||||
|
||||
public void setSpace(int _space) {
|
||||
space = _space;
|
||||
key = null;
|
||||
}
|
||||
|
||||
public int getMeter() {
|
||||
return meter;
|
||||
}
|
||||
|
||||
public void setMeter(int _meter) {
|
||||
meter = _meter;
|
||||
}
|
||||
|
||||
public String getSpaceDisplay() {
|
||||
return toSpaceDisplay(space);
|
||||
}
|
||||
|
||||
public void setSpaceTandemA(int _space) {
|
||||
space = TANDEM_BREAKER_A_MASK | _space;
|
||||
}
|
||||
|
||||
public void setSpaceTandemB(int _space) {
|
||||
space = TANDEM_BREAKER_B_MASK | _space;
|
||||
}
|
||||
|
||||
public boolean isTandemBreaker() {
|
||||
return (TANDEM_BREAKER_MASK & space) != 0;
|
||||
}
|
||||
|
||||
public boolean isTandemBreakerA() {
|
||||
return isTandemBreakerA(space);
|
||||
}
|
||||
|
||||
public boolean isTandemBreakerB() {
|
||||
return isTandemBreakerB(space);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String _name) {
|
||||
name = _name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String _description) {
|
||||
description = _description;
|
||||
}
|
||||
|
||||
public int getHub() {
|
||||
return hub;
|
||||
}
|
||||
|
||||
public void setHub(int _hub) {
|
||||
hub = _hub;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int _port) {
|
||||
port = _port;
|
||||
}
|
||||
|
||||
public int getChip() {
|
||||
return portToChip(port);
|
||||
}
|
||||
|
||||
public int getPin() {
|
||||
return portToPin(port);
|
||||
}
|
||||
|
||||
public int getSizeAmps() {
|
||||
return sizeAmps;
|
||||
}
|
||||
|
||||
public void setSizeAmps(int _sizeAmps) {
|
||||
sizeAmps = _sizeAmps;
|
||||
}
|
||||
|
||||
public double getLowPassFilter() {
|
||||
return lowPassFilter;
|
||||
}
|
||||
|
||||
public void setLowPassFilter(double _lowPassFilter) {
|
||||
lowPassFilter = _lowPassFilter;
|
||||
}
|
||||
|
||||
public BreakerPolarity getPolarity() {
|
||||
return polarity;
|
||||
}
|
||||
|
||||
public void setPolarity(BreakerPolarity _polarity) {
|
||||
polarity = _polarity;
|
||||
}
|
||||
|
||||
public double getCalibrationFactor() {
|
||||
return calibrationFactor == 0.0?1.0:calibrationFactor;
|
||||
}
|
||||
|
||||
public void setCalibrationFactor(double _calibrationFactor) {
|
||||
calibrationFactor = _calibrationFactor;
|
||||
}
|
||||
|
||||
public BreakerType getType() {
|
||||
if (type == null) {
|
||||
if (isTandemBreaker())
|
||||
return BreakerType.SINGLE_POLE_TANDEM;
|
||||
return BreakerType.SINGLE_POLE;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(BreakerType _type) {
|
||||
type = _type;
|
||||
}
|
||||
|
||||
public double getFinalCalibrationFactor() {
|
||||
return getCalibrationFactor() * getSizeAmps() / 380.0;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
if (key == null)
|
||||
key = key(panel, space);
|
||||
return key;
|
||||
}
|
||||
|
||||
public static String key(int _panel, int _space) {
|
||||
return String.format("%d-%d", _panel, _space);
|
||||
}
|
||||
|
||||
public static int portToChip(int _port) {
|
||||
return (_port < 9)?1:0;
|
||||
}
|
||||
|
||||
public static int portToPin(int _port) {
|
||||
return (_port < 9)?_port-1:_port-8;
|
||||
}
|
||||
|
||||
public static int toPort(int _chip, int _pin) {
|
||||
return (_chip == 0)?_pin+8:_pin+1;
|
||||
}
|
||||
|
||||
public static boolean isTandemBreakerA(int _space) {
|
||||
return (TANDEM_BREAKER_A_MASK & _space) != 0;
|
||||
}
|
||||
|
||||
public static boolean isTandemBreakerB(int _space) {
|
||||
return (TANDEM_BREAKER_B_MASK & _space) != 0;
|
||||
}
|
||||
|
||||
public static int toId(int _panel, int _space) {
|
||||
return (_panel << 12) | _space;
|
||||
}
|
||||
|
||||
public static int toPanel(int _id) {
|
||||
return _id >> 12;
|
||||
}
|
||||
|
||||
public static int toSpace(int _id) {
|
||||
return _id & (TANDEM_BREAKER_MASK |SPACE_MASK);
|
||||
}
|
||||
|
||||
public static String toSpaceDisplay(int _space) {
|
||||
if (isTandemBreakerA(_space))
|
||||
return String.format("%dA", _space & SPACE_MASK);
|
||||
if (isTandemBreakerB(_space))
|
||||
return String.format("%dB", _space & SPACE_MASK);
|
||||
return String.valueOf(_space);
|
||||
}
|
||||
|
||||
public int getSpaceIndex() {
|
||||
return space & SPACE_MASK;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
import com.lanternsoftware.util.dao.annotations.PrimaryKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@DBSerializable(autogen = false)
|
||||
public class BreakerConfig {
|
||||
@PrimaryKey
|
||||
private int accountId;
|
||||
private List<Meter> meters;
|
||||
private List<BreakerPanel> panels;
|
||||
private List<BreakerHub> breakerHubs;
|
||||
private List<BreakerGroup> breakerGroups;
|
||||
|
||||
public BreakerConfig() {
|
||||
}
|
||||
|
||||
public BreakerConfig(List<BreakerGroup> _breakerGroups) {
|
||||
breakerGroups = _breakerGroups;
|
||||
}
|
||||
|
||||
public int getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(int _accountId) {
|
||||
accountId = _accountId;
|
||||
}
|
||||
|
||||
public List<Meter> getMeters() {
|
||||
return meters;
|
||||
}
|
||||
|
||||
public void setMeters(List<Meter> _meters) {
|
||||
meters = _meters;
|
||||
}
|
||||
|
||||
public List<BreakerPanel> getPanels() {
|
||||
return panels;
|
||||
}
|
||||
|
||||
public void setPanels(List<BreakerPanel> _panels) {
|
||||
panels = _panels;
|
||||
}
|
||||
|
||||
public List<BreakerHub> getBreakerHubs() {
|
||||
return breakerHubs;
|
||||
}
|
||||
|
||||
public void setBreakerHubs(List<BreakerHub> _breakerHubs) {
|
||||
breakerHubs = _breakerHubs;
|
||||
}
|
||||
|
||||
public List<BreakerGroup> getBreakerGroups() {
|
||||
return breakerGroups;
|
||||
}
|
||||
|
||||
public void setBreakerGroups(List<BreakerGroup> _breakerGroups) {
|
||||
breakerGroups = _breakerGroups;
|
||||
}
|
||||
|
||||
public List<Breaker> getAllBreakers() {
|
||||
List<Breaker> allBreakers = new ArrayList<>();
|
||||
for (BreakerGroup g : CollectionUtils.makeNotNull(breakerGroups)) {
|
||||
allBreakers.addAll(g.getAllBreakers());
|
||||
}
|
||||
return allBreakers;
|
||||
}
|
||||
|
||||
public List<BreakerGroup> getAllBreakerGroups() {
|
||||
List<BreakerGroup> groups = new ArrayList<>();
|
||||
for (BreakerGroup g : CollectionUtils.makeNotNull(breakerGroups)) {
|
||||
groups.addAll(g.getAllBreakerGroups());
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
public List<String> getAllBreakerGroupIds() {
|
||||
List<String> ids = new ArrayList<>();
|
||||
for (BreakerGroup g : CollectionUtils.makeNotNull(breakerGroups)) {
|
||||
ids.addAll(g.getAllBreakerGroupIds());
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
public List<Breaker> getBreakersForHub(int _hub) {
|
||||
return CollectionUtils.filter(getAllBreakers(), _b -> _b.getHub() == _hub);
|
||||
}
|
||||
|
||||
public BreakerHub getHub(int _hub) {
|
||||
return CollectionUtils.filterOne(breakerHubs, _h->_h.getHub() == _hub);
|
||||
}
|
||||
|
||||
public boolean isSolarConfigured() {
|
||||
return CollectionUtils.anyQualify(getAllBreakers(), _b->_b.getPolarity() == BreakerPolarity.SOLAR);
|
||||
}
|
||||
|
||||
public String nextGroupId() {
|
||||
List<Integer> ids = CollectionUtils.transform(getAllBreakerGroupIds(), NullUtils::toInteger);
|
||||
return String.valueOf(CollectionUtils.getLargest(ids) + 1);
|
||||
}
|
||||
|
||||
public void addGroup(BreakerGroup _group) {
|
||||
if (NullUtils.isEmpty(_group.getId())) {
|
||||
_group.setId(nextGroupId());
|
||||
}
|
||||
if (breakerGroups == null)
|
||||
breakerGroups = new ArrayList<>();
|
||||
breakerGroups.add(_group);
|
||||
}
|
||||
|
||||
public void removeInvalidGroups() {
|
||||
if (breakerGroups != null)
|
||||
breakerGroups.removeIf(_g->!_g.removeInvalidGroups());
|
||||
}
|
||||
|
||||
public String getGroupIdForBreaker(Breaker _breaker) {
|
||||
return getGroupIdForBreaker(_breaker.getKey());
|
||||
}
|
||||
|
||||
public String getGroupIdForBreaker(int _panel, int _space) {
|
||||
return getGroupIdForBreaker(Breaker.key(_panel, _space));
|
||||
}
|
||||
|
||||
public String getGroupIdForBreaker(String _breakerKey) {
|
||||
BreakerGroup group = getGroupForBreaker(_breakerKey);
|
||||
return group != null ? group.getId() : null;
|
||||
}
|
||||
|
||||
public BreakerGroup getGroupForBreaker(Breaker _breaker) {
|
||||
return getGroupForBreaker(_breaker.getKey());
|
||||
}
|
||||
|
||||
public BreakerGroup getGroupForBreaker(int _panel, int _space) {
|
||||
return getGroupForBreaker(Breaker.key(_panel, _space));
|
||||
}
|
||||
|
||||
public BreakerGroup getGroupForBreaker(String _breakerKey) {
|
||||
if (_breakerKey == null)
|
||||
return null;
|
||||
for (BreakerGroup subGroup : CollectionUtils.makeNotNull(breakerGroups)) {
|
||||
BreakerGroup group = subGroup.getGroupForBreaker(_breakerKey);
|
||||
if (group != null)
|
||||
return group;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public BreakerGroup findParentGroup(BreakerGroup _group) {
|
||||
for (BreakerGroup group : CollectionUtils.makeNotNull(breakerGroups)) {
|
||||
BreakerGroup parent = group.findParentGroup(_group);
|
||||
if (parent != null)
|
||||
return parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
import com.lanternsoftware.util.dao.annotations.PrimaryKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@DBSerializable()
|
||||
public class BreakerGroup {
|
||||
@PrimaryKey private String id;
|
||||
private int accountId;
|
||||
private String name;
|
||||
private List<BreakerGroup> subGroups;
|
||||
private List<Breaker> breakers;
|
||||
|
||||
public BreakerGroup() {
|
||||
}
|
||||
|
||||
public BreakerGroup(String _id, String _name, List<Breaker> _breakers) {
|
||||
id = _id;
|
||||
name = _name;
|
||||
breakers = _breakers;
|
||||
}
|
||||
|
||||
public BreakerGroup(String _id, String _name, List<BreakerGroup> _subGroups, List<Breaker> _breakers) {
|
||||
id = _id;
|
||||
name = _name;
|
||||
subGroups = _subGroups;
|
||||
breakers = _breakers;
|
||||
}
|
||||
|
||||
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 String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String _name) {
|
||||
name = _name;
|
||||
}
|
||||
|
||||
public List<BreakerGroup> getSubGroups() {
|
||||
return subGroups;
|
||||
}
|
||||
|
||||
public void setSubGroups(List<BreakerGroup> _subGroups) {
|
||||
subGroups = _subGroups;
|
||||
}
|
||||
|
||||
public List<Breaker> getBreakers() {
|
||||
return breakers;
|
||||
}
|
||||
|
||||
public void setBreakers(List<Breaker> _breakers) {
|
||||
breakers = _breakers;
|
||||
}
|
||||
|
||||
public List<Breaker> getAllBreakers() {
|
||||
List<Breaker> allBreakers = new ArrayList<>();
|
||||
getAllBreakers(allBreakers);
|
||||
return allBreakers;
|
||||
}
|
||||
|
||||
private void getAllBreakers(List<Breaker> _breakers) {
|
||||
if (breakers != null)
|
||||
_breakers.addAll(breakers);
|
||||
for (BreakerGroup group : CollectionUtils.makeNotNull(subGroups)) {
|
||||
group.getAllBreakers(_breakers);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getAllBreakerKeys() {
|
||||
return CollectionUtils.transform(getAllBreakers(), Breaker::getKey);
|
||||
}
|
||||
|
||||
public List<BreakerGroup> getAllBreakerGroups() {
|
||||
List<BreakerGroup> allGroups = new ArrayList<>();
|
||||
getAllBreakerGroups(allGroups);
|
||||
return allGroups;
|
||||
}
|
||||
|
||||
private void getAllBreakerGroups(List<BreakerGroup> _groups) {
|
||||
_groups.add(this);
|
||||
for (BreakerGroup group : CollectionUtils.makeNotNull(subGroups)) {
|
||||
group.getAllBreakerGroups(_groups);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getAllBreakerGroupIds() {
|
||||
return CollectionUtils.transform(getAllBreakerGroups(), BreakerGroup::getId);
|
||||
}
|
||||
|
||||
public Breaker getBreaker(String _breakerKey) {
|
||||
for (Breaker b : CollectionUtils.makeNotNull(breakers)) {
|
||||
if (NullUtils.isEqual(b.getKey(), _breakerKey))
|
||||
return b;
|
||||
}
|
||||
for (BreakerGroup group : CollectionUtils.makeNotNull(subGroups)) {
|
||||
Breaker b = group.getBreaker(_breakerKey);
|
||||
if (b != null)
|
||||
return b;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getGroupIdForBreaker(Breaker _breaker) {
|
||||
return getGroupIdForBreaker(_breaker.getKey());
|
||||
}
|
||||
|
||||
public String getGroupIdForBreaker(int _panel, int _space) {
|
||||
return getGroupIdForBreaker(Breaker.key(_panel, _space));
|
||||
}
|
||||
|
||||
public String getGroupIdForBreaker(String _breakerKey) {
|
||||
BreakerGroup group = getGroupForBreaker(_breakerKey);
|
||||
return group != null ? group.getId() : null;
|
||||
}
|
||||
|
||||
public BreakerGroup getGroupForBreaker(Breaker _breaker) {
|
||||
return getGroupForBreaker(_breaker.getKey());
|
||||
}
|
||||
|
||||
public BreakerGroup getGroupForBreaker(int _panel, int _space) {
|
||||
return getGroupForBreaker(Breaker.key(_panel, _space));
|
||||
}
|
||||
|
||||
public BreakerGroup getGroupForBreaker(String _breakerKey) {
|
||||
if (_breakerKey == null)
|
||||
return null;
|
||||
Breaker b = CollectionUtils.filterOne(breakers, _b->_breakerKey.equals(_b.getKey()));
|
||||
if (b != null)
|
||||
return this;
|
||||
for (BreakerGroup subGroup : CollectionUtils.makeNotNull(subGroups)) {
|
||||
BreakerGroup group = subGroup.getGroupForBreaker(_breakerKey);
|
||||
if (group != null)
|
||||
return group;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public BreakerGroup findParentGroup(BreakerGroup _group) {
|
||||
if (CollectionUtils.contains(subGroups, _group))
|
||||
return this;
|
||||
for (BreakerGroup subGroup : CollectionUtils.makeNotNull(subGroups)) {
|
||||
BreakerGroup parent = subGroup.findParentGroup(_group);
|
||||
if (parent != null)
|
||||
return parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean removeInvalidGroups() {
|
||||
if (subGroups != null)
|
||||
subGroups.removeIf(_g->!_g.removeInvalidGroups());
|
||||
if (breakers != null)
|
||||
breakers.removeIf(_b->(_b.getType() == null) || (_b.getType() == BreakerType.EMPTY) || (_b.getPort() < 1));
|
||||
return CollectionUtils.isNotEmpty(subGroups) || CollectionUtils.isNotEmpty(breakers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object _o) {
|
||||
if (this == _o) return true;
|
||||
if (_o == null || getClass() != _o.getClass()) return false;
|
||||
BreakerGroup that = (BreakerGroup) _o;
|
||||
return Objects.equals(id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,337 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@DBSerializable(autogen = false)
|
||||
public class BreakerGroupEnergy {
|
||||
private int accountId;
|
||||
private String groupId;
|
||||
private String groupName;
|
||||
private EnergyBlockViewMode viewMode;
|
||||
private Date start;
|
||||
private List<BreakerGroupEnergy> subGroups;
|
||||
private List<EnergyBlock> energyBlocks;
|
||||
private double toGrid;
|
||||
private double fromGrid;
|
||||
|
||||
public BreakerGroupEnergy() {
|
||||
}
|
||||
|
||||
public BreakerGroupEnergy(BreakerGroup _group, Map<String, List<BreakerPower>> _powerReadings, EnergyBlockViewMode _viewMode, Date _start, TimeZone _tz) {
|
||||
groupId = _group.getId();
|
||||
groupName = _group.getName();
|
||||
viewMode = _viewMode;
|
||||
start = _start;
|
||||
accountId = _group.getAccountId();
|
||||
subGroups = CollectionUtils.transform(_group.getSubGroups(), _g -> new BreakerGroupEnergy(_g, _powerReadings, _viewMode, _start, _tz));
|
||||
energyBlocks = new ArrayList<>();
|
||||
List<String> breakerKeys = CollectionUtils.transform(_group.getBreakers(), Breaker::getKey);
|
||||
if (!breakerKeys.isEmpty()) {
|
||||
for (BreakerPower power : CollectionUtils.aggregate(breakerKeys, _powerReadings::get)) {
|
||||
addEnergy(groupId, power.getReadTime(), power.getPower(), _tz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BreakerGroupEnergy(BreakerGroup _group, List<HubPowerMinute> _power, EnergyBlockViewMode _viewMode, Date _start, TimeZone _tz) {
|
||||
groupId = _group.getId();
|
||||
groupName = _group.getName();
|
||||
viewMode = _viewMode;
|
||||
start = _start;
|
||||
accountId = _group.getAccountId();
|
||||
subGroups = CollectionUtils.transform(_group.getSubGroups(), _g -> new BreakerGroupEnergy(_g, (List<HubPowerMinute>)null, _viewMode, _start, _tz));
|
||||
energyBlocks = new ArrayList<>();
|
||||
addEnergy(_group, _power, _tz);
|
||||
}
|
||||
|
||||
public void addEnergy(BreakerGroup _group, List<HubPowerMinute> _hubPower, TimeZone _tz) {
|
||||
Map<String, Breaker> breakers = CollectionUtils.transformToMap(_group.getAllBreakers(), Breaker::getKey);
|
||||
Map<String, BreakerGroup> breakerKeyToGroup = new HashMap<>();
|
||||
for (BreakerGroup group : _group.getAllBreakerGroups()) {
|
||||
for (Breaker b : group.getAllBreakers()) {
|
||||
breakerKeyToGroup.put(b.getKey(), group);
|
||||
}
|
||||
}
|
||||
addEnergy(breakers, breakerKeyToGroup, _hubPower, _tz);
|
||||
}
|
||||
|
||||
public void addEnergy(Map<String, Breaker> _breakers, Map<String, BreakerGroup> _breakerKeyToGroup, List<HubPowerMinute> _hubPower, TimeZone _tz) {
|
||||
if (CollectionUtils.isEmpty(_hubPower) || CollectionUtils.anyQualify(_hubPower, _p->_p.getAccountId() != accountId))
|
||||
return;
|
||||
Date minute = CollectionUtils.getFirst(_hubPower).getMinuteAsDate();
|
||||
resetEnergy(minute, _tz);
|
||||
Map<Integer, MeterMinute> meters = new HashMap<>();
|
||||
for (HubPowerMinute hubPower : _hubPower) {
|
||||
for (BreakerPowerMinute breaker : CollectionUtils.makeNotNull(hubPower.getBreakers())) {
|
||||
Breaker b = _breakers.get(breaker.breakerKey());
|
||||
if (b == null)
|
||||
continue;
|
||||
BreakerGroup group = _breakerKeyToGroup.get(breaker.breakerKey());
|
||||
if (group == null)
|
||||
continue;
|
||||
MeterMinute meter = meters.computeIfAbsent(b.getMeter(), _p->new MeterMinute());
|
||||
int idx = 0;
|
||||
for (Float power : CollectionUtils.makeNotNull(breaker.getReadings())) {
|
||||
if (power > 0)
|
||||
meter.usage[idx] += power;
|
||||
else
|
||||
meter.solar[idx] += -power;
|
||||
if (power != 0.0)
|
||||
addEnergy(group.getId(), minute, power, _tz);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (MeterMinute meter : meters.values()) {
|
||||
for (int i = 0; i < 60; i++) {
|
||||
if (meter.usage[i] > meter.solar[i])
|
||||
fromGrid += meter.usage[i] - meter.solar[i];
|
||||
else
|
||||
toGrid += meter.solar[i] - meter.usage[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void resetEnergy(Date _readTime, TimeZone _tz) {
|
||||
EnergyBlock block = getBlock(_readTime, _tz, false);
|
||||
if (block != null)
|
||||
block.setJoules(0);
|
||||
for (BreakerGroupEnergy subGroup : CollectionUtils.makeNotNull(subGroups)) {
|
||||
subGroup.resetEnergy(_readTime, _tz);
|
||||
}
|
||||
}
|
||||
|
||||
public void addEnergy(String _groupId, Date _readTime, double _joules, TimeZone _tz) {
|
||||
if (NullUtils.isEqual(groupId, _groupId))
|
||||
getBlock(_readTime, _tz).addJoules(_joules);
|
||||
else {
|
||||
for (BreakerGroupEnergy subGroup : CollectionUtils.makeNotNull(subGroups)) {
|
||||
subGroup.addEnergy(_groupId, _readTime, _joules, _tz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static BreakerGroupEnergy summary(BreakerGroup _group, Map<String, List<BreakerGroupSummary>> _energies, EnergyBlockViewMode _viewMode, Date _start, TimeZone _tz) {
|
||||
BreakerGroupEnergy energy = new BreakerGroupEnergy();
|
||||
energy.setGroupId(_group.getId());
|
||||
energy.setGroupName(_group.getName());
|
||||
energy.setAccountId(_group.getAccountId());
|
||||
energy.setViewMode(_viewMode);
|
||||
energy.setStart(_start);
|
||||
energy.setSubGroups(CollectionUtils.transform(_group.getSubGroups(), _g -> BreakerGroupEnergy.summary(_g, _energies, _viewMode, _start, _tz)));
|
||||
for (BreakerGroupSummary curEnergy : CollectionUtils.makeNotNull(_energies.get(_group.getId()))) {
|
||||
EnergyBlock block = energy.getBlock(curEnergy.getStart(), _tz);
|
||||
block.addJoules(curEnergy.getJoules());
|
||||
energy.setToGrid(energy.getToGrid()+curEnergy.getToGrid());
|
||||
energy.setFromGrid(energy.getFromGrid()+curEnergy.getFromGrid());
|
||||
}
|
||||
return energy;
|
||||
}
|
||||
|
||||
private EnergyBlock getBlock(Date _readTime, TimeZone _tz) {
|
||||
return getBlock(_readTime, _tz, true);
|
||||
}
|
||||
|
||||
private EnergyBlock getBlock(Date _readTime, TimeZone _tz, boolean _add) {
|
||||
int size = CollectionUtils.size(energyBlocks);
|
||||
int idx = viewMode.blockIndex(_readTime, _tz);
|
||||
if (_add && (idx >= size)) {
|
||||
if (energyBlocks == null)
|
||||
energyBlocks = new ArrayList<>();
|
||||
LinkedList<EnergyBlock> newBlocks = new LinkedList<>();
|
||||
Date end = viewMode.toBlockEnd(_readTime, _tz);
|
||||
while (idx >= size) {
|
||||
Date start = viewMode.decrementBlock(end, _tz);
|
||||
newBlocks.add(new EnergyBlock(start, end, 0));
|
||||
end = start;
|
||||
size++;
|
||||
}
|
||||
Iterator<EnergyBlock> iter = newBlocks.descendingIterator();
|
||||
while (iter.hasNext()) {
|
||||
energyBlocks.add(iter.next());
|
||||
}
|
||||
}
|
||||
return CollectionUtils.get(energyBlocks, idx);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return toId(accountId, groupId, viewMode, start);
|
||||
}
|
||||
|
||||
public static String toId(int _accountId, String _groupId, EnergyBlockViewMode _viewMode, Date _start) {
|
||||
return _accountId + "-" + _groupId + "-" + DaoSerializer.toEnumName(_viewMode) + "-" + _start.getTime();
|
||||
}
|
||||
|
||||
public int getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(int _accountId) {
|
||||
accountId = _accountId;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public void setGroupId(String _groupId) {
|
||||
groupId = _groupId;
|
||||
}
|
||||
|
||||
public String getGroupName() {
|
||||
return groupName;
|
||||
}
|
||||
|
||||
public void setGroupName(String _groupName) {
|
||||
groupName = _groupName;
|
||||
}
|
||||
|
||||
public BreakerGroupEnergy getSubGroup(String _groupId) {
|
||||
return CollectionUtils.filterOne(subGroups, _g->_groupId.equals(_g.getGroupId()));
|
||||
}
|
||||
|
||||
public List<BreakerGroupEnergy> getSubGroups() {
|
||||
return subGroups;
|
||||
}
|
||||
|
||||
public EnergyBlockViewMode getViewMode() {
|
||||
return viewMode;
|
||||
}
|
||||
|
||||
public void setViewMode(EnergyBlockViewMode _viewMode) {
|
||||
viewMode = _viewMode;
|
||||
}
|
||||
|
||||
public Date getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(Date _start) {
|
||||
start = _start;
|
||||
}
|
||||
|
||||
public void setSubGroups(List<BreakerGroupEnergy> _subGroups) {
|
||||
subGroups = _subGroups;
|
||||
}
|
||||
|
||||
public List<EnergyBlock> getEnergyBlocks() {
|
||||
return energyBlocks;
|
||||
}
|
||||
|
||||
public void setEnergyBlocks(List<EnergyBlock> _energyBlocks) {
|
||||
energyBlocks = _energyBlocks;
|
||||
}
|
||||
|
||||
public double getToGrid() {
|
||||
return toGrid;
|
||||
}
|
||||
|
||||
public void setToGrid(double _toGrid) {
|
||||
toGrid = _toGrid;
|
||||
}
|
||||
|
||||
public double getFromGrid() {
|
||||
return fromGrid;
|
||||
}
|
||||
|
||||
public void setFromGrid(double _fromGrid) {
|
||||
fromGrid = _fromGrid;
|
||||
}
|
||||
|
||||
public double wattHours() {
|
||||
return joules() / 3600;
|
||||
}
|
||||
|
||||
public double wattHours(Set<String> _selectedBreakers) {
|
||||
return joules(_selectedBreakers) / 3600;
|
||||
}
|
||||
|
||||
public double joules() {
|
||||
return joules(null);
|
||||
}
|
||||
|
||||
public double joules(Set<String> _selectedBreakers) {
|
||||
return joules(_selectedBreakers, true);
|
||||
}
|
||||
|
||||
public double joules(Set<String> _selectedBreakers, boolean _includeSubgroups) {
|
||||
double joules = 0.0;
|
||||
if (_includeSubgroups) {
|
||||
for (BreakerGroupEnergy group : CollectionUtils.makeNotNull(subGroups)) {
|
||||
joules += group.joules(_selectedBreakers);
|
||||
}
|
||||
}
|
||||
if ((energyBlocks != null) && ((_selectedBreakers == null) || _selectedBreakers.contains(getGroupId()))) {
|
||||
for (EnergyBlock energy : energyBlocks) {
|
||||
joules += energy.getJoules();
|
||||
}
|
||||
}
|
||||
return joules;
|
||||
}
|
||||
|
||||
public List<BreakerGroupEnergy> getAllGroups() {
|
||||
Map<String, BreakerGroupEnergy> groups = new TreeMap<>();
|
||||
getAllGroups(groups);
|
||||
return new ArrayList<>(groups.values());
|
||||
}
|
||||
|
||||
public void getAllGroups(Map<String, BreakerGroupEnergy> _groups) {
|
||||
_groups.put(getGroupId(), this);
|
||||
for (BreakerGroupEnergy group : CollectionUtils.makeNotNull(subGroups)) {
|
||||
group.getAllGroups(_groups);
|
||||
}
|
||||
}
|
||||
|
||||
public List<EnergyBlock> getAllEnergyBlocks() {
|
||||
return getAllEnergyBlocks(null);
|
||||
}
|
||||
|
||||
public List<EnergyBlock> getAllEnergyBlocks(Set<String> _selectedGroups) {
|
||||
return getAllEnergyBlocks(_selectedGroups, EnergyBlockType.ANY);
|
||||
}
|
||||
|
||||
public List<EnergyBlock> getAllEnergyBlocks(Set<String> _selectedGroups, EnergyBlockType _type) {
|
||||
Map<Long, EnergyBlock> blocks = new TreeMap<>();
|
||||
getAllEnergyBlocks(_selectedGroups, blocks, _type);
|
||||
return new ArrayList<>(blocks.values());
|
||||
}
|
||||
|
||||
private void getAllEnergyBlocks(Set<String> _selectedGroups, Map<Long, EnergyBlock> _energyBlocks, EnergyBlockType _type) {
|
||||
if ((energyBlocks != null) && ((_selectedGroups == null) || _selectedGroups.contains(getGroupId()))) {
|
||||
for (EnergyBlock block : energyBlocks) {
|
||||
if ((_type == EnergyBlockType.ANY) || ((_type == EnergyBlockType.POSITIVE) && block.getJoules() >= 0.0) || ((_type == EnergyBlockType.NEGATIVE) && block.getJoules() <= 0.0)) {
|
||||
EnergyBlock b = _energyBlocks.get(block.getStart().getTime());
|
||||
if (b == null) {
|
||||
b = new EnergyBlock(block.getStart(), block.getEnd(), block.getJoules());
|
||||
_energyBlocks.put(block.getStart().getTime(), b);
|
||||
} else
|
||||
b.addJoules(block.getJoules());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (BreakerGroupEnergy group : CollectionUtils.makeNotNull(subGroups)) {
|
||||
group.getAllEnergyBlocks(_selectedGroups, _energyBlocks, _type);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MeterMinute {
|
||||
public double[] usage = new double[60];
|
||||
public double[] solar = new double[60];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@DBSerializable(autogen = false)
|
||||
public class BreakerGroupSummary {
|
||||
private int accountId;
|
||||
private String groupId;
|
||||
private String groupName;
|
||||
private EnergyBlockViewMode viewMode;
|
||||
private Date start;
|
||||
private List<BreakerGroupSummary> subGroups;
|
||||
private double joules;
|
||||
private double toGrid;
|
||||
private double fromGrid;
|
||||
|
||||
public BreakerGroupSummary() {
|
||||
}
|
||||
|
||||
public BreakerGroupSummary(BreakerGroupEnergy _energy) {
|
||||
accountId = _energy.getAccountId();
|
||||
groupId = _energy.getGroupId();
|
||||
groupName = _energy.getGroupName();
|
||||
viewMode = _energy.getViewMode();
|
||||
start = _energy.getStart();
|
||||
subGroups = CollectionUtils.transform(_energy.getSubGroups(), BreakerGroupSummary::new);
|
||||
joules = _energy.joules(null, false);
|
||||
toGrid = _energy.getToGrid();
|
||||
fromGrid = _energy.getFromGrid();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return toId(accountId, groupId, viewMode, start);
|
||||
}
|
||||
|
||||
public static String toId(int _accountId, String _groupId, EnergyBlockViewMode _viewMode, Date _start) {
|
||||
return _accountId + "-" + _groupId + "-" + DaoSerializer.toEnumName(_viewMode) + "-" + _start.getTime();
|
||||
}
|
||||
|
||||
public int getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(int _accountId) {
|
||||
accountId = _accountId;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public void setGroupId(String _groupId) {
|
||||
groupId = _groupId;
|
||||
}
|
||||
|
||||
public String getGroupName() {
|
||||
return groupName;
|
||||
}
|
||||
|
||||
public void setGroupName(String _groupName) {
|
||||
groupName = _groupName;
|
||||
}
|
||||
|
||||
public BreakerGroupSummary getSubGroup(String _groupId) {
|
||||
return CollectionUtils.filterOne(subGroups, _g->_groupId.equals(_g.getGroupId()));
|
||||
}
|
||||
|
||||
public List<BreakerGroupSummary> getSubGroups() {
|
||||
return subGroups;
|
||||
}
|
||||
|
||||
public EnergyBlockViewMode getViewMode() {
|
||||
return viewMode;
|
||||
}
|
||||
|
||||
public void setViewMode(EnergyBlockViewMode _viewMode) {
|
||||
viewMode = _viewMode;
|
||||
}
|
||||
|
||||
public Date getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(Date _start) {
|
||||
start = _start;
|
||||
}
|
||||
|
||||
public void setSubGroups(List<BreakerGroupSummary> _subGroups) {
|
||||
subGroups = _subGroups;
|
||||
}
|
||||
|
||||
public double getJoules() {
|
||||
return joules;
|
||||
}
|
||||
|
||||
public void setJoules(double _joules) {
|
||||
joules = _joules;
|
||||
}
|
||||
|
||||
public double getToGrid() {
|
||||
return toGrid;
|
||||
}
|
||||
|
||||
public void setToGrid(double _toGrid) {
|
||||
toGrid = _toGrid;
|
||||
}
|
||||
|
||||
public double getFromGrid() {
|
||||
return fromGrid;
|
||||
}
|
||||
|
||||
public void setFromGrid(double _fromGrid) {
|
||||
fromGrid = _fromGrid;
|
||||
}
|
||||
|
||||
public List<BreakerGroupSummary> getAllGroups() {
|
||||
Map<String, BreakerGroupSummary> groups = new TreeMap<>();
|
||||
getAllGroups(groups);
|
||||
return new ArrayList<>(groups.values());
|
||||
}
|
||||
|
||||
public void getAllGroups(Map<String, BreakerGroupSummary> _groups) {
|
||||
if (NullUtils.isNotEmpty(getGroupId()))
|
||||
_groups.put(getGroupId(), this);
|
||||
for (BreakerGroupSummary group : CollectionUtils.makeNotNull(subGroups)) {
|
||||
group.getAllGroups(_groups);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
@DBSerializable
|
||||
public class BreakerHub {
|
||||
private int hub;
|
||||
private double voltageCalibrationFactor;
|
||||
private int frequency;
|
||||
private String bluetoothMac;
|
||||
|
||||
public int getHub() {
|
||||
return hub;
|
||||
}
|
||||
|
||||
public void setHub(int _hub) {
|
||||
hub = _hub;
|
||||
}
|
||||
|
||||
public double getVoltageCalibrationFactor() {
|
||||
return voltageCalibrationFactor;
|
||||
}
|
||||
|
||||
public void setVoltageCalibrationFactor(double _voltageCalibrationFactor) {
|
||||
voltageCalibrationFactor = _voltageCalibrationFactor;
|
||||
}
|
||||
|
||||
public int getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public void setFrequency(int _frequency) {
|
||||
frequency = _frequency;
|
||||
}
|
||||
|
||||
public String getBluetoothMac() {
|
||||
return bluetoothMac;
|
||||
}
|
||||
|
||||
public void setBluetoothMac(String _bluetoothMac) {
|
||||
bluetoothMac = _bluetoothMac;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
@DBSerializable
|
||||
public class BreakerPanel {
|
||||
private int accountId;
|
||||
private String name;
|
||||
private int index;
|
||||
private int spaces;
|
||||
private int meter;
|
||||
|
||||
public int getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(int _accountId) {
|
||||
accountId = _accountId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String _name) {
|
||||
name = _name;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(int _index) {
|
||||
index = _index;
|
||||
}
|
||||
|
||||
public int getSpaces() {
|
||||
return spaces;
|
||||
}
|
||||
|
||||
public void setSpaces(int _spaces) {
|
||||
spaces = _spaces;
|
||||
}
|
||||
|
||||
public int getMeter() {
|
||||
return meter;
|
||||
}
|
||||
|
||||
public void setMeter(int _meter) {
|
||||
meter = _meter;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
public enum BreakerPolarity {
|
||||
NORMAL,
|
||||
SOLAR;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@DBSerializable(autogen = false)
|
||||
public class BreakerPower {
|
||||
private int accountId;
|
||||
private int panel;
|
||||
private int space;
|
||||
private Date readTime;
|
||||
private String hubVersion;
|
||||
private double power;
|
||||
private double voltage;
|
||||
|
||||
public BreakerPower() {
|
||||
}
|
||||
|
||||
public BreakerPower(int _panel, int _space, Date _readTime, double _power, double _voltage) {
|
||||
panel = _panel;
|
||||
space = _space;
|
||||
readTime = _readTime;
|
||||
power = _power;
|
||||
voltage = _voltage;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return String.format("%d-%d-%d", accountId, panel, space);
|
||||
}
|
||||
|
||||
public int getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(int _accountId) {
|
||||
accountId = _accountId;
|
||||
}
|
||||
|
||||
public int getPanel() {
|
||||
return panel;
|
||||
}
|
||||
|
||||
public void setPanel(int _panel) {
|
||||
panel = _panel;
|
||||
}
|
||||
|
||||
public int getSpace() {
|
||||
return space;
|
||||
}
|
||||
|
||||
public void setSpace(int _space) {
|
||||
space = _space;
|
||||
}
|
||||
|
||||
public Date getReadTime() {
|
||||
return readTime;
|
||||
}
|
||||
|
||||
public void setReadTime(Date _readTime) {
|
||||
readTime = _readTime;
|
||||
}
|
||||
|
||||
public String getHubVersion() {
|
||||
return hubVersion;
|
||||
}
|
||||
|
||||
public void setHubVersion(String _hubVersion) {
|
||||
hubVersion = _hubVersion;
|
||||
}
|
||||
|
||||
public double getPower() {
|
||||
return power;
|
||||
}
|
||||
|
||||
public void setPower(double _power) {
|
||||
power = _power;
|
||||
}
|
||||
|
||||
public double getVoltage() {
|
||||
return voltage;
|
||||
}
|
||||
|
||||
public void setVoltage(double _voltage) {
|
||||
voltage = _voltage;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return Breaker.key(panel, space);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@DBSerializable(autogen = false)
|
||||
public class BreakerPowerMinute {
|
||||
private int panel;
|
||||
private int space;
|
||||
private List<Float> readings;
|
||||
|
||||
public int getPanel() {
|
||||
return panel;
|
||||
}
|
||||
|
||||
public void setPanel(int _panel) {
|
||||
panel = _panel;
|
||||
}
|
||||
|
||||
public int getSpace() {
|
||||
return space;
|
||||
}
|
||||
|
||||
public void setSpace(int _space) {
|
||||
space = _space;
|
||||
}
|
||||
|
||||
public String breakerKey() {
|
||||
return Breaker.key(panel, space);
|
||||
}
|
||||
|
||||
public List<Float> getReadings() {
|
||||
return readings;
|
||||
}
|
||||
|
||||
public void setReadings(List<Float> _readings) {
|
||||
readings = _readings;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public enum BreakerType {
|
||||
EMPTY("Empty"),
|
||||
SINGLE_POLE("Single Pole"),
|
||||
SINGLE_POLE_TANDEM("Single Pole Tandem (Two Breakers in One)"),
|
||||
DOUBLE_POLE_TOP("Double Pole (240V)"),
|
||||
DOUBLE_POLE_BOTTOM("Double Pole (240V)");
|
||||
|
||||
private final String display;
|
||||
|
||||
BreakerType(String _display) {
|
||||
display = _display;
|
||||
}
|
||||
|
||||
public String getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public static List<BreakerType> selectable() {
|
||||
return CollectionUtils.asArrayList(EMPTY, SINGLE_POLE, SINGLE_POLE_TANDEM, DOUBLE_POLE_TOP);
|
||||
}
|
||||
|
||||
public static BreakerType fromDisplay(String _display) {
|
||||
for (BreakerType type : values()) {
|
||||
if (NullUtils.isEqual(_display, type.getDisplay()))
|
||||
return type;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public enum CharacteristicFlag {
|
||||
BROADCAST("broadcast"),
|
||||
READ("read"),
|
||||
WRITE_WITHOUT_RESPONSE("write-without-response"),
|
||||
WRITE("write"),
|
||||
NOTIFY("notify"),
|
||||
INDICATE("indicate"),
|
||||
AUTHENTICATED_SIGNED_WRITES("authenticated-signed-writes"),
|
||||
RELIABLE_WRITE("reliable-write"),
|
||||
WRITABLE_AUXILIARIES("writable-auxiliaries"),
|
||||
ENCRYPT_READ("encrypt-read"),
|
||||
ENCRYPT_WRITE("encrypt-write"),
|
||||
ENCRYPT_AUTHENTICATED_READ("encrypt-authenticated-read"),
|
||||
ENCRYPT_AUTHENTICATED_WRITE("encrypt-authenticated-write");
|
||||
|
||||
CharacteristicFlag(String _value) {
|
||||
value = _value;
|
||||
}
|
||||
|
||||
public final String value;
|
||||
|
||||
public static String[] toArray(Collection<CharacteristicFlag> _flags) {
|
||||
return CollectionUtils.transform(_flags, _c->_c.value).toArray(new String[0]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@DBSerializable
|
||||
public class EnergyBlock {
|
||||
private Date start;
|
||||
private Date end;
|
||||
private double joules;
|
||||
|
||||
public EnergyBlock() {
|
||||
}
|
||||
|
||||
public EnergyBlock(Date _start, Date _end, double _joules) {
|
||||
start = _start;
|
||||
end = _end;
|
||||
joules = _joules;
|
||||
}
|
||||
|
||||
public Date getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(Date _start) {
|
||||
start = _start;
|
||||
}
|
||||
|
||||
public Date getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public void setEnd(Date _end) {
|
||||
end = _end;
|
||||
}
|
||||
|
||||
public double getJoules() {
|
||||
return joules;
|
||||
}
|
||||
|
||||
public void addJoules(double _joules) {
|
||||
joules += _joules;
|
||||
}
|
||||
|
||||
public void setJoules(double _joules) {
|
||||
joules = _joules;
|
||||
}
|
||||
|
||||
public double wattHours() {
|
||||
return joules / 3600;
|
||||
}
|
||||
|
||||
public double getAveragePower() {
|
||||
if ((end == null) || (start == null))
|
||||
return 0;
|
||||
return 1000*joules/(end.getTime()-start.getTime());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
public enum EnergyBlockType {
|
||||
ANY,
|
||||
POSITIVE,
|
||||
NEGATIVE
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.DateUtils;
|
||||
|
||||
import javax.management.remote.rmi._RMIConnection_Stub;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public enum EnergyBlockViewMode {
|
||||
DAY,
|
||||
MONTH,
|
||||
YEAR,
|
||||
ALL;
|
||||
|
||||
public Date toStart(Date _dt, TimeZone _tz) {
|
||||
if (this == DAY)
|
||||
return DateUtils.getMidnightBefore(_dt, _tz);
|
||||
if (this == MONTH)
|
||||
return DateUtils.getStartOfMonth(_dt, _tz);
|
||||
if (this == YEAR)
|
||||
return DateUtils.getStartOfYear(_dt, _tz);
|
||||
return new Date(0);
|
||||
}
|
||||
|
||||
public Date toEnd(Date _dt, TimeZone _tz) {
|
||||
if (this == DAY)
|
||||
return DateUtils.getMidnightAfter(_dt, _tz);
|
||||
if (this == MONTH)
|
||||
return DateUtils.getEndOfMonth(_dt, _tz);
|
||||
if (this == YEAR)
|
||||
return DateUtils.getEndOfYear(_dt, _tz);
|
||||
return new Date(0);
|
||||
}
|
||||
|
||||
public Date toBlockStart(Date _dt, TimeZone _tz) {
|
||||
if (this == DAY)
|
||||
return DateUtils.getStartOfMinute(_dt, _tz);
|
||||
if (this == MONTH)
|
||||
return DateUtils.getMidnightBefore(_dt, _tz);
|
||||
if (this == YEAR)
|
||||
return DateUtils.getStartOfMonth(_dt, _tz);
|
||||
return new Date(0);
|
||||
}
|
||||
|
||||
public Date toBlockEnd(Date _dt, TimeZone _tz) {
|
||||
if (this == DAY)
|
||||
return DateUtils.getEndOfMinute(_dt, _tz);
|
||||
if (this == MONTH)
|
||||
return DateUtils.getMidnightAfter(_dt, _tz);
|
||||
if (this == YEAR)
|
||||
return DateUtils.getEndOfMonth(_dt, _tz);
|
||||
return new Date(0);
|
||||
}
|
||||
|
||||
public Date incrementBlock(Date _dt, TimeZone _tz) {
|
||||
Calendar cal = DateUtils.toCalendar(_dt, _tz);
|
||||
if (this == DAY)
|
||||
cal.add(Calendar.MINUTE, 1);
|
||||
else if (this == MONTH)
|
||||
cal.add(Calendar.DAY_OF_YEAR, 1);
|
||||
if (this == YEAR)
|
||||
cal.add(Calendar.MONTH, 1);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
public Date decrementBlock(Date _dt, TimeZone _tz) {
|
||||
Calendar cal = DateUtils.toCalendar(_dt, _tz);
|
||||
if (this == DAY)
|
||||
cal.add(Calendar.MINUTE, -1);
|
||||
else if (this == MONTH)
|
||||
cal.add(Calendar.DAY_OF_YEAR, -1);
|
||||
if (this == YEAR)
|
||||
cal.add(Calendar.MONTH, -1);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
public Date incrementView(Date _dt, TimeZone _tz) {
|
||||
Calendar cal = DateUtils.toCalendar(_dt, _tz);
|
||||
if (this == DAY)
|
||||
cal.add(Calendar.DAY_OF_YEAR, 1);
|
||||
else if (this == MONTH)
|
||||
cal.add(Calendar.MONTH, 1);
|
||||
if (this == YEAR)
|
||||
cal.add(Calendar.YEAR, 1);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
public Date decrementView(Date _dt, TimeZone _tz) {
|
||||
Calendar cal = DateUtils.toCalendar(_dt, _tz);
|
||||
if (this == DAY)
|
||||
cal.add(Calendar.DAY_OF_YEAR, -1);
|
||||
else if (this == MONTH)
|
||||
cal.add(Calendar.MONTH, -1);
|
||||
if (this == YEAR)
|
||||
cal.add(Calendar.YEAR, -1);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
public int blockCount(Date _start, TimeZone _tz) {
|
||||
if (this == ALL)
|
||||
return 1;
|
||||
Date end = toEnd(_start, _tz);
|
||||
int blockCnt = 0;
|
||||
while (_start.before(end)) {
|
||||
blockCnt++;
|
||||
_start = toBlockEnd(_start, _tz);
|
||||
}
|
||||
return blockCnt;
|
||||
}
|
||||
|
||||
public int blockIndex(Date _readTime, TimeZone _tz) {
|
||||
if (this == DAY) {
|
||||
Date start = DateUtils.getMidnightBefore(_readTime, _tz);
|
||||
return (int)((_readTime.getTime() - start.getTime())/60000);
|
||||
}
|
||||
else if (this == MONTH) {
|
||||
Calendar read = DateUtils.toCalendar(_readTime, _tz);
|
||||
return read.get(Calendar.DAY_OF_MONTH) - 1;
|
||||
}
|
||||
if (this == YEAR) {
|
||||
Calendar read = DateUtils.toCalendar(_readTime, _tz);
|
||||
return read.get(Calendar.MONTH);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Date toBlockStart(int _index, Date _start, TimeZone _tz) {
|
||||
if (this == DAY)
|
||||
return new Date(_start.getTime() + _index*60000);
|
||||
else if (this == MONTH) {
|
||||
Calendar read = DateUtils.toCalendar(_start, _tz);
|
||||
read.add(Calendar.DAY_OF_MONTH, _index);
|
||||
return read.getTime();
|
||||
}
|
||||
if (this == YEAR) {
|
||||
Calendar read = DateUtils.toCalendar(_start, _tz);
|
||||
read.add(Calendar.MONTH, _index);
|
||||
return read.getTime();
|
||||
}
|
||||
return new Date(0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.UUID;
|
||||
|
||||
public enum HubConfigCharacteristic {
|
||||
WifiCredentials(2, CharacteristicFlag.WRITE),
|
||||
AuthCode(3, CharacteristicFlag.WRITE),
|
||||
HubIndex(4, CharacteristicFlag.READ, CharacteristicFlag.WRITE),
|
||||
Restart(5, CharacteristicFlag.WRITE),
|
||||
Reboot(6, CharacteristicFlag.WRITE),
|
||||
AccountId(7, CharacteristicFlag.READ),
|
||||
NetworkState(8, CharacteristicFlag.READ),
|
||||
Flash(9, CharacteristicFlag.WRITE);
|
||||
|
||||
public final int idx;
|
||||
public final UUID uuid;
|
||||
public final EnumSet<CharacteristicFlag> flags;
|
||||
|
||||
HubConfigCharacteristic(int _idx, CharacteristicFlag... _flags) {
|
||||
idx = _idx;
|
||||
uuid = HubConfigService.uuidFormat.format(_idx);
|
||||
flags = EnumSet.copyOf(Arrays.asList(_flags));
|
||||
}
|
||||
|
||||
public int getIdx() {
|
||||
return idx;
|
||||
}
|
||||
|
||||
public UUID getUUID() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public EnumSet<CharacteristicFlag> getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public boolean isChar(String _char) {
|
||||
return NullUtils.isEqual(name(), _char);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.cryptography.AESTool;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class HubConfigService {
|
||||
public static final UUIDFormatter uuidFormat = new UUIDFormatter("c5650001-d50f-49af-b906-cada0dc17937");
|
||||
private static final AESTool aes = new AESTool(37320708309265127L,-8068168662055796771L,-4867793276337148572L,4425609941731230765L);
|
||||
private static final UUID serviceUUID = uuidFormat.format(1);
|
||||
|
||||
public HubConfigService() {
|
||||
}
|
||||
|
||||
public static UUID getServiceUUID() {
|
||||
return serviceUUID;
|
||||
}
|
||||
|
||||
public List<HubConfigCharacteristic> getCharacteristics() {
|
||||
return Arrays.asList(HubConfigCharacteristic.values());
|
||||
}
|
||||
|
||||
public static byte[] encryptWifiCreds(String _ssid, String _password) {
|
||||
DaoEntity creds = new DaoEntity("ssid", _ssid).and("pwd", _password);
|
||||
return aes.encrypt(DaoSerializer.toZipBson(creds));
|
||||
}
|
||||
|
||||
public static String decryptWifiSSID(byte[] _payload) {
|
||||
return DaoSerializer.getString(DaoSerializer.fromZipBson(aes.decrypt(_payload)), "ssid");
|
||||
}
|
||||
|
||||
public static String decryptWifiPassword(byte[] _payload) {
|
||||
return DaoSerializer.getString(DaoSerializer.fromZipBson(aes.decrypt(_payload)), "pwd");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@DBSerializable
|
||||
public class HubPowerMinute {
|
||||
private int accountId;
|
||||
private int hub;
|
||||
private int minute;
|
||||
private List<BreakerPowerMinute> breakers;
|
||||
|
||||
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 getMinuteAsDate() {
|
||||
return new Date(((long)minute)*60000);
|
||||
}
|
||||
|
||||
public int getMinute() {
|
||||
return minute;
|
||||
}
|
||||
|
||||
public void setMinute(int _minute) {
|
||||
minute = _minute;
|
||||
}
|
||||
|
||||
public void setMinute(Date _minute) {
|
||||
minute = (int)(_minute.getTime()/60000);
|
||||
}
|
||||
|
||||
public List<BreakerPowerMinute> getBreakers() {
|
||||
return breakers;
|
||||
}
|
||||
|
||||
public void setBreakers(List<BreakerPowerMinute> _breakers) {
|
||||
breakers = _breakers;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return String.format("%d-%d-%d", accountId, hub, minute);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
@DBSerializable
|
||||
public class Meter {
|
||||
private int accountId;
|
||||
private int index;
|
||||
private String name;
|
||||
|
||||
public int getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(int _accountId) {
|
||||
accountId = _accountId;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(int _index) {
|
||||
index = _index;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String _name) {
|
||||
name = _name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
|
||||
public enum NetworkAdapter {
|
||||
ETHERNET((byte)0x1),
|
||||
WIFI((byte)0x2);
|
||||
|
||||
public final byte bt;
|
||||
|
||||
NetworkAdapter(byte _bt) {
|
||||
bt = _bt;
|
||||
}
|
||||
|
||||
public static NetworkAdapter fromByte(byte _bt) {
|
||||
for (NetworkAdapter a : values()) {
|
||||
if (a.bt == _bt)
|
||||
return a;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static EnumSet<NetworkAdapter> fromMask(byte _bt) {
|
||||
EnumSet<NetworkAdapter> values = EnumSet.noneOf(NetworkAdapter.class);
|
||||
for (NetworkAdapter a : values()) {
|
||||
if ((a.bt & _bt) == a.bt)
|
||||
values.add(a);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static byte toMask(Collection<NetworkAdapter> _adapters) {
|
||||
byte mask = 0;
|
||||
for (NetworkAdapter a : CollectionUtils.makeNotNull(_adapters)) {
|
||||
mask |= a.bt;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
public class NetworkStatus {
|
||||
private List<String> wifiIPs;
|
||||
private List<String> ethernetIPs;
|
||||
|
||||
public List<String> getWifiIPs() {
|
||||
return wifiIPs;
|
||||
}
|
||||
|
||||
public void setWifiIPs(List<String> _wifiIPs) {
|
||||
wifiIPs = _wifiIPs;
|
||||
}
|
||||
|
||||
public List<String> getEthernetIPs() {
|
||||
return ethernetIPs;
|
||||
}
|
||||
|
||||
public void setEthernetIPs(List<String> _ethernetIPs) {
|
||||
ethernetIPs = _ethernetIPs;
|
||||
}
|
||||
|
||||
public boolean isWifiConnected() {
|
||||
return CollectionUtils.isNotEmpty(wifiIPs);
|
||||
}
|
||||
|
||||
public boolean isEthernetConnected() {
|
||||
return CollectionUtils.isNotEmpty(ethernetIPs);
|
||||
}
|
||||
|
||||
public byte toMask() {
|
||||
EnumSet<NetworkAdapter> adapters = EnumSet.noneOf(NetworkAdapter.class);
|
||||
if (isWifiConnected())
|
||||
adapters.add(NetworkAdapter.WIFI);
|
||||
if (isEthernetConnected())
|
||||
adapters.add(NetworkAdapter.ETHERNET);
|
||||
return NetworkAdapter.toMask(adapters);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
import com.lanternsoftware.util.dao.annotations.PrimaryKey;
|
||||
|
||||
@DBSerializable
|
||||
public class Sequence {
|
||||
@PrimaryKey
|
||||
private String id;
|
||||
private int sequence;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String _id) {
|
||||
id = _id;
|
||||
}
|
||||
|
||||
public int getSequence() {
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public void setSequence(int _sequence) {
|
||||
sequence = _sequence;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
@DBSerializable
|
||||
public class SignupResponse {
|
||||
private String error;
|
||||
private String authCode;
|
||||
|
||||
public SignupResponse() {
|
||||
}
|
||||
|
||||
public static SignupResponse error(String _error) {
|
||||
SignupResponse response = new SignupResponse();
|
||||
response.setError(_error);
|
||||
return response;
|
||||
}
|
||||
|
||||
public static SignupResponse success(String _authCode) {
|
||||
SignupResponse response = new SignupResponse();
|
||||
response.setAuthCode(_authCode);
|
||||
return response;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(String _error) {
|
||||
error = _error;
|
||||
}
|
||||
|
||||
public String getAuthCode() {
|
||||
return authCode;
|
||||
}
|
||||
|
||||
public void setAuthCode(String _authCode) {
|
||||
authCode = _authCode;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return NullUtils.isEmpty(error) && NullUtils.isNotEmpty(authCode);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class UUIDFormatter {
|
||||
private final String uuidPrefix;
|
||||
private final String uuidSuffix;
|
||||
|
||||
public UUIDFormatter(String _uuid) {
|
||||
uuidPrefix = _uuid.substring(0,4);
|
||||
uuidSuffix = _uuid.substring(8);
|
||||
}
|
||||
|
||||
public UUID format(int _idx) {
|
||||
return UUID.fromString(uuidPrefix + String.format("%04X", _idx) + uuidSuffix);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Account;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
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.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class AccountSerializer extends AbstractDaoSerializer<Account>
|
||||
{
|
||||
@Override
|
||||
public Class<Account> getSupportedClass()
|
||||
{
|
||||
return Account.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(Account _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("_id", String.valueOf(_o.getId()));
|
||||
d.put("username", _o.getUsername());
|
||||
d.put("password", _o.getPassword());
|
||||
if (CollectionUtils.isNotEmpty(_o.getAuxiliaryAccountIds()))
|
||||
d.put("aux_account_ids", CollectionUtils.toByteArray(_o.getAuxiliaryAccountIds()));
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
Account o = new Account();
|
||||
o.setId(DaoSerializer.getInteger(_d, "_id"));
|
||||
o.setUsername(DaoSerializer.getString(_d, "username"));
|
||||
o.setPassword(DaoSerializer.getString(_d, "password"));
|
||||
o.setAuxiliaryAccountIds(CollectionUtils.fromByteArrayOfIntegers(DaoSerializer.getByteArray(_d, "aux_account_ids")));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
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.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class AuthCodeSerializer extends AbstractDaoSerializer<AuthCode>
|
||||
{
|
||||
@Override
|
||||
public Class<AuthCode> getSupportedClass()
|
||||
{
|
||||
return AuthCode.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(AuthCode _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("account_id", _o.getAccountId());
|
||||
if (CollectionUtils.isNotEmpty(_o.getAuxiliaryAccountIds()))
|
||||
d.put("aux_account_ids", CollectionUtils.toByteArray(_o.getAuxiliaryAccountIds()));
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthCode fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
AuthCode o = new AuthCode();
|
||||
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
|
||||
o.setAuxiliaryAccountIds(CollectionUtils.fromByteArrayOfIntegers(DaoSerializer.getByteArray(_d, "aux_account_ids")));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerHub;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPanel;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Meter;
|
||||
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 BreakerConfigSerializer extends AbstractDaoSerializer<BreakerConfig>
|
||||
{
|
||||
@Override
|
||||
public Class<BreakerConfig> getSupportedClass()
|
||||
{
|
||||
return BreakerConfig.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(BreakerConfig _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("_id", String.valueOf(_o.getAccountId()));
|
||||
d.put("meters", DaoSerializer.toDaoEntities(_o.getMeters(), DaoProxyType.MONGO));
|
||||
d.put("panels", DaoSerializer.toDaoEntities(_o.getPanels(), DaoProxyType.MONGO));
|
||||
d.put("breaker_hubs", DaoSerializer.toDaoEntities(_o.getBreakerHubs(), DaoProxyType.MONGO));
|
||||
d.put("breaker_groups", DaoSerializer.toDaoEntities(_o.getBreakerGroups(), DaoProxyType.MONGO));
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerConfig fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
BreakerConfig o = new BreakerConfig();
|
||||
o.setAccountId(DaoSerializer.getInteger(_d, "_id"));
|
||||
o.setMeters(DaoSerializer.getList(_d, "meters", Meter.class));
|
||||
o.setPanels(DaoSerializer.getList(_d, "panels", BreakerPanel.class));
|
||||
o.setBreakerHubs(DaoSerializer.getList(_d, "breaker_hubs", BreakerHub.class));
|
||||
o.setBreakerGroups(DaoSerializer.getList(_d, "breaker_groups", BreakerGroup.class));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroupEnergy;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.EnergyBlock;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.EnergyBlockViewMode;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
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.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class BreakerGroupEnergySerializer extends AbstractDaoSerializer<BreakerGroupEnergy>
|
||||
{
|
||||
@Override
|
||||
public Class<BreakerGroupEnergy> getSupportedClass()
|
||||
{
|
||||
return BreakerGroupEnergy.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(BreakerGroupEnergy _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("_id", _o.getId());
|
||||
d.put("account_id", _o.getAccountId());
|
||||
d.put("group_id", _o.getGroupId());
|
||||
d.put("group_name", _o.getGroupName());
|
||||
d.put("view_mode", DaoSerializer.toEnumName(_o.getViewMode()));
|
||||
d.put("start", DaoSerializer.toLong(_o.getStart()));
|
||||
d.put("sub_groups", DaoSerializer.toDaoEntities(_o.getSubGroups(), DaoProxyType.MONGO));
|
||||
if (CollectionUtils.size(_o.getEnergyBlocks()) > 0) {
|
||||
Date start = _o.getStart();
|
||||
Date now = new Date();
|
||||
TimeZone tz = TimeZone.getTimeZone("America/Chicago");
|
||||
ByteBuffer bb = ByteBuffer.allocate(_o.getViewMode().blockCount(start, tz) * 4);
|
||||
for (EnergyBlock b : _o.getEnergyBlocks()) {
|
||||
if (b.getStart().before(start))
|
||||
continue;
|
||||
if (now.before(start))
|
||||
break;
|
||||
while (start.before(b.getStart())) {
|
||||
bb.putFloat(0);
|
||||
start = _o.getViewMode().toBlockEnd(start, tz);
|
||||
}
|
||||
bb.putFloat((float) b.getJoules());
|
||||
start = _o.getViewMode().toBlockEnd(start, tz);
|
||||
}
|
||||
if (bb.position() < bb.limit())
|
||||
d.put("blocks", Arrays.copyOfRange(bb.array(), 0, bb.position()));
|
||||
else
|
||||
d.put("blocks", bb.array());
|
||||
}
|
||||
d.put("to_grid", _o.getToGrid());
|
||||
d.put("from_grid", _o.getFromGrid());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerGroupEnergy fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
TimeZone tz = TimeZone.getTimeZone("America/Chicago");
|
||||
BreakerGroupEnergy o = new BreakerGroupEnergy();
|
||||
o.setGroupId(DaoSerializer.getString(_d, "group_id"));
|
||||
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
|
||||
o.setGroupName(DaoSerializer.getString(_d, "group_name"));
|
||||
o.setViewMode(DaoSerializer.getEnum(_d, "view_mode", EnergyBlockViewMode.class));
|
||||
o.setStart(DaoSerializer.getDate(_d, "start"));
|
||||
o.setSubGroups(DaoSerializer.getList(_d, "sub_groups", BreakerGroupEnergy.class));
|
||||
List<EnergyBlock> blocks = new ArrayList<>();
|
||||
byte[] blockData = DaoSerializer.getByteArray(_d, "blocks");
|
||||
if (CollectionUtils.length(blockData) > 0) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(blockData);
|
||||
Date start = o.getStart();
|
||||
while (bb.hasRemaining()) {
|
||||
EnergyBlock block = new EnergyBlock(start, o.getViewMode().toBlockEnd(start, tz), bb.getFloat());
|
||||
blocks.add(block);
|
||||
start = block.getEnd();
|
||||
}
|
||||
}
|
||||
o.setEnergyBlocks(blocks);
|
||||
o.setToGrid(DaoSerializer.getDouble(_d, "to_grid"));
|
||||
o.setFromGrid(DaoSerializer.getDouble(_d, "from_grid"));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
|
||||
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 BreakerGroupSerializer extends AbstractDaoSerializer<BreakerGroup>
|
||||
{
|
||||
@Override
|
||||
public Class<BreakerGroup> getSupportedClass()
|
||||
{
|
||||
return BreakerGroup.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(BreakerGroup _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
if (_o.getId() != null)
|
||||
d.put("_id", _o.getId());
|
||||
d.put("account_id", _o.getAccountId());
|
||||
d.put("name", _o.getName());
|
||||
d.put("sub_groups", DaoSerializer.toDaoEntities(_o.getSubGroups(), DaoProxyType.MONGO));
|
||||
d.put("breakers", DaoSerializer.toDaoEntities(_o.getBreakers(), DaoProxyType.MONGO));
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerGroup fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
BreakerGroup o = new BreakerGroup();
|
||||
o.setId(DaoSerializer.getString(_d, "_id"));
|
||||
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
|
||||
o.setName(DaoSerializer.getString(_d, "name"));
|
||||
o.setSubGroups(DaoSerializer.getList(_d, "sub_groups", BreakerGroup.class));
|
||||
o.setBreakers(DaoSerializer.getList(_d, "breakers", Breaker.class));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroupSummary;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.EnergyBlockViewMode;
|
||||
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;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class BreakerGroupSummarySerializer extends AbstractDaoSerializer<BreakerGroupSummary> {
|
||||
@Override
|
||||
public Class<BreakerGroupSummary> getSupportedClass() {
|
||||
return BreakerGroupSummary.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(BreakerGroupSummary _o) {
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("_id", _o.getId());
|
||||
d.put("account_id", _o.getAccountId());
|
||||
d.put("group_id", _o.getGroupId());
|
||||
d.put("group_name", _o.getGroupName());
|
||||
d.put("view_mode", DaoSerializer.toEnumName(_o.getViewMode()));
|
||||
d.put("start", DaoSerializer.toLong(_o.getStart()));
|
||||
d.put("sub_groups", DaoSerializer.toDaoEntities(_o.getSubGroups(), DaoProxyType.MONGO));
|
||||
d.put("joules", _o.getJoules());
|
||||
d.put("to_grid", _o.getToGrid());
|
||||
d.put("from_grid", _o.getFromGrid());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerGroupSummary fromDaoEntity(DaoEntity _d) {
|
||||
BreakerGroupSummary o = new BreakerGroupSummary();
|
||||
o.setGroupId(DaoSerializer.getString(_d, "group_id"));
|
||||
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
|
||||
o.setGroupName(DaoSerializer.getString(_d, "group_name"));
|
||||
o.setViewMode(DaoSerializer.getEnum(_d, "view_mode", EnergyBlockViewMode.class));
|
||||
o.setStart(DaoSerializer.getDate(_d, "start"));
|
||||
o.setSubGroups(DaoSerializer.getList(_d, "sub_groups", BreakerGroupSummary.class));
|
||||
o.setJoules(DaoSerializer.getDouble(_d, "joules"));
|
||||
o.setToGrid(DaoSerializer.getDouble(_d, "to_grid"));
|
||||
o.setFromGrid(DaoSerializer.getDouble(_d, "from_grid"));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerHub;
|
||||
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 BreakerHubSerializer extends AbstractDaoSerializer<BreakerHub>
|
||||
{
|
||||
@Override
|
||||
public Class<BreakerHub> getSupportedClass()
|
||||
{
|
||||
return BreakerHub.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(BreakerHub _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("hub", _o.getHub());
|
||||
d.put("voltage_calibration_factor", _o.getVoltageCalibrationFactor());
|
||||
d.put("frequency", _o.getFrequency());
|
||||
d.put("bluetooth_mac", _o.getBluetoothMac());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerHub fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
BreakerHub o = new BreakerHub();
|
||||
o.setHub(DaoSerializer.getInteger(_d, "hub"));
|
||||
o.setVoltageCalibrationFactor(DaoSerializer.getDouble(_d, "voltage_calibration_factor"));
|
||||
o.setFrequency(DaoSerializer.getInteger(_d, "frequency"));
|
||||
o.setBluetoothMac(DaoSerializer.getString(_d, "bluetooth_mac"));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPanel;
|
||||
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 BreakerPanelSerializer extends AbstractDaoSerializer<BreakerPanel>
|
||||
{
|
||||
@Override
|
||||
public Class<BreakerPanel> getSupportedClass()
|
||||
{
|
||||
return BreakerPanel.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(BreakerPanel _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("account_id", _o.getAccountId());
|
||||
d.put("name", _o.getName());
|
||||
d.put("index", _o.getIndex());
|
||||
d.put("spaces", _o.getSpaces());
|
||||
d.put("meter", _o.getMeter());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerPanel fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
BreakerPanel o = new BreakerPanel();
|
||||
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
|
||||
o.setName(DaoSerializer.getString(_d, "name"));
|
||||
o.setIndex(DaoSerializer.getInteger(_d, "index"));
|
||||
o.setSpaces(DaoSerializer.getInteger(_d, "spaces"));
|
||||
o.setMeter(DaoSerializer.getInteger(_d, "meter"));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPowerMinute;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.dao.AbstractDaoSerializer;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BreakerPowerMinuteSerializer extends AbstractDaoSerializer<BreakerPowerMinute> {
|
||||
@Override
|
||||
public Class<BreakerPowerMinute> getSupportedClass() {
|
||||
return BreakerPowerMinute.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(BreakerPowerMinute _o) {
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("panel", _o.getPanel());
|
||||
d.put("space", _o.getSpace());
|
||||
ByteBuffer bb = ByteBuffer.allocate(240);
|
||||
for (Float reading : CollectionUtils.makeNotNull(_o.getReadings())) {
|
||||
bb.putFloat(DaoSerializer.toFloat(reading));
|
||||
}
|
||||
d.put("readings", bb.array());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerPowerMinute fromDaoEntity(DaoEntity _d) {
|
||||
BreakerPowerMinute o = new BreakerPowerMinute();
|
||||
o.setPanel(DaoSerializer.getInteger(_d, "panel"));
|
||||
o.setSpace(DaoSerializer.getInteger(_d, "space"));
|
||||
byte[] data = DaoSerializer.getByteArray(_d, "readings");
|
||||
List<Float> readings = new ArrayList<>();
|
||||
o.setReadings(readings);
|
||||
if (CollectionUtils.length(data) > 0) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(data);
|
||||
while (bb.hasRemaining()) {
|
||||
readings.add(bb.getFloat());
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPower;
|
||||
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 BreakerPowerSerializer extends AbstractDaoSerializer<BreakerPower>
|
||||
{
|
||||
@Override
|
||||
public Class<BreakerPower> getSupportedClass()
|
||||
{
|
||||
return BreakerPower.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(BreakerPower _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("_id", _o.getId());
|
||||
d.put("account_id", _o.getAccountId());
|
||||
d.put("panel", _o.getPanel());
|
||||
d.put("space", _o.getSpace());
|
||||
d.put("key", _o.getKey());
|
||||
d.put("read_time", DaoSerializer.toLong(_o.getReadTime()));
|
||||
d.put("hub_version", _o.getHubVersion());
|
||||
d.put("power", _o.getPower());
|
||||
d.put("voltage", _o.getVoltage());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BreakerPower fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
BreakerPower o = new BreakerPower();
|
||||
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
|
||||
o.setPanel(DaoSerializer.getInteger(_d, "panel"));
|
||||
o.setSpace(DaoSerializer.getInteger(_d, "space"));
|
||||
o.setReadTime(DaoSerializer.getDate(_d, "read_time"));
|
||||
o.setHubVersion(DaoSerializer.getString(_d, "hub_version"));
|
||||
o.setPower(DaoSerializer.getDouble(_d, "power"));
|
||||
o.setVoltage(DaoSerializer.getDouble(_d, "voltage"));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPolarity;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerType;
|
||||
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 BreakerSerializer extends AbstractDaoSerializer<Breaker>
|
||||
{
|
||||
@Override
|
||||
public Class<Breaker> getSupportedClass()
|
||||
{
|
||||
return Breaker.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(Breaker _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("panel", _o.getPanel());
|
||||
d.put("space", _o.getSpace());
|
||||
d.put("meter", _o.getMeter());
|
||||
d.put("hub", _o.getHub());
|
||||
d.put("port", _o.getPort());
|
||||
d.put("name", _o.getName());
|
||||
d.put("description", _o.getDescription());
|
||||
d.put("size_amps", _o.getSizeAmps());
|
||||
d.put("calibration_factor", _o.getCalibrationFactor());
|
||||
d.put("low_pass_filter", _o.getLowPassFilter());
|
||||
d.put("polarity", DaoSerializer.toEnumName(_o.getPolarity()));
|
||||
d.put("type", DaoSerializer.toEnumName(_o.getType()));
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Breaker fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
Breaker o = new Breaker();
|
||||
o.setPanel(DaoSerializer.getInteger(_d, "panel"));
|
||||
o.setSpace(DaoSerializer.getInteger(_d, "space"));
|
||||
o.setMeter(DaoSerializer.getInteger(_d, "meter"));
|
||||
o.setHub(DaoSerializer.getInteger(_d, "hub"));
|
||||
o.setPort(DaoSerializer.getInteger(_d, "port"));
|
||||
o.setName(DaoSerializer.getString(_d, "name"));
|
||||
o.setDescription(DaoSerializer.getString(_d, "description"));
|
||||
o.setSizeAmps(DaoSerializer.getInteger(_d, "size_amps"));
|
||||
o.setCalibrationFactor(DaoSerializer.getDouble(_d, "calibration_factor"));
|
||||
o.setLowPassFilter(DaoSerializer.getDouble(_d, "low_pass_filter"));
|
||||
o.setPolarity(DaoSerializer.getEnum(_d, "polarity", BreakerPolarity.class));
|
||||
o.setType(DaoSerializer.getEnum(_d, "type", BreakerType.class));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.EnergyBlock;
|
||||
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 EnergyBlockSerializer extends AbstractDaoSerializer<EnergyBlock>
|
||||
{
|
||||
@Override
|
||||
public Class<EnergyBlock> getSupportedClass()
|
||||
{
|
||||
return EnergyBlock.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(EnergyBlock _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("start", DaoSerializer.toLong(_o.getStart()));
|
||||
d.put("end", DaoSerializer.toLong(_o.getEnd()));
|
||||
d.put("joules", _o.getJoules());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnergyBlock fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
EnergyBlock o = new EnergyBlock();
|
||||
o.setStart(DaoSerializer.getDate(_d, "start"));
|
||||
o.setEnd(DaoSerializer.getDate(_d, "end"));
|
||||
o.setJoules(DaoSerializer.getDouble(_d, "joules"));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPowerMinute;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.HubPowerMinute;
|
||||
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 HubPowerMinuteSerializer extends AbstractDaoSerializer<HubPowerMinute>
|
||||
{
|
||||
@Override
|
||||
public Class<HubPowerMinute> getSupportedClass()
|
||||
{
|
||||
return HubPowerMinute.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(HubPowerMinute _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("account_id", _o.getAccountId());
|
||||
d.put("hub", _o.getHub());
|
||||
d.put("minute", _o.getMinute());
|
||||
d.put("breakers", DaoSerializer.toDaoEntities(_o.getBreakers(), DaoProxyType.MONGO));
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HubPowerMinute fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
HubPowerMinute o = new HubPowerMinute();
|
||||
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
|
||||
o.setHub(DaoSerializer.getInteger(_d, "hub"));
|
||||
o.setMinute(DaoSerializer.getInteger(_d, "minute"));
|
||||
o.setBreakers(DaoSerializer.getList(_d, "breakers", BreakerPowerMinute.class));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Meter;
|
||||
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 MeterSerializer extends AbstractDaoSerializer<Meter>
|
||||
{
|
||||
@Override
|
||||
public Class<Meter> getSupportedClass()
|
||||
{
|
||||
return Meter.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(Meter _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("account_id", _o.getAccountId());
|
||||
d.put("index", _o.getIndex());
|
||||
d.put("name", _o.getName());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Meter fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
Meter o = new Meter();
|
||||
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
|
||||
o.setIndex(DaoSerializer.getInteger(_d, "index"));
|
||||
o.setName(DaoSerializer.getString(_d, "name"));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Sequence;
|
||||
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 SequenceSerializer extends AbstractDaoSerializer<Sequence>
|
||||
{
|
||||
@Override
|
||||
public Class<Sequence> getSupportedClass()
|
||||
{
|
||||
return Sequence.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(Sequence _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
if (_o.getId() != null)
|
||||
d.put("_id", _o.getId());
|
||||
d.put("sequence", _o.getSequence());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sequence fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
Sequence o = new Sequence();
|
||||
o.setId(DaoSerializer.getString(_d, "_id"));
|
||||
o.setSequence(DaoSerializer.getInteger(_d, "sequence"));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.SignupResponse;
|
||||
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 SignupResponseSerializer extends AbstractDaoSerializer<SignupResponse>
|
||||
{
|
||||
@Override
|
||||
public Class<SignupResponse> getSupportedClass()
|
||||
{
|
||||
return SignupResponse.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DaoProxyType> getSupportedProxies() {
|
||||
return Collections.singletonList(DaoProxyType.MONGO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoEntity toDaoEntity(SignupResponse _o)
|
||||
{
|
||||
DaoEntity d = new DaoEntity();
|
||||
d.put("error", _o.getError());
|
||||
d.put("auth_code", _o.getAuthCode());
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignupResponse fromDaoEntity(DaoEntity _d)
|
||||
{
|
||||
SignupResponse o = new SignupResponse();
|
||||
o.setError(DaoSerializer.getString(_d, "error"));
|
||||
o.setAuthCode(DaoSerializer.getString(_d, "auth_code"));
|
||||
return o;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
com.lanternsoftware.datamodel.currentmonitor.dao.AccountSerializer
|
||||
com.lanternsoftware.datamodel.currentmonitor.dao.AuthCodeSerializer
|
||||
com.lanternsoftware.datamodel.currentmonitor.dao.BreakerConfigSerializer
|
||||
com.lanternsoftware.datamodel.currentmonitor.dao.BreakerGroupEnergySerializer
|
||||
com.lanternsoftware.datamodel.currentmonitor.dao.BreakerGroupSerializer
|
||||
com.lanternsoftware.datamodel.currentmonitor.dao.BreakerGroupSummarySerializer
|
||||
com.lanternsoftware.datamodel.currentmonitor.dao.BreakerHubSerializer
|
||||
com.lanternsoftware.datamodel.currentmonitor.dao.BreakerPanelSerializer
|
||||
com.lanternsoftware.datamodel.currentmonitor.dao.BreakerPowerMinuteSerializer
|
||||
com.lanternsoftware.datamodel.currentmonitor.dao.BreakerPowerSerializer
|
||||
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.SequenceSerializer
|
||||
com.lanternsoftware.datamodel.currentmonitor.dao.SignupResponseSerializer
|
89
currentmonitor/lantern-service-currentmonitor/pom.xml
Normal file
89
currentmonitor/lantern-service-currentmonitor/pom.xml
Normal file
|
@ -0,0 +1,89 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.lanternsoftware.currentmonitor</groupId>
|
||||
<artifactId>lantern-service-currentmonitor</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>1.0.0</version>
|
||||
<name>lantern-service-currentmonitor</name>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.lanternsoftware.currentmonitor</groupId>
|
||||
<artifactId>lantern-dataaccess-currentmonitor</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.lanternsoftware.util</groupId>
|
||||
<artifactId>lantern-util-servlet</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.api-client</groupId>
|
||||
<artifactId>google-api-client</artifactId>
|
||||
<version>1.30.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax</groupId>
|
||||
<artifactId>javaee-api</artifactId>
|
||||
<version>8.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.29</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
<phase>compile</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<optimize>true</optimize>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>lib/</classpathPrefix>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,23 @@
|
|||
package com.lanternsoftware.currentmonitor.context;
|
||||
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.CurrentMonitorDao;
|
||||
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 CurrentMonitorDao dao;
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
dao.shutdown();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
|
||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||
import com.google.api.client.json.jackson2.JacksonFactory;
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
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 com.lanternsoftware.util.servlet.BasicAuth;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Collections;
|
||||
|
||||
@WebServlet("/auth/*")
|
||||
public class AuthServlet extends CMServlet {
|
||||
private static final NetHttpTransport transport = new NetHttpTransport();
|
||||
private static final JacksonFactory jsonFactory = new JacksonFactory();
|
||||
private static final Logger logger = LoggerFactory.getLogger(AuthServlet.class);
|
||||
private static final String googleSsoKey = ResourceLoader.loadFileAsString(LanternFiles.OPS_PATH + "google_sso_key.txt");
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String authCode = _req.getHeader("auth_code");
|
||||
if (NullUtils.isEmpty(authCode)) {
|
||||
BasicAuth auth = new BasicAuth(_req);
|
||||
if (NullUtils.isEqual(auth.getUsername(), "googlesso")) {
|
||||
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory).setAudience(Collections.singletonList(googleSsoKey)).build();
|
||||
try {
|
||||
GoogleIdToken idToken = verifier.verify(auth.getPassword());
|
||||
if (idToken != null) {
|
||||
GoogleIdToken.Payload payload = idToken.getPayload();
|
||||
String email = payload.getEmail();
|
||||
authCode = Globals.dao.getAuthCodeForEmail(email);
|
||||
}
|
||||
}
|
||||
catch (Exception _e) {
|
||||
logger.error("Failed to validate google auth token", _e);
|
||||
}
|
||||
}
|
||||
else
|
||||
authCode = Globals.dao.authenticateAccount(auth.getUsername(), auth.getPassword());
|
||||
}
|
||||
DaoEntity rep = new DaoEntity("auth_code", authCode);
|
||||
if (isPath(_req, 0, "bin"))
|
||||
zipBsonResponse(_rep, rep);
|
||||
else
|
||||
jsonResponse(_rep, rep);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
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 CMServlet extends HttpServlet {
|
||||
public static void setResponseHtml(HttpServletResponse _response, String _sHtml) {
|
||||
setResponseEntity(_response, MediaType.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 DaoEntity getRequestZipBson(HttpServletRequest _req) {
|
||||
return DaoSerializer.fromZipBson(getRequestPayload(_req));
|
||||
}
|
||||
|
||||
protected <T> T getRequestPayload(HttpServletRequest _req, Class<T> _retClass) {
|
||||
return DaoSerializer.fromZipBson(getRequestPayload(_req), _retClass);
|
||||
}
|
||||
|
||||
protected String[] path(HttpServletRequest _req) {
|
||||
return NullUtils.cleanSplit(NullUtils.makeNotNull(_req.getPathInfo()), "/");
|
||||
}
|
||||
|
||||
protected boolean isPath(HttpServletRequest _req, int _index, String _path) {
|
||||
return NullUtils.isEqual(_path, CollectionUtils.get(path(_req), _index));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.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<String> 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"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/config/*")
|
||||
public class ConfigServlet extends SecureServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
if (isPath(_req, 0, "bin"))
|
||||
zipBsonResponse(_rep, Globals.dao.getMergedConfig(_authCode));
|
||||
else
|
||||
jsonResponse(_rep, Globals.dao.getMergedConfig(_authCode));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void post(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
BreakerConfig config = getRequestPayload(_req, BreakerConfig.class);
|
||||
if (config == null) {
|
||||
_rep.setStatus(400);
|
||||
return;
|
||||
}
|
||||
if (config.getAccountId() != _authCode.getAccountId()) {
|
||||
_rep.setStatus(401);
|
||||
return;
|
||||
}
|
||||
Globals.dao.putConfig(config);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroupEnergy;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.EnergyBlockViewMode;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@WebServlet("/energy/group/*")
|
||||
public class GroupEnergyServlet extends SecureServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String[] path = path(_req);
|
||||
if (path.length < 3) {
|
||||
_rep.setStatus(400);
|
||||
return;
|
||||
}
|
||||
EnergyBlockViewMode viewMode = NullUtils.toEnum(EnergyBlockViewMode.class, path[1], EnergyBlockViewMode.DAY);
|
||||
Date start = new Date(NullUtils.toLong(path[2]));
|
||||
List<BreakerGroupEnergy> energies = CollectionUtils.transform(_authCode.getAllAccountIds(), _id->Globals.dao.getBreakerGroupEnergy(_id, path[0], viewMode, start), true);
|
||||
if (CollectionUtils.isNotEmpty(energies)) {
|
||||
BreakerGroupEnergy energy;
|
||||
if (energies.size() > 1) {
|
||||
energy = new BreakerGroupEnergy();
|
||||
energy.setAccountId(_authCode.getAccountId());
|
||||
energy.setGroupId("Sites");
|
||||
energy.setGroupName("Sites");
|
||||
energy.setStart(start);
|
||||
energy.setViewMode(viewMode);
|
||||
energy.setSubGroups(CollectionUtils.asArrayList(energies));
|
||||
}
|
||||
else
|
||||
energy = CollectionUtils.getFirst(energies);
|
||||
if (NullUtils.isEqual(CollectionUtils.get(path, 3), "bin"))
|
||||
zipBsonResponse(_rep, energy);
|
||||
else
|
||||
jsonResponse(_rep, energy);
|
||||
} else
|
||||
_rep.setStatus(404);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPower;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import org.bson.Document;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/power/group/*")
|
||||
public class GroupPowerServlet extends SecureServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String[] path = path(_req);
|
||||
if (path.length < 1)
|
||||
zipBsonResponse(_rep, new DaoEntity("breakers", DaoSerializer.toDaoEntities(Globals.dao.getBreakerPowerForAccount(_authCode.getAccountId()))));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.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 javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
@WebServlet("/power/*")
|
||||
public class PowerServlet extends SecureServlet {
|
||||
@Override
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String[] path = path(_req);
|
||||
if (path.length < 2) {
|
||||
_rep.setStatus(400);
|
||||
return;
|
||||
}
|
||||
int hub = DaoSerializer.toInteger(CollectionUtils.get(path, 0));
|
||||
int port = DaoSerializer.toInteger(CollectionUtils.get(path, 1));
|
||||
jsonResponse(_rep, Globals.dao.getLatestBreakerPower(_authCode.getAccountId(), hub, port));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void post(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
String[] path = path(_req);
|
||||
if ((path.length > 0) && NullUtils.isEqual(CollectionUtils.get(path, 0), "hub")) {
|
||||
Globals.dao.putHubPowerMinute(getRequestPayload(_req, HubPowerMinute.class));
|
||||
return;
|
||||
}
|
||||
if ((path.length > 0) && NullUtils.isEqual(CollectionUtils.get(path, 0), "batch")) {
|
||||
List<BreakerPower> powers = DaoSerializer.getList(getRequestZipBson(_req), "readings", BreakerPower.class);
|
||||
if (!powers.isEmpty()) {
|
||||
CollectionUtils.edit(powers, _p->_p.setAccountId(_authCode.getAccountId()));
|
||||
Globals.dao.getProxy().save(powers);
|
||||
}
|
||||
return;
|
||||
}
|
||||
BreakerPower power = getRequestPayload(_req, BreakerPower.class);
|
||||
power.setAccountId(_authCode.getAccountId());
|
||||
Globals.dao.putBreakerPower(power);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public abstract class SecureServlet extends CMServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
AuthCode authCode = Globals.dao.decryptAuthCode(_req.getHeader("auth_code"));
|
||||
if (authCode == null) {
|
||||
_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.dao.decryptAuthCode(_req.getHeader("auth_code"));
|
||||
if (authCode == null) {
|
||||
_rep.setStatus(401);
|
||||
return;
|
||||
}
|
||||
post(authCode, _req, _rep);
|
||||
}
|
||||
|
||||
protected void post(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Account;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.SignupResponse;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.DaoEntity;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.email.EmailValidator;
|
||||
import com.lanternsoftware.util.servlet.BasicAuth;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/signup")
|
||||
public class SignupServlet extends CMServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
BasicAuth auth = new BasicAuth(_req);
|
||||
Account acct = Globals.dao.getAccountByUsername(auth.getUsername());
|
||||
if (acct != null) {
|
||||
jsonResponse(_rep, SignupResponse.error("An account for " + auth.getUsername() + " already exists"));
|
||||
return;
|
||||
}
|
||||
if (!EmailValidator.getInstance().isValid(auth.getUsername())) {
|
||||
jsonResponse(_rep, SignupResponse.error(auth.getUsername() + " is not a valid email address"));
|
||||
return;
|
||||
}
|
||||
if (NullUtils.length(auth.getPassword()) < 8) {
|
||||
jsonResponse(_rep, SignupResponse.error("Your password must be at least 8 characters long"));
|
||||
return;
|
||||
}
|
||||
if (NullUtils.isEqual("password", auth.getPassword())) {
|
||||
jsonResponse(_rep, SignupResponse.error("Seriously? \"password\"? Come on."));
|
||||
return;
|
||||
}
|
||||
acct = new Account();
|
||||
acct.setUsername(auth.getUsername());
|
||||
acct.setPassword(auth.getPassword());
|
||||
Globals.dao.putAccount(acct);
|
||||
String authCode = Globals.dao.authenticateAccount(auth.getUsername(), auth.getPassword());
|
||||
jsonResponse(_rep, SignupResponse.success(authCode));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.lanternsoftware.currentmonitor.servlet;
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.File;
|
||||
|
||||
@WebServlet("/update/*")
|
||||
public class UpdateServlet extends CMServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
if (isPath(_req, 0, "version"))
|
||||
setResponseEntity(_rep, MediaType.APPLICATION_OCTET_STREAM, DaoSerializer.toZipBson(DaoSerializer.parse(ResourceLoader.loadFileAsString(LanternFiles.OPS_PATH + "release" + File.separator + "version.json"))));
|
||||
else
|
||||
setResponseEntity(_rep, MediaType.APPLICATION_OCTET_STREAM, ResourceLoader.loadFile(LanternFiles.OPS_PATH + "release" + File.separator + "lantern-currentmonitor.jar"));
|
||||
}
|
||||
}
|
|
@ -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="DEBUG"/>
|
||||
|
||||
<root level="OFF">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -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.currentmonitor.context.Globals</listener-class>
|
||||
</listener>
|
||||
</web-app>
|
|
@ -0,0 +1,25 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.CurrentMonitorDao;
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.MongoCurrentMonitorDao;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Account;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class CreateAccount {
|
||||
public static void main(String[] args) {
|
||||
CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
Account account = new Account();
|
||||
account.setId(1);
|
||||
account.setPassword("*redacted*");
|
||||
|
||||
account.setId(2);
|
||||
account.setUsername("admin@lanternsoftware.com");
|
||||
account.setPassword("*redacted*");
|
||||
|
||||
dao.putAccount(account);
|
||||
dao.shutdown();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.AuthCode;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.cryptography.AESTool;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
|
||||
public class CreateAuthCode {
|
||||
private static final AESTool aes = new AESTool(ResourceLoader.loadFile(LanternFiles.OPS_PATH + "authKey.dat"));
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(aes.encryptToBase64(DaoSerializer.toZipBson(new AuthCode(100, null))));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.ResourceLoader;
|
||||
import com.lanternsoftware.util.cryptography.AESTool;
|
||||
|
||||
public class CreateAuthKey {
|
||||
public static void main(String[] args) {
|
||||
ResourceLoader.writeFile(LanternFiles.OPS_PATH + "authKey.dat", AESTool.generateRandomSecretKey().getEncoded());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.CurrentMonitorDao;
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.MongoCurrentMonitorDao;
|
||||
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.BreakerPanel;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerPolarity;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Meter;
|
||||
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.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CreateBreakers {
|
||||
public static void main(String[] args) {
|
||||
CurrentMonitorDao dao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
|
||||
/* Breaker bf1 = new Breaker("Solar A", 2, 20, 0, 1, 50, 1.6);
|
||||
bf1.setPolarity(BreakerPolarity.SOLAR);
|
||||
Breaker bf2 = new Breaker("Solar B", 2, 18, 0, 2, 50, 1.6);
|
||||
bf2.setPolarity(BreakerPolarity.SOLAR);
|
||||
Breaker bf3 = new Breaker("Septic Agitator", 2, 11, 0, 3, 20, 1.6);
|
||||
Breaker bf4 = new Breaker("Garage/Guest Baths", 2, 5, 0, 4, 20, 1.6);
|
||||
Breaker bf5 = new Breaker("Office", 2, 2, 0, 5, 20, 1.6);
|
||||
Breaker bf6 = new Breaker("Upstairs Furnace R-A", 1, 2, 0, 6, 50, 1.6);
|
||||
Breaker bf7 = new Breaker("Upstairs Furnace R-B", 1, 4, 0, 7, 50, 1.6);
|
||||
Breaker bf8 = new Breaker("Upstairs Furnace R-C", 1, 6, 0, 8, 30, 1.6);
|
||||
Breaker bf9 = new Breaker("Upstairs Furnace R-D", 1, 8, 0, 9, 30, 1.6);
|
||||
Breaker bf10 = new Breaker("Upstairs Furnace HP-A", 1, 1, 0, 10, 30, 1.6);
|
||||
Breaker bf11 = new Breaker("Upstairs Furnace HP-B", 1, 3, 0, 11, 30, 1.6);
|
||||
Breaker bf12 = new Breaker("Dryer A", 2, 8, 0, 12, 30, 1.6);
|
||||
Breaker bf13 = new Breaker("Dryer B", 2, 10, 0, 13, 30, 1.6);
|
||||
Breaker bf2_1 = new Breaker("Main Furnace R-A", 0, 6, 1, 1, 50, 1.6);
|
||||
Breaker bf2_2 = new Breaker("Main Furnace R-B", 0, 8, 1, 2, 50, 1.6);
|
||||
Breaker bf2_3 = new Breaker("Main Furnace R-C", 0, 2, 1, 3, 50, 1.6);
|
||||
Breaker bf2_4 = new Breaker("Main Furnace R-D", 0, 4, 1, 4, 50, 1.6);
|
||||
Breaker bf2_5 = new Breaker("Main Furnace HP-A", 0, 1, 1, 5, 30, 1.6);
|
||||
Breaker bf2_6 = new Breaker("Main Furnace HP-B", 0, 3, 1, 6, 30, 1.6);
|
||||
Breaker bf2_7 = new Breaker("Hot Water Heater A", 0, 5, 1, 7, 30, 1.6);
|
||||
Breaker bf2_8 = new Breaker("Hot Water Heater B", 0, 7, 1, 8, 30, 1.6);
|
||||
Breaker bf2_9 = new Breaker("Basement HP-A", 1, 13, 1, 9, 30, 1.6);
|
||||
Breaker bf2_10 = new Breaker("Basement HP-B", 1, 15, 1, 10, 30, 1.6);
|
||||
Breaker bf2_11 = new Breaker("Oven A", 2, 12, 1, 11, 50, 1.6);
|
||||
Breaker bf2_12 = new Breaker("Oven B", 2, 14, 1, 12, 50, 1.6);
|
||||
Breaker bf2_13 = new Breaker("Master Bathroom", 3, 9, 2, 5, 20, 1.6);
|
||||
Breaker bf2_14 = new Breaker("Refrigerator", 2, 6, 1, 14, 20, 1.6);
|
||||
bf2_14.setSpaceTandemB(6);
|
||||
Breaker bf2_15 = new Breaker("Master Bedroom", 2, 1, 1, 15, 20, 1.6);
|
||||
BreakerGroup basementHP = new BreakerGroup("6", "Heat Pump", Arrays.asList(bf2_9, bf2_10));
|
||||
BreakerGroup basementCC = new BreakerGroup("3", "Basement", Arrays.asList(basementHP), null);
|
||||
BreakerGroup mainHP = new BreakerGroup("5", "Heat Pump", Arrays.asList(bf2_5, bf2_6));
|
||||
BreakerGroup mainR = new BreakerGroup("4", "Air Handler/Resistive", Arrays.asList(bf2_1, bf2_2, bf2_3, bf2_4));
|
||||
BreakerGroup mainCC = new BreakerGroup("2", "Main Floor", Arrays.asList(mainHP, mainR), null);
|
||||
BreakerGroup upstairsHP = new BreakerGroup("34", "Heat Pump", Arrays.asList(bf10, bf11));
|
||||
BreakerGroup upstairsR = new BreakerGroup("35", "Air Handler/Resistive", Arrays.asList(bf6, bf7, bf8, bf9));
|
||||
BreakerGroup upstairsCC = new BreakerGroup("36", "Upstairs", Arrays.asList(upstairsHP, upstairsR), null);
|
||||
BreakerGroup cc = new BreakerGroup("1", "Climate Control", Arrays.asList(mainCC, upstairsCC, basementCC), null);
|
||||
BreakerGroup hotWater = new BreakerGroup("7", "Hot Water Heater", Arrays.asList(bf2_7, bf2_8));
|
||||
BreakerGroup oven = new BreakerGroup("8", "Oven/Cooktop", Arrays.asList(bf2_11, bf2_12));
|
||||
BreakerGroup masterBR = new BreakerGroup("9", "Master Bedroom", Arrays.asList(bf2_13, bf2_15));
|
||||
BreakerGroup fridge = new BreakerGroup("10", "Refrigerator", Arrays.asList(bf2_14));
|
||||
BreakerGroup solar = new BreakerGroup("11", "Solar", Arrays.asList(bf1, bf2));
|
||||
BreakerGroup septic = new BreakerGroup("13", "Septic Aerator", Arrays.asList(bf3));
|
||||
BreakerGroup garage = new BreakerGroup("14", "Garage/Guest Baths", Arrays.asList(bf4));
|
||||
BreakerGroup office = new BreakerGroup("15", "Office", Arrays.asList(bf5));
|
||||
BreakerGroup dryer = new BreakerGroup("37", "Dryer", Arrays.asList(bf12, bf13));
|
||||
Breaker bf3_1 = new Breaker("Hub 2 Port 1", 3, 1, 2, 1, 20, 1.6);
|
||||
Breaker bf3_2 = new Breaker("Hub 2 Port 2", 3, 3, 2, 2, 20, 1.6);
|
||||
Breaker bf3_3 = new Breaker("Hub 2 Port 3", 3, 5, 2, 3, 20, 1.6);
|
||||
Breaker bf3_4 = new Breaker("Hub 2 Port 4", 3, 7, 2, 4, 20, 1.6);
|
||||
Breaker bf3_6 = new Breaker("Hub 2 Port 6", 3, 11, 2, 6, 20, 1.6);
|
||||
Breaker bf3_7 = new Breaker("Hub 2 Port 7", 3, 13, 2, 7, 20, 1.6);
|
||||
Breaker bf3_8 = new Breaker("Hub 2 Port 8", 3, 15, 2, 8, 20, 1.6);
|
||||
Breaker bf3_9 = new Breaker("Hub 2 Port 9", 3, 2, 2, 9, 20, 1.6);
|
||||
Breaker bf3_10 = new Breaker("Hub 2 Port 10", 3, 4, 2, 10, 20, 1.6);
|
||||
Breaker bf3_12 = new Breaker("Hub 2 Port 12", 3, 6, 2, 12, 20, 1.6);
|
||||
Breaker bf3_13 = new Breaker("Hub 2 Port 13", 3, 8, 2, 13, 20, 1.6);
|
||||
Breaker bf3_14 = new Breaker("Hub 2 Port 14", 3, 10, 2, 14, 20, 1.6);
|
||||
BreakerGroup g1 = new BreakerGroup("17", "Living Room/Printer/Outdoor Lights", Arrays.asList(bf3_1));
|
||||
BreakerGroup g2 = new BreakerGroup("18", "Dishwasher/Disposal/Sink Lights", Arrays.asList(bf3_2));
|
||||
BreakerGroup g3 = new BreakerGroup("19", "Microwave", Arrays.asList(bf3_3));
|
||||
BreakerGroup g4 = new BreakerGroup("20", "Kitchen Outlets", Arrays.asList(bf3_4));
|
||||
// BreakerGroup g5 = new BreakerGroup("21", "Hub 2 Port 5", Arrays.asList(bf3_5));
|
||||
BreakerGroup g6 = new BreakerGroup("22", "Mini Fridge", Arrays.asList(bf3_6));
|
||||
BreakerGroup g7 = new BreakerGroup("23", "Basement Lights/Outlets", Arrays.asList(bf3_7));
|
||||
BreakerGroup g8 = new BreakerGroup("24", "Theatre", Arrays.asList(bf3_8));
|
||||
BreakerGroup g9 = new BreakerGroup("25", "Sunroom Fan/Outside Floods", Arrays.asList(bf3_9));
|
||||
BreakerGroup g10 = new BreakerGroup("26", "Radon/Deep Freezer", Arrays.asList(bf3_10));
|
||||
// BreakerGroup g11 = new BreakerGroup("27", "Hub 2 Port 11", Arrays.asList(bf3_11));
|
||||
BreakerGroup g12 = new BreakerGroup("28", "Kitchen Lights", Arrays.asList(bf3_12));
|
||||
BreakerGroup g13 = new BreakerGroup("29", "Router/Networking", Arrays.asList(bf3_13));
|
||||
BreakerGroup g14 = new BreakerGroup("30", "Half Bath/Utility/Garage Lights", Arrays.asList(bf3_14));
|
||||
// BreakerGroup g15 = new BreakerGroup("31", "Bar Outlets", Arrays.asList(bf3_15));
|
||||
BreakerGroup kitchen = new BreakerGroup("33", "Kitchen", Arrays.asList(oven, fridge, g2, g3, g4, g12), null);
|
||||
|
||||
Breaker b4_1 = new Breaker("Hub 3 Port 1", 4, 1, 3, 1, 20, 1.6);
|
||||
Breaker b4_2 = new Breaker("Hub 3 Port 2", 4, 2, 3, 2, 30, 1.6);
|
||||
Breaker b4_3 = new Breaker("Hub 3 Port 3", 4, 3, 3, 3, 50, 1.6);
|
||||
Breaker b4_4 = new Breaker("Hub 3 Port 4", 4, 4, 3, 4, 20, 1.6);
|
||||
Breaker b4_5 = new Breaker("Hub 3 Port 5", 4, 5, 3, 5, 20, 1.6);
|
||||
Breaker b4_6 = new Breaker("Hub 3 Port 6", 4, 6, 3, 6, 20, 1.6);
|
||||
Breaker b4_7 = new Breaker("Hub 3 Port 7", 4, 7, 3, 7, 20, 1.6);
|
||||
Breaker b4_8 = new Breaker("Hub 3 Port 8", 4, 8, 3, 8, 20, 1.6);
|
||||
Breaker b4_9 = new Breaker("Hub 3 Port 9", 4, 9, 3, 9, 20, 1.6);
|
||||
Breaker b4_10 = new Breaker("Hub 3 Port 10", 4, 10, 3, 10, 20, 1.6);
|
||||
Breaker b4_11 = new Breaker("Hub 3 Port 11", 4, 11, 3, 11, 20, 1.6);
|
||||
Breaker b4_12 = new Breaker("Hub 3 Port 12", 4, 12, 3, 12, 20, 1.6);
|
||||
Breaker b4_13 = new Breaker("Hub 3 Port 13", 4, 13, 3, 13, 20, 1.6);
|
||||
Breaker b4_14 = new Breaker("Hub 3 Port 14", 4, 14, 3, 14, 20, 1.6);
|
||||
Breaker b4_15 = new Breaker("Hub 3 Port 15", 4, 15, 3, 15, 20, 1.6);
|
||||
BreakerGroup g4_1 = new BreakerGroup("41", "Hub 3 Port 1", Arrays.asList(b4_1));
|
||||
BreakerGroup g4_2 = new BreakerGroup("42", "Hub 3 Port 2", Arrays.asList(b4_2));
|
||||
BreakerGroup g4_3 = new BreakerGroup("43", "Hub 3 Port 3", Arrays.asList(b4_3));
|
||||
BreakerGroup g4_4 = new BreakerGroup("44", "Hub 3 Port 4", Arrays.asList(b4_4));
|
||||
BreakerGroup g4_5 = new BreakerGroup("45", "Hub 3 Port 5", Arrays.asList(b4_5));
|
||||
BreakerGroup g4_6 = new BreakerGroup("46", "Hub 3 Port 6", Arrays.asList(b4_6));
|
||||
BreakerGroup g4_7 = new BreakerGroup("47", "Hub 3 Port 7", Arrays.asList(b4_7));
|
||||
BreakerGroup g4_8 = new BreakerGroup("48", "Hub 3 Port 8", Arrays.asList(b4_8));
|
||||
BreakerGroup g4_9 = new BreakerGroup("49", "Hub 3 Port 9", Arrays.asList(b4_9));
|
||||
BreakerGroup g4_10 = new BreakerGroup("50", "Hub 3 Port 10", Arrays.asList(b4_10));
|
||||
BreakerGroup g4_11 = new BreakerGroup("51", "Hub 3 Port 11", Arrays.asList(b4_11));
|
||||
BreakerGroup g4_12 = new BreakerGroup("52", "Hub 3 Port 12", Arrays.asList(b4_12));
|
||||
BreakerGroup g4_13 = new BreakerGroup("53", "Hub 3 Port 13", Arrays.asList(b4_13));
|
||||
BreakerGroup g4_14 = new BreakerGroup("54", "Hub 3 Port 14", Arrays.asList(b4_14));
|
||||
BreakerGroup g4_15 = new BreakerGroup("55", "Hub 3 Port 15", Arrays.asList(b4_15));
|
||||
BreakerGroup debug = new BreakerGroup("40", "Debug Hub 3", Arrays.asList(g4_1, g4_2, g4_3), null);
|
||||
// BreakerGroup debug = new BreakerGroup("40", "Debug Hub 3", Arrays.asList(g4_1, g4_2, g4_3, g4_4, g4_5, g4_6, g4_7, g4_8, g4_9, g4_10, g4_11, g4_12, g4_13, g4_14, g4_15), null);
|
||||
// BreakerGroup debug = new BreakerGroup("40", "Debug Hub 3", Arrays.asList(b4_1));
|
||||
|
||||
|
||||
BreakerGroup house = new BreakerGroup("0", "*redacted*", Arrays.asList(solar, cc, hotWater, dryer, septic, masterBR, garage, office, kitchen, g1, g6, g7, g8, g9, g10, g13, g14, debug), null);
|
||||
BreakerConfig config = new BreakerConfig(Collections.singletonList(house));
|
||||
CollectionUtils.edit(config.getAllBreakerGroups(), _g->_g.setAccountId(1));
|
||||
CollectionUtils.edit(config.getAllBreakers(), _b->{
|
||||
_b.setAccountId(1);
|
||||
_b.setCalibrationFactor(1.0);
|
||||
});
|
||||
b4_1.setCalibrationFactor(1.215);
|
||||
b4_2.setCalibrationFactor(1.215);
|
||||
b4_3.setCalibrationFactor(1.215);
|
||||
config.setAccountId(1);
|
||||
BreakerHub hub0 = new BreakerHub();
|
||||
hub0.setHub(0);
|
||||
hub0.setVoltageCalibrationFactor(0.4587);
|
||||
hub0.setFrequency(60);
|
||||
BreakerHub hub1 = new BreakerHub();
|
||||
hub1.setHub(1);
|
||||
hub1.setVoltageCalibrationFactor(0.439);
|
||||
hub1.setFrequency(60);
|
||||
BreakerHub hub2 = new BreakerHub();
|
||||
hub2.setHub(2);
|
||||
hub2.setVoltageCalibrationFactor(0.3535);
|
||||
hub2.setFrequency(60);
|
||||
BreakerHub hub3 = new BreakerHub();
|
||||
hub3.setHub(3);
|
||||
hub3.setVoltageCalibrationFactor(0.419);
|
||||
hub3.setFrequency(60);
|
||||
config.setBreakerHubs(Arrays.asList(hub0, hub1, hub2, hub3));
|
||||
|
||||
Meter heatMeter = new Meter();
|
||||
heatMeter.setAccountId(1);
|
||||
heatMeter.setIndex(0);
|
||||
heatMeter.setName("Heat");
|
||||
|
||||
Meter mainMeter = new Meter();
|
||||
mainMeter.setAccountId(1);
|
||||
mainMeter.setIndex(1);
|
||||
mainMeter.setName("Main/Solar");
|
||||
|
||||
config.setMeters(CollectionUtils.asArrayList(heatMeter, mainMeter));
|
||||
|
||||
BreakerPanel heat1 = new BreakerPanel();
|
||||
heat1.setAccountId(1);
|
||||
heat1.setIndex(0);
|
||||
heat1.setMeter(heatMeter.getIndex());
|
||||
heat1.setName("Heat 1");
|
||||
heat1.setSpaces(20);
|
||||
|
||||
BreakerPanel heat2 = new BreakerPanel();
|
||||
heat2.setAccountId(1);
|
||||
heat2.setIndex(1);
|
||||
heat2.setMeter(heatMeter.getIndex());
|
||||
heat2.setName("Heat 2");
|
||||
heat2.setSpaces(20);
|
||||
|
||||
BreakerPanel main = new BreakerPanel();
|
||||
main.setAccountId(1);
|
||||
main.setIndex(2);
|
||||
main.setMeter(mainMeter.getIndex());
|
||||
main.setName("Main");
|
||||
main.setSpaces(20);
|
||||
|
||||
BreakerPanel sub = new BreakerPanel();
|
||||
sub.setAccountId(1);
|
||||
sub.setIndex(3);
|
||||
sub.setMeter(mainMeter.getIndex());
|
||||
sub.setName("Sub-Panel");
|
||||
sub.setSpaces(20);
|
||||
|
||||
config.setPanels(CollectionUtils.asArrayList(heat1, heat2, main, sub));
|
||||
|
||||
Map<Integer, Integer> panelToMeter = CollectionUtils.transformToMap(config.getPanels(), BreakerPanel::getIndex, BreakerPanel::getMeter);
|
||||
CollectionUtils.edit(config.getAllBreakers(), _b->_b.setMeter(DaoSerializer.toInteger(panelToMeter.get(_b.getPanel()))));*/
|
||||
|
||||
BreakerConfig config = dao.getConfig(1);
|
||||
// BreakerConfig config = DaoSerializer.parse(ResourceLoader.loadFileAsString(LanternFiles.OPS_PATH + "breakerconfig_backup_210107.json"), BreakerConfig.class);
|
||||
// ResourceLoader.writeFile(LanternFiles.OPS_PATH + "breakerconfig_backup_210107.json", DaoSerializer.toJson(config));
|
||||
// CollectionUtils.edit(config.getAllBreakerGroups(), _g->{
|
||||
// if (NullUtils.isEmpty(_g.getName())) {
|
||||
// Breaker b = CollectionUtils.getFirst(_g.getBreakers());
|
||||
// if (b != null)
|
||||
// _g.setName(String.format("Panel %d, %s", b.getPanel(), b.getName()));
|
||||
// }
|
||||
// });
|
||||
// for (BreakerGroup group : CollectionUtils.filter(config.getAllBreakerGroups(), _g->NullUtils.isEmpty(_g.getId()))) {
|
||||
// List<Integer> ids = CollectionUtils.transform(config.getAllBreakerGroupIds(), NullUtils::toInteger);
|
||||
// group.setId(String.valueOf(CollectionUtils.getLargest(ids) + 1));
|
||||
// }
|
||||
// BreakerGroup root = CollectionUtils.getFirst(config.getBreakerGroups());
|
||||
// root.getSubGroups().removeIf(_g->_g.getName().equals("Debug Hub 3"));
|
||||
// config.removeInvalidGroups();
|
||||
// for (BreakerGroup group : config.getAllBreakerGroups()) {
|
||||
// if (NullUtils.isEmpty(group.getId())) {
|
||||
// List<Integer> ids = CollectionUtils.transform(config.getAllBreakerGroupIds(), NullUtils::toInteger);
|
||||
// group.setId(String.valueOf(CollectionUtils.getLargest(ids) + 1));
|
||||
// }
|
||||
// }
|
||||
dao.putConfig(config);
|
||||
dao.shutdown();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
|
||||
public class CreateMongoConfig {
|
||||
public static void main(String[] args) {
|
||||
new MongoConfig("localhost", "*redacted*", "*redacted*", "CURRENT_MONITOR").saveToDisk(LanternFiles.OPS_PATH + "mongo.cfg");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.generator.DaoSerializerGenerator;
|
||||
import com.lanternsoftware.util.dao.generator.SwiftModelGenerator;
|
||||
|
||||
public class CurrentMonitorSerializers {
|
||||
public static void main(String[] args) {
|
||||
DaoSerializerGenerator.generateSerializers(LanternFiles.SOURCE_PATH + "currentmonitor", true, null);
|
||||
SwiftModelGenerator.generateModel(LanternFiles.SOURCE_PATH + "currentmonitor", LanternFiles.SOURCE_PATH + "iOS");
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user