mirror of
https://github.com/zyphlar/LanternPowerMonitor.git
synced 2024-03-08 14:07:47 +00:00
Migrating from from wiringpi to pigpio. This increases the sample rate by a factor of 3 and will allow creation of a board that can monitor over 30 breakers with a single raspberry pi.
This is based on pi4j 2.0 which is in a beta status. I have fixed a few bugs in a local version of pi4j 2.0 to get it to work but I haven't submitted those changes to pi4j yet. This change requires a migration to Java 11 and will *NOT* be backwards compatible. Upgrading to this hub software will require that java 11 and pigpio be installed on the hub. This can be done from an ssh session with the following commands: apt-get update apt-get install openjdk-11-jre-headless apt-get install pigpio Alternatively, you can download a new sd image, reflash your sd card, and re-adopt your hub.
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
<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.7</version>
|
||||
<version>1.1.0</version>
|
||||
<name>lantern-currentmonitor</name>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
<parent>
|
||||
<groupId>com.lanternsoftware.currentmonitor</groupId>
|
||||
<artifactId>currentmonitor</artifactId>
|
||||
<version>1.1.0</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -24,8 +24,13 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pi4j</groupId>
|
||||
<artifactId>pi4j-gpio-extension</artifactId>
|
||||
<version>1.3</version>
|
||||
<artifactId>pi4j-core</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pi4j</groupId>
|
||||
<artifactId>pi4j-plugin-pigpio</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.hypfvieh</groupId>
|
||||
@@ -35,12 +40,12 @@
|
||||
<dependency>
|
||||
<groupId>com.lanternsoftware.currentmonitor</groupId>
|
||||
<artifactId>lantern-datamodel-currentmonitor</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>${cm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.lanternsoftware.util</groupId>
|
||||
<artifactId>lantern-util-http</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>${util.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
@@ -71,8 +76,8 @@
|
||||
<optimize>true</optimize>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.adc.MCP3008Pin;
|
||||
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 MCP3008Pin voltagePin;
|
||||
private final MCP3008Pin currentPin;
|
||||
private final List<PowerSample> samples;
|
||||
private int cycleCnt;
|
||||
private int sampleCnt;
|
||||
|
||||
public BreakerSamples(Breaker _breaker, GpioPinAnalogInput _voltagePin, GpioPinAnalogInput _currentPin, List<PowerSample> _samples) {
|
||||
public BreakerSamples(Breaker _breaker, MCP3008Pin _voltagePin, MCP3008Pin _currentPin, List<PowerSample> _samples) {
|
||||
breaker = _breaker;
|
||||
voltagePin = _voltagePin;
|
||||
currentPin = _currentPin;
|
||||
@@ -23,11 +24,11 @@ public class BreakerSamples {
|
||||
return breaker;
|
||||
}
|
||||
|
||||
public GpioPinAnalogInput getVoltagePin() {
|
||||
public MCP3008Pin getVoltagePin() {
|
||||
return voltagePin;
|
||||
}
|
||||
|
||||
public GpioPinAnalogInput getCurrentPin() {
|
||||
public MCP3008Pin getCurrentPin() {
|
||||
return currentPin;
|
||||
}
|
||||
|
||||
@@ -35,8 +36,20 @@ public class BreakerSamples {
|
||||
return samples;
|
||||
}
|
||||
|
||||
public PowerSample getSample(int _sample) {
|
||||
return samples.get(_sample);
|
||||
public void incrementCycleCnt() {
|
||||
cycleCnt++;
|
||||
}
|
||||
|
||||
public PowerSample incrementSample() {
|
||||
return samples.get(sampleCnt++);
|
||||
}
|
||||
|
||||
public int getCycleCnt() {
|
||||
return cycleCnt;
|
||||
}
|
||||
|
||||
public void setCycleCnt(int _cycleCnt) {
|
||||
cycleCnt = _cycleCnt;
|
||||
}
|
||||
|
||||
public int getSampleCnt() {
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
package com.lanternsoftware.currentmonitor;
|
||||
|
||||
import com.lanternsoftware.currentmonitor.adc.MCP3008;
|
||||
import com.lanternsoftware.currentmonitor.adc.MCP3008Pin;
|
||||
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 com.pi4j.Pi4J;
|
||||
import com.pi4j.context.Context;
|
||||
import com.pi4j.io.spi.Spi;
|
||||
import com.pi4j.io.spi.SpiMode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
@@ -30,22 +27,15 @@ 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 Context pi4j;
|
||||
private final Map<Integer, MCP3008> chips = 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);
|
||||
}
|
||||
pi4j = Pi4J.newAutoContext();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
@@ -53,9 +43,12 @@ public class CurrentMonitor {
|
||||
ConcurrencyUtils.sleep(1000);
|
||||
executor.shutdown();
|
||||
ConcurrencyUtils.sleep(1000);
|
||||
for (MCP3008 mcp : chips.values()) {
|
||||
mcp.shutdown(pi4j);
|
||||
}
|
||||
ConcurrencyUtils.sleep(1000);
|
||||
pi4j.shutdown();
|
||||
chips.clear();
|
||||
pins.clear();
|
||||
gpio.shutdown();
|
||||
LOG.info("Power Monitor Service Stopped");
|
||||
}
|
||||
|
||||
@@ -64,10 +57,9 @@ public class CurrentMonitor {
|
||||
}
|
||||
|
||||
public CalibrationResult calibrateVoltage(double _curCalibration) {
|
||||
GpioPinAnalogInput voltagePin = getPin(0, 0);
|
||||
if (voltagePin == null)
|
||||
return null;
|
||||
int maxSamples = 120000;
|
||||
LOG.info("Calibrating Voltage");
|
||||
MCP3008Pin voltagePin = new MCP3008Pin(getChip(0), 0);
|
||||
int maxSamples = 240000;
|
||||
CalibrationSample[] samples = new CalibrationSample[maxSamples];
|
||||
int offset = 0;
|
||||
for (;offset < maxSamples; offset++) {
|
||||
@@ -77,7 +69,7 @@ public class CurrentMonitor {
|
||||
long intervalEnd = System.nanoTime() + 2000000000L; //Scan voltage for 2 seconds
|
||||
while (offset < maxSamples) {
|
||||
samples[offset].time = System.nanoTime();
|
||||
samples[offset].voltage = voltagePin.getValue();
|
||||
samples[offset].voltage = voltagePin.read();
|
||||
offset++;
|
||||
if (samples[offset-1].time > intervalEnd)
|
||||
break;
|
||||
@@ -128,10 +120,12 @@ public class CurrentMonitor {
|
||||
stopMonitoring();
|
||||
listener = _listener;
|
||||
List<Breaker> validBreakers = CollectionUtils.filter(_breakers, _b -> _b.getPort() > 0 && _b.getPort() < 16);
|
||||
if (CollectionUtils.isEmpty(validBreakers))
|
||||
if (CollectionUtils.isEmpty(validBreakers)) {
|
||||
LOG.error("No breakers found for hub number {}", _hub.getHub());
|
||||
return;
|
||||
}
|
||||
LOG.info("Monitoring {} breakers for hub {}", CollectionUtils.size(validBreakers), _hub.getHub());
|
||||
sampler = new Sampler(_hub, validBreakers, _intervalMs, 2);
|
||||
sampler = new Sampler(_hub, validBreakers, _intervalMs, 5);
|
||||
LOG.info("Starting to monitor ports {}", CollectionUtils.transformToCommaSeparated(validBreakers, _b -> String.valueOf(_b.getPort())));
|
||||
executor.submit(sampler);
|
||||
}
|
||||
@@ -140,34 +134,17 @@ public class CurrentMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
private synchronized MCP3008 getChip(int _chip) {
|
||||
MCP3008 chip = chips.get(_chip);
|
||||
if (chip == null) {
|
||||
String id = "SPI" + _chip;
|
||||
LOG.info("Creating chip {}", id);
|
||||
Spi spi = pi4j.create(Spi.newConfigBuilder(pi4j).mode(SpiMode.MODE_0).id(id).name("MCP3008_" + _chip).address(_chip).baud(810000).build());
|
||||
LOG.info("is open {}", spi.isOpen());
|
||||
chip = new MCP3008(spi);
|
||||
chips.put(_chip, chip);
|
||||
}
|
||||
return pin;
|
||||
}
|
||||
|
||||
private Integer pinKey(int _chip, int _pin) {
|
||||
return (_chip*8)+_pin;
|
||||
return chip;
|
||||
}
|
||||
|
||||
public void submit(Runnable _runnable) {
|
||||
@@ -190,14 +167,14 @@ public class CurrentMonitor {
|
||||
|
||||
public Sampler(BreakerHub _hub, List<Breaker> _breakers, int _intervalMs, int _concurrentBreakerCnt) {
|
||||
hub = _hub;
|
||||
GpioPinAnalogInput voltagePin = getPin(0, 0);
|
||||
MCP3008Pin voltagePin = new MCP3008Pin(getChip(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());
|
||||
MCP3008Pin currentPin = new MCP3008Pin(getChip(_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++) {
|
||||
for (int j=0; j<60000/_breakers.size(); j++) {
|
||||
samples.add(new PowerSample());
|
||||
}
|
||||
batches.add(new BreakerSamples(_b, voltagePin, currentPin, samples));
|
||||
@@ -213,6 +190,7 @@ public class CurrentMonitor {
|
||||
long start = System.nanoTime();
|
||||
long interval = 0;
|
||||
int cycle;
|
||||
int curBreaker;
|
||||
BreakerSamples[] cycleBreakers = new BreakerSamples[concurrentBreakerCnt];
|
||||
try {
|
||||
while (true) {
|
||||
@@ -227,22 +205,18 @@ public class CurrentMonitor {
|
||||
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);
|
||||
cycleBreakers[curBreaker].incrementCycleCnt();
|
||||
}
|
||||
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);
|
||||
PowerSample sample = cycleBreakers[curBreaker].incrementSample();
|
||||
sample.voltage = cycleBreakers[curBreaker].getVoltagePin().read();
|
||||
sample.current = cycleBreakers[curBreaker].getCurrentPin().read();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,10 +258,11 @@ public class CurrentMonitor {
|
||||
if (debug) {
|
||||
synchronized (CurrentMonitor.this) {
|
||||
LOG.info("===========================Start Port {}", samples.getBreaker().getPort());
|
||||
LOG.info("Cycles: {}", samples.getCycleCnt());
|
||||
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)));
|
||||
double iRms = hub.getPortCalibrationFactor() * 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;
|
||||
@@ -298,6 +273,8 @@ public class CurrentMonitor {
|
||||
LOG.info("===========================End Port {}", samples.getBreaker().getPort());
|
||||
}
|
||||
}
|
||||
samples.setSampleCnt(0);
|
||||
samples.setCycleCnt(0);
|
||||
listener.onPowerEvent(new BreakerPower(samples.getBreaker().getPanel(), samples.getBreaker().getSpace(), readTime, realPower, vRms));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -35,12 +35,9 @@ 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.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
@@ -210,8 +207,8 @@ public class MonitorApp {
|
||||
version = getVersionNumber();
|
||||
config = DaoSerializer.parse(ResourceLoader.loadFileAsString(WORKING_DIR + "config.json"), MonitorConfig.class);
|
||||
if (config == null) {
|
||||
LOG.error("Failed to load config file from {}", WORKING_DIR + "config.json");
|
||||
return;
|
||||
config = new MonitorConfig();
|
||||
ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config));
|
||||
}
|
||||
pool = new HttpPool(10, 10, config.getSocketTimeout(), config.getConnectTimeout(), config.getSocketTimeout());
|
||||
if (NullUtils.isNotEmpty(config.getHost()))
|
||||
@@ -219,8 +216,6 @@ public class MonitorApp {
|
||||
monitor.setDebug(config.isDebug());
|
||||
monitor.start();
|
||||
LEDFlasher.setLEDOn(false);
|
||||
bluetoothConfig = new BluetoothConfig("Lantern Hub", bluetoothListener);
|
||||
bluetoothConfig.start();
|
||||
if (NullUtils.isNotEmpty(config.getAuthCode()))
|
||||
authCode = config.getAuthCode();
|
||||
else if (NullUtils.isNotEmpty(host) && NullUtils.isNotEmpty(config.getUsername()) && NullUtils.isNotEmpty(config.getPassword())) {
|
||||
@@ -231,7 +226,8 @@ public class MonitorApp {
|
||||
if (NullUtils.isNotEmpty(config.getMqttBrokerUrl()))
|
||||
mqttPoster = new MqttPoster(config);
|
||||
if (NullUtils.isNotEmpty(host) && NullUtils.isNotEmpty(authCode)) {
|
||||
while (true) {
|
||||
int configAttempts = 0;
|
||||
while (configAttempts < 5) {
|
||||
HttpGet get = new HttpGet(host + "config");
|
||||
get.addHeader("auth_code", authCode);
|
||||
breakerConfig = DaoSerializer.parse(pool.executeToString(get), BreakerConfig.class);
|
||||
@@ -239,8 +235,11 @@ public class MonitorApp {
|
||||
break;
|
||||
LOG.error("Failed to load breaker config. Retrying in 5 seconds...");
|
||||
ConcurrencyUtils.sleep(5000);
|
||||
configAttempts++;
|
||||
}
|
||||
}
|
||||
bluetoothConfig = new BluetoothConfig("Lantern Hub", bluetoothListener);
|
||||
bluetoothConfig.start();
|
||||
if ((mqttPoster != null) && (breakerConfig == null)) {
|
||||
LOG.info("Hub not configured by a Lantern Power Monitor server, defaulting to MQTT mode only");
|
||||
BreakerHub hub = new BreakerHub();
|
||||
@@ -266,13 +265,18 @@ public class MonitorApp {
|
||||
BreakerHub hub = breakerConfig.getHub(config.getHub());
|
||||
if (hub != null) {
|
||||
if (config.isNeedsCalibration()) {
|
||||
CalibrationResult cal = monitor.calibrateVoltage(hub.getVoltageCalibrationFactor());
|
||||
if (cal != null) {
|
||||
hub.setVoltageCalibrationFactor(cal.getVoltageCalibrationFactor());
|
||||
hub.setFrequency(cal.getFrequency());
|
||||
config.setNeedsCalibration(false);
|
||||
ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config));
|
||||
post(DaoSerializer.toZipBson(breakerConfig), "config");
|
||||
try {
|
||||
CalibrationResult cal = monitor.calibrateVoltage(hub.getVoltageCalibrationFactor());
|
||||
if (cal != null) {
|
||||
hub.setVoltageCalibrationFactor(cal.getVoltageCalibrationFactor());
|
||||
hub.setFrequency(cal.getFrequency());
|
||||
config.setNeedsCalibration(false);
|
||||
ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config));
|
||||
post(DaoSerializer.toZipBson(breakerConfig), "config");
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.error("Exception trying to read from voltage pin", t);
|
||||
}
|
||||
}
|
||||
List<Breaker> breakers = breakerConfig.getBreakersForHub(config.getHub());
|
||||
@@ -288,18 +292,10 @@ public class MonitorApp {
|
||||
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;
|
||||
}
|
||||
try {
|
||||
monitor.wait();
|
||||
} catch (InterruptedException _e) {
|
||||
LOG.error("Interrupted, shutting down", _e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +356,7 @@ public class MonitorApp {
|
||||
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);
|
||||
ResourceLoader.writeFile(WORKING_DIR + "cache/" + UUID.randomUUID() + ".min", payload);
|
||||
}
|
||||
}
|
||||
if (post != null) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.lanternsoftware.currentmonitor;
|
||||
|
||||
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
||||
import com.lanternsoftware.util.NullUtils;
|
||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||
|
||||
import java.util.List;
|
||||
@@ -12,11 +13,11 @@ public class MonitorConfig {
|
||||
private String authCode;
|
||||
private String username;
|
||||
private String password;
|
||||
private int hub;
|
||||
private int hub = -1;
|
||||
private boolean debug;
|
||||
private int connectTimeout;
|
||||
private int socketTimeout;
|
||||
private boolean needsCalibration;
|
||||
private boolean needsCalibration = true;
|
||||
private String mqttBrokerUrl;
|
||||
private String mqttUserName;
|
||||
private String mqttPassword;
|
||||
@@ -34,7 +35,7 @@ public class MonitorConfig {
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
return NullUtils.isEmpty(host) ? "https://lanternpowermonitor.com/" : host;
|
||||
}
|
||||
|
||||
public void setHost(String _host) {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.lanternsoftware.currentmonitor.adc;
|
||||
|
||||
import com.pi4j.context.Context;
|
||||
import com.pi4j.io.spi.Spi;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class MCP3008 {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MCP3008.class);
|
||||
private static final byte[][] pins = new byte[8][];
|
||||
|
||||
private final Spi spi;
|
||||
private final byte[] resp = new byte[3];
|
||||
|
||||
static {
|
||||
for (int p = 0; p < 8; p++) {
|
||||
pins[p] = new byte[]{1,(byte)(p + 8 << 4),0};
|
||||
}
|
||||
}
|
||||
|
||||
public MCP3008(Spi _spi) {
|
||||
spi = _spi;
|
||||
}
|
||||
|
||||
public void shutdown(Context _pi4j) {
|
||||
spi.close();
|
||||
spi.shutdown(_pi4j);
|
||||
}
|
||||
|
||||
public int readPin(int _pin) {
|
||||
if (spi.transfer(pins[_pin], resp) > 2) {
|
||||
return ((resp[1] & 0x03) << 8) + (resp[2] & 0xFF);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.lanternsoftware.currentmonitor.adc;
|
||||
|
||||
public class MCP3008Pin {
|
||||
private final MCP3008 chip;
|
||||
private final int pin;
|
||||
|
||||
public MCP3008Pin(MCP3008 _chip, int _pin) {
|
||||
chip = _chip;
|
||||
pin = _pin;
|
||||
}
|
||||
|
||||
public int read() {
|
||||
return chip.readPin(pin);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
</appender>
|
||||
|
||||
<logger name="com.lanternsoftware" level="INFO"/>
|
||||
<logger name="com.pi4j" level="INFO"/>
|
||||
|
||||
<root level="OFF">
|
||||
<appender-ref ref="FILE"/>
|
||||
|
||||
Reference in New Issue
Block a user