Implement 3-phase voltage logic.

This commit is contained in:
Mark Milligan
2022-08-20 21:20:50 -05:00
parent 1369529e8d
commit e0d4dafd3a
34 changed files with 591 additions and 117 deletions

View File

@@ -21,6 +21,7 @@ public class Breaker implements IIdentical<Breaker> {
private String name;
private String description;
private int sizeAmps;
private int phaseOffsetNs;
private double calibrationFactor;
private double lowPassFilter;
private BreakerPolarity polarity;
@@ -140,6 +141,14 @@ public class Breaker implements IIdentical<Breaker> {
sizeAmps = _sizeAmps;
}
public int getPhaseOffsetNs() {
return phaseOffsetNs;
}
public void setPhaseOffsetNs(int _phaseOffsetNs) {
phaseOffsetNs = _phaseOffsetNs;
}
public double getLowPassFilter() {
return Math.abs(lowPassFilter) < 0.05 ? 1.6 : lowPassFilter;
}
@@ -278,7 +287,7 @@ public class Breaker implements IIdentical<Breaker> {
@Override
public boolean isIdentical(Breaker _o) {
if (this == _o) return true;
return panel == _o.panel && space == _o.space && meter == _o.meter && hub == _o.hub && port == _o.port && sizeAmps == _o.sizeAmps && Double.compare(_o.calibrationFactor, calibrationFactor) == 0 && Double.compare(_o.lowPassFilter, lowPassFilter) == 0 && doublePower == _o.doublePower && Objects.equals(name, _o.name) && Objects.equals(description, _o.description) && polarity == _o.polarity && type == _o.type;
return panel == _o.panel && space == _o.space && meter == _o.meter && hub == _o.hub && port == _o.port && sizeAmps == _o.sizeAmps && phaseOffsetNs == _o.phaseOffsetNs && Double.compare(_o.calibrationFactor, calibrationFactor) == 0 && Double.compare(_o.lowPassFilter, lowPassFilter) == 0 && doublePower == _o.doublePower && Objects.equals(name, _o.name) && Objects.equals(description, _o.description) && polarity == _o.polarity && type == _o.type;
}
@Override

View File

@@ -11,6 +11,8 @@ public class BreakerHub implements IIdentical<BreakerHub> {
private int hub;
private double voltageCalibrationFactor;
private double portCalibrationFactor;
private int phaseCnt;
private int phaseOffsetNs;
private int frequency;
private String bluetoothMac;
@@ -46,8 +48,24 @@ public class BreakerHub implements IIdentical<BreakerHub> {
portCalibrationFactor = _portCalibrationFactor;
}
public int getPhaseCnt() {
return phaseCnt == 0 ? 2 : phaseCnt;
}
public void setPhaseCnt(int _phaseCnt) {
phaseCnt = _phaseCnt;
}
public int getPhaseOffsetNs() {
return phaseOffsetNs;
}
public void setPhaseOffsetNs(int _phaseOffsetNs) {
phaseOffsetNs = _phaseOffsetNs;
}
public int getFrequency() {
return frequency;
return frequency == 0 ? 60 : frequency;
}
public void setFrequency(int _frequency) {
@@ -73,7 +91,7 @@ public class BreakerHub implements IIdentical<BreakerHub> {
@Override
public boolean isIdentical(BreakerHub _o) {
if (this == _o) return true;
return hub == _o.hub && Double.compare(_o.voltageCalibrationFactor, voltageCalibrationFactor) == 0 && Double.compare(_o.portCalibrationFactor, portCalibrationFactor) == 0 && frequency == _o.frequency && Objects.equals(bluetoothMac, _o.bluetoothMac);
return hub == _o.hub && Double.compare(_o.voltageCalibrationFactor, voltageCalibrationFactor) == 0 && Double.compare(_o.portCalibrationFactor, portCalibrationFactor) == 0 && getPhaseCnt() == _o.getPhaseCnt() && getPhaseOffsetNs() == _o.getPhaseOffsetNs() && getFrequency() == _o.getFrequency() && Objects.equals(bluetoothMac, _o.bluetoothMac);
}
@Override

View File

@@ -2,5 +2,7 @@ package com.lanternsoftware.datamodel.currentmonitor;
public enum BreakerPolarity {
NORMAL,
SOLAR;
SOLAR,
BI_DIRECTIONAL,
BI_DIRECTIONAL_INVERTED
}

View File

@@ -140,9 +140,9 @@ public class EnergySummary {
idx = 0;
double flow = 0.0;
for (Float power : CollectionUtils.makeNotNull(breaker.getReadings())) {
if ((b.getPolarity() == BreakerPolarity.SOLAR) && (meter.flow[idx] < 0.0))
if (power < 0 && (meter.flow[idx] < 0.0))
flow -= meter.flow[idx] * (power / meter.solar[idx]);
else if ((b.getPolarity() != BreakerPolarity.SOLAR) && (meter.flow[idx] > 0.0))
else if (power > 0 && (meter.flow[idx] > 0.0))
flow += meter.flow[idx] * (power / meter.usage[idx]);
idx++;
}
@@ -152,11 +152,11 @@ public class EnergySummary {
}
public void resetEnergy(Date _readTime) {
if (energy == null)
return;
int idx = viewMode.blockIndex(start, _readTime, timezone);
if (idx < energy.length)
energy[idx] = 0f;
if (energy != null) {
int idx = viewMode.blockIndex(start, _readTime, timezone);
if (idx < energy.length)
energy[idx] = 0f;
}
for (EnergySummary subGroup : CollectionUtils.makeNotNull(subGroups)) {
subGroup.resetEnergy(_readTime);
}

View File

@@ -28,6 +28,8 @@ public class BreakerHubSerializer extends AbstractDaoSerializer<BreakerHub>
d.put("hub", _o.getHub());
d.put("voltage_calibration_factor", _o.getRawVoltageCalibrationFactor());
d.put("port_calibration_factor", _o.getRawPortCalibrationFactor());
d.put("phase_cnt", _o.getPhaseCnt());
d.put("phase_offset_ns", _o.getPhaseOffsetNs());
d.put("frequency", _o.getFrequency());
d.put("bluetooth_mac", _o.getBluetoothMac());
return d;
@@ -40,6 +42,8 @@ public class BreakerHubSerializer extends AbstractDaoSerializer<BreakerHub>
o.setHub(DaoSerializer.getInteger(_d, "hub"));
o.setVoltageCalibrationFactor(DaoSerializer.getDouble(_d, "voltage_calibration_factor"));
o.setPortCalibrationFactor(DaoSerializer.getDouble(_d, "port_calibration_factor"));
o.setPhaseCnt(DaoSerializer.getInteger(_d, "phase_cnt"));
o.setPhaseOffsetNs(DaoSerializer.getInteger(_d, "phase_offset_ns"));
o.setFrequency(DaoSerializer.getInteger(_d, "frequency"));
o.setBluetoothMac(DaoSerializer.getString(_d, "bluetooth_mac"));
return o;

View File

@@ -35,6 +35,7 @@ public class BreakerSerializer extends AbstractDaoSerializer<Breaker>
d.put("name", _o.getName());
d.put("description", _o.getDescription());
d.put("size_amps", _o.getSizeAmps());
d.put("phase_offset_ns", _o.getPhaseOffsetNs());
d.put("calibration_factor", _o.getCalibrationFactor());
d.put("low_pass_filter", _o.getLowPassFilter());
d.put("polarity", DaoSerializer.toEnumName(_o.getPolarity()));
@@ -56,6 +57,7 @@ public class BreakerSerializer extends AbstractDaoSerializer<Breaker>
o.setName(DaoSerializer.getString(_d, "name"));
o.setDescription(DaoSerializer.getString(_d, "description"));
o.setSizeAmps(DaoSerializer.getInteger(_d, "size_amps"));
o.setPhaseOffsetNs(DaoSerializer.getInteger(_d, "phase_offset_ns"));
o.setCalibrationFactor(DaoSerializer.getDouble(_d, "calibration_factor"));
o.setLowPassFilter(DaoSerializer.getDouble(_d, "low_pass_filter"));
o.setPolarity(DaoSerializer.getEnum(_d, "polarity", BreakerPolarity.class));

View File

@@ -0,0 +1,41 @@
package com.lanternsoftware.datamodel.currentmonitor.hub;
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
import com.lanternsoftware.util.dao.annotations.DBSerializable;
import java.util.List;
@DBSerializable
public class BreakerSample {
private int panel;
private int space;
private List<PowerSample> samples;
public int key() {
return Breaker.intKey(panel, space);
}
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 List<PowerSample> getSamples() {
return samples;
}
public void setSamples(List<PowerSample> _samples) {
samples = _samples;
}
}

View File

@@ -0,0 +1,42 @@
package com.lanternsoftware.datamodel.currentmonitor.hub;
import com.lanternsoftware.util.DateUtils;
import com.lanternsoftware.util.dao.annotations.DBSerializable;
import java.util.Date;
import java.util.List;
@DBSerializable(autogen = false)
public class HubSample {
private int accountId;
private Date sampleDate;
private List<BreakerSample> breakers;
public String getId() {
return String.format("%d-%d", accountId, DateUtils.toLong(sampleDate));
}
public int getAccountId() {
return accountId;
}
public void setAccountId(int _accountId) {
accountId = _accountId;
}
public Date getSampleDate() {
return sampleDate;
}
public void setSampleDate(Date _sampleDate) {
sampleDate = _sampleDate;
}
public List<BreakerSample> getBreakers() {
return breakers;
}
public void setBreakers(List<BreakerSample> _breakers) {
breakers = _breakers;
}
}

View File

@@ -0,0 +1,43 @@
package com.lanternsoftware.datamodel.currentmonitor.hub;
import com.lanternsoftware.util.dao.annotations.DBSerializable;
@DBSerializable
public class PowerSample {
public long nanoTime;
public int cycle;
public double voltage;
public double current;
public long getNanoTime() {
return nanoTime;
}
public void setNanoTime(long _nanoTime) {
nanoTime = _nanoTime;
}
public int getCycle() {
return cycle;
}
public void setCycle(int _cycle) {
cycle = _cycle;
}
public double getVoltage() {
return voltage;
}
public void setVoltage(double _voltage) {
voltage = _voltage;
}
public double getCurrent() {
return current;
}
public void setCurrent(double _current) {
current = _current;
}
}

View File

@@ -0,0 +1,44 @@
package com.lanternsoftware.datamodel.currentmonitor.hub.dao;
import com.lanternsoftware.datamodel.currentmonitor.hub.BreakerSample;
import com.lanternsoftware.datamodel.currentmonitor.hub.PowerSample;
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 BreakerSampleSerializer extends AbstractDaoSerializer<BreakerSample>
{
@Override
public Class<BreakerSample> getSupportedClass()
{
return BreakerSample.class;
}
@Override
public List<DaoProxyType> getSupportedProxies() {
return Collections.singletonList(DaoProxyType.MONGO);
}
@Override
public DaoEntity toDaoEntity(BreakerSample _o)
{
DaoEntity d = new DaoEntity();
d.put("panel", _o.getPanel());
d.put("space", _o.getSpace());
d.put("samples", DaoSerializer.toDaoEntities(_o.getSamples(), DaoProxyType.MONGO));
return d;
}
@Override
public BreakerSample fromDaoEntity(DaoEntity _d)
{
BreakerSample o = new BreakerSample();
o.setPanel(DaoSerializer.getInteger(_d, "panel"));
o.setSpace(DaoSerializer.getInteger(_d, "space"));
o.setSamples(DaoSerializer.getList(_d, "samples", PowerSample.class));
return o;
}
}

View File

@@ -0,0 +1,45 @@
package com.lanternsoftware.datamodel.currentmonitor.hub.dao;
import com.lanternsoftware.datamodel.currentmonitor.hub.BreakerSample;
import com.lanternsoftware.datamodel.currentmonitor.hub.HubSample;
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 HubSampleSerializer extends AbstractDaoSerializer<HubSample>
{
@Override
public Class<HubSample> getSupportedClass()
{
return HubSample.class;
}
@Override
public List<DaoProxyType> getSupportedProxies() {
return Collections.singletonList(DaoProxyType.MONGO);
}
@Override
public DaoEntity toDaoEntity(HubSample _o)
{
DaoEntity d = new DaoEntity();
d.put("_id", _o.getId());
d.put("account_id", _o.getAccountId());
d.put("sample_date", DaoSerializer.toLong(_o.getSampleDate()));
d.put("breakers", DaoSerializer.toDaoEntities(_o.getBreakers(), DaoProxyType.MONGO));
return d;
}
@Override
public HubSample fromDaoEntity(DaoEntity _d)
{
HubSample o = new HubSample();
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
o.setSampleDate(DaoSerializer.getDate(_d, "sample_date"));
o.setBreakers(DaoSerializer.getList(_d, "breakers", BreakerSample.class));
return o;
}
}

View File

@@ -0,0 +1,45 @@
package com.lanternsoftware.datamodel.currentmonitor.hub.dao;
import com.lanternsoftware.datamodel.currentmonitor.hub.PowerSample;
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 PowerSampleSerializer extends AbstractDaoSerializer<PowerSample>
{
@Override
public Class<PowerSample> getSupportedClass()
{
return PowerSample.class;
}
@Override
public List<DaoProxyType> getSupportedProxies() {
return Collections.singletonList(DaoProxyType.MONGO);
}
@Override
public DaoEntity toDaoEntity(PowerSample _o)
{
DaoEntity d = new DaoEntity();
d.put("nano_time", _o.getNanoTime());
d.put("cycle", _o.getCycle());
d.put("voltage", _o.getVoltage());
d.put("current", _o.getCurrent());
return d;
}
@Override
public PowerSample fromDaoEntity(DaoEntity _d)
{
PowerSample o = new PowerSample();
o.setNanoTime(DaoSerializer.getLong(_d, "nano_time"));
o.setCycle(DaoSerializer.getInteger(_d, "cycle"));
o.setVoltage(DaoSerializer.getDouble(_d, "voltage"));
o.setCurrent(DaoSerializer.getDouble(_d, "current"));
return o;
}
}

View File

@@ -26,3 +26,6 @@ com.lanternsoftware.datamodel.currentmonitor.dao.MeterSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.NetworkStatusSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.SequenceSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.SignupResponseSerializer
com.lanternsoftware.datamodel.currentmonitor.hub.dao.BreakerSampleSerializer
com.lanternsoftware.datamodel.currentmonitor.hub.dao.HubSampleSerializer
com.lanternsoftware.datamodel.currentmonitor.hub.dao.PowerSampleSerializer