mirror of
https://github.com/zyphlar/LanternPowerMonitor.git
synced 2024-03-08 14:07:47 +00:00
Update summaries when billing rate configuration changes. Refactor some of the billing rate variable names to be more clear.
This commit is contained in:
parent
cb774d1950
commit
77ceec745c
|
@ -1,6 +1,7 @@
|
||||||
package com.lanternsoftware.dataaccess.currentmonitor;
|
package com.lanternsoftware.dataaccess.currentmonitor;
|
||||||
|
|
||||||
import com.lanternsoftware.datamodel.currentmonitor.Account;
|
import com.lanternsoftware.datamodel.currentmonitor.Account;
|
||||||
|
import com.lanternsoftware.datamodel.currentmonitor.BillingRate;
|
||||||
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
import com.lanternsoftware.datamodel.currentmonitor.Breaker;
|
||||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
|
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
|
||||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
|
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
|
||||||
|
@ -28,6 +29,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -159,6 +161,32 @@ public class MongoCurrentMonitorDao implements CurrentMonitorDao {
|
||||||
putBreakerGroupEnergy(summary);
|
putBreakerGroupEnergy(summary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void rebuildSummaries(int _accountId, Collection<BillingRate> _rates) {
|
||||||
|
logger.info("Rebuilding summaries due to a change in {} rates", CollectionUtils.size(_rates));
|
||||||
|
HubPowerMinute firstMinute = proxy.queryOne(HubPowerMinute.class, new DaoQuery("account_id", _accountId), DaoSort.sort("minute"));
|
||||||
|
if (firstMinute == null)
|
||||||
|
return;
|
||||||
|
TimeZone tz = getTimeZoneForAccount(_accountId);
|
||||||
|
Map<String, BillingRate> rates = CollectionUtils.transformToMap(_rates, _r->String.format("%d%d", DaoSerializer.toLong(_r.getBeginEffective()), DaoSerializer.toLong(_r.getEndEffective())));
|
||||||
|
for (BillingRate rate : rates.values()) {
|
||||||
|
Date start = rate.getBeginEffective();
|
||||||
|
Date end = rate.getEndEffective();
|
||||||
|
Date now = new Date();
|
||||||
|
if ((start == null) || start.before(firstMinute.getMinuteAsDate()))
|
||||||
|
start = firstMinute.getMinuteAsDate();
|
||||||
|
if ((end == null) || end.after(now))
|
||||||
|
end = now;
|
||||||
|
rebuildSummaries(_accountId, start, end);
|
||||||
|
if (rate.isRecursAnnually()) {
|
||||||
|
while (end.before(now)) {
|
||||||
|
start = DateUtils.addYears(start, 1, tz);
|
||||||
|
end = DateUtils.addYears(end, 1, tz);
|
||||||
|
rebuildSummaries(_accountId, start, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rebuildSummaries(int _accountId) {
|
public void rebuildSummaries(int _accountId) {
|
||||||
HubPowerMinute firstMinute = proxy.queryOne(HubPowerMinute.class, new DaoQuery("account_id", _accountId), DaoSort.sort("minute"));
|
HubPowerMinute firstMinute = proxy.queryOne(HubPowerMinute.class, new DaoQuery("account_id", _accountId), DaoSort.sort("minute"));
|
||||||
|
@ -228,8 +256,20 @@ public class MongoCurrentMonitorDao implements CurrentMonitorDao {
|
||||||
DaoQuery configQuery = new DaoQuery("_id", String.valueOf(_config.getAccountId()));
|
DaoQuery configQuery = new DaoQuery("_id", String.valueOf(_config.getAccountId()));
|
||||||
BreakerConfig oldConfig = proxy.queryOne(BreakerConfig.class, configQuery);
|
BreakerConfig oldConfig = proxy.queryOne(BreakerConfig.class, configQuery);
|
||||||
if (oldConfig != null) {
|
if (oldConfig != null) {
|
||||||
proxy.saveEntity("config_archive", DaoSerializer.toDaoEntity(oldConfig));
|
|
||||||
_config.setVersion(oldConfig.getVersion() + 1);
|
_config.setVersion(oldConfig.getVersion() + 1);
|
||||||
|
if (NullUtils.isNotIdentical(_config, oldConfig)) {
|
||||||
|
DaoEntity oldEntity = DaoSerializer.toDaoEntity(oldConfig);
|
||||||
|
oldEntity.put("_id", String.format("%d-%d", oldConfig.getAccountId(), oldConfig.getVersion()));
|
||||||
|
oldEntity.put("account_id", oldConfig.getAccountId());
|
||||||
|
oldEntity.put("archive_date", DaoSerializer.toLong(new Date()));
|
||||||
|
proxy.saveEntity("config_archive", oldEntity);
|
||||||
|
executor.submit(() -> {
|
||||||
|
List<BillingRate> changedRates = new ArrayList<>(_config.getBillingRates());
|
||||||
|
changedRates.removeAll(CollectionUtils.makeNotNull(oldConfig.getBillingRates()));
|
||||||
|
if (!changedRates.isEmpty())
|
||||||
|
rebuildSummaries(_config.getAccountId(), changedRates);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
proxy.save(_config);
|
proxy.save(_config);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
package com.lanternsoftware.datamodel.currentmonitor;
|
|
||||||
|
|
||||||
public enum BillingMode {
|
|
||||||
ANY_DIRECTION,
|
|
||||||
CONSUMPTION,
|
|
||||||
PRODUCTION;
|
|
||||||
}
|
|
|
@ -5,13 +5,14 @@ import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
@DBSerializable
|
@DBSerializable
|
||||||
public class BillingRate {
|
public class BillingRate {
|
||||||
private int meter;
|
private int meter;
|
||||||
private int dayBillingCycleStart;
|
private int dayBillingCycleStart;
|
||||||
private BillingMode mode;
|
private GridFlow flow;
|
||||||
private double rate;
|
private double rate;
|
||||||
private BillingCurrency currency;
|
private BillingCurrency currency;
|
||||||
private int timeOfDayStart;
|
private int timeOfDayStart;
|
||||||
|
@ -38,12 +39,12 @@ public class BillingRate {
|
||||||
dayBillingCycleStart = _dayBillingCycleStart;
|
dayBillingCycleStart = _dayBillingCycleStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BillingMode getMode() {
|
public GridFlow getFlow() {
|
||||||
return mode;
|
return flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMode(BillingMode _mode) {
|
public void setFlow(GridFlow _flow) {
|
||||||
mode = _mode;
|
flow = _flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getRate() {
|
public double getRate() {
|
||||||
|
@ -118,8 +119,8 @@ public class BillingRate {
|
||||||
recursAnnually = _recursAnnually;
|
recursAnnually = _recursAnnually;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isApplicable(BillingMode _mode, int _meter, double _monthKWh, Date _time, TimeZone _tz) {
|
public boolean isApplicable(GridFlow _mode, int _meter, double _monthKWh, Date _time, TimeZone _tz) {
|
||||||
if ((mode != BillingMode.ANY_DIRECTION) && (mode != _mode))
|
if ((flow != GridFlow.BOTH) && (flow != _mode))
|
||||||
return false;
|
return false;
|
||||||
if ((meter != -1) && (_meter != meter))
|
if ((meter != -1) && (_meter != meter))
|
||||||
return false;
|
return false;
|
||||||
|
@ -160,11 +161,24 @@ public class BillingRate {
|
||||||
return rate * _kWh;
|
return rate * _kWh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object _o) {
|
||||||
|
if (this == _o) return true;
|
||||||
|
if (_o == null || getClass() != _o.getClass()) return false;
|
||||||
|
BillingRate that = (BillingRate) _o;
|
||||||
|
return meter == that.meter && dayBillingCycleStart == that.dayBillingCycleStart && Double.compare(that.rate, rate) == 0 && timeOfDayStart == that.timeOfDayStart && timeOfDayEnd == that.timeOfDayEnd && Double.compare(that.monthKWhStart, monthKWhStart) == 0 && Double.compare(that.monthKWhEnd, monthKWhEnd) == 0 && recursAnnually == that.recursAnnually && flow == that.flow && currency == that.currency && Objects.equals(beginEffective, that.beginEffective) && Objects.equals(endEffective, that.endEffective);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(meter, dayBillingCycleStart, flow, rate, currency, timeOfDayStart, timeOfDayEnd, monthKWhStart, monthKWhEnd, beginEffective, endEffective, recursAnnually);
|
||||||
|
}
|
||||||
|
|
||||||
public BillingRate duplicate() {
|
public BillingRate duplicate() {
|
||||||
BillingRate r = new BillingRate();
|
BillingRate r = new BillingRate();
|
||||||
r.setMeter(meter);
|
r.setMeter(meter);
|
||||||
r.setDayBillingCycleStart(dayBillingCycleStart);
|
r.setDayBillingCycleStart(dayBillingCycleStart);
|
||||||
r.setMode(mode);
|
r.setFlow(flow);
|
||||||
r.setRate(rate);
|
r.setRate(rate);
|
||||||
r.setCurrency(currency);
|
r.setCurrency(currency);
|
||||||
r.setTimeOfDayStart(timeOfDayStart);
|
r.setTimeOfDayStart(timeOfDayStart);
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package com.lanternsoftware.datamodel.currentmonitor;
|
package com.lanternsoftware.datamodel.currentmonitor;
|
||||||
|
|
||||||
|
|
||||||
|
import com.lanternsoftware.util.IIdentical;
|
||||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@DBSerializable()
|
@DBSerializable()
|
||||||
public class Breaker {
|
public class Breaker implements IIdentical<Breaker> {
|
||||||
private static final int TANDEM_BREAKER_MASK = 3072;
|
private static final int TANDEM_BREAKER_MASK = 3072;
|
||||||
private static final int SPACE_MASK = 1023;
|
private static final int SPACE_MASK = 1023;
|
||||||
private static final int TANDEM_BREAKER_A_MASK = 1024;
|
private static final int TANDEM_BREAKER_A_MASK = 1024;
|
||||||
|
@ -238,4 +241,23 @@ public class Breaker {
|
||||||
public int getSpaceIndex() {
|
public int getSpaceIndex() {
|
||||||
return space & SPACE_MASK;
|
return space & SPACE_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object _o) {
|
||||||
|
if (this == _o) return true;
|
||||||
|
if (_o == null || getClass() != _o.getClass()) return false;
|
||||||
|
Breaker breaker = (Breaker) _o;
|
||||||
|
return panel == breaker.panel && space == breaker.space;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 && Objects.equals(key, _o.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(panel, space);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.lanternsoftware.datamodel.currentmonitor;
|
package com.lanternsoftware.datamodel.currentmonitor;
|
||||||
|
|
||||||
import com.lanternsoftware.util.CollectionUtils;
|
import com.lanternsoftware.util.CollectionUtils;
|
||||||
|
import com.lanternsoftware.util.IIdentical;
|
||||||
import com.lanternsoftware.util.NullUtils;
|
import com.lanternsoftware.util.NullUtils;
|
||||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||||
|
@ -8,9 +9,10 @@ import com.lanternsoftware.util.dao.annotations.PrimaryKey;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@DBSerializable(autogen = false)
|
@DBSerializable(autogen = false)
|
||||||
public class BreakerConfig {
|
public class BreakerConfig implements IIdentical<BreakerConfig> {
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
private int accountId;
|
private int accountId;
|
||||||
private List<Meter> meters;
|
private List<Meter> meters;
|
||||||
|
@ -182,4 +184,23 @@ public class BreakerConfig {
|
||||||
public BillingCurrency getCurrency() {
|
public BillingCurrency getCurrency() {
|
||||||
return CollectionUtils.getFirst(CollectionUtils.transformToSet(billingRates, BillingRate::getCurrency));
|
return CollectionUtils.getFirst(CollectionUtils.transformToSet(billingRates, BillingRate::getCurrency));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object _o) {
|
||||||
|
if (this == _o) return true;
|
||||||
|
if (_o == null || getClass() != _o.getClass()) return false;
|
||||||
|
BreakerConfig that = (BreakerConfig) _o;
|
||||||
|
return accountId == that.accountId && CollectionUtils.isEqual(meters, that.meters) && CollectionUtils.isEqual(panels, that.panels) && CollectionUtils.isEqual(breakerHubs, that.breakerHubs) && CollectionUtils.isEqual(breakerGroups, that.breakerGroups) && CollectionUtils.isEqual(billingRates, that.billingRates);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIdentical(BreakerConfig _o) {
|
||||||
|
if (this == _o) return true;
|
||||||
|
return accountId == _o.accountId && CollectionUtils.isIdentical(meters, _o.meters) && CollectionUtils.isIdentical(panels, _o.panels) && CollectionUtils.isIdentical(breakerHubs, _o.breakerHubs) && CollectionUtils.isIdentical(breakerGroups, _o.breakerGroups) && CollectionUtils.isEqual(billingRates, _o.billingRates);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(accountId, meters, panels, breakerHubs, breakerGroups, billingRates, version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,18 @@ package com.lanternsoftware.datamodel.currentmonitor;
|
||||||
|
|
||||||
|
|
||||||
import com.lanternsoftware.util.CollectionUtils;
|
import com.lanternsoftware.util.CollectionUtils;
|
||||||
|
import com.lanternsoftware.util.IIdentical;
|
||||||
import com.lanternsoftware.util.NullUtils;
|
import com.lanternsoftware.util.NullUtils;
|
||||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||||
import com.lanternsoftware.util.dao.annotations.PrimaryKey;
|
import com.lanternsoftware.util.dao.annotations.PrimaryKey;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@DBSerializable()
|
@DBSerializable()
|
||||||
public class BreakerGroup {
|
public class BreakerGroup implements IIdentical<BreakerGroup> {
|
||||||
@PrimaryKey private String id;
|
@PrimaryKey private String id;
|
||||||
private int accountId;
|
private int accountId;
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -186,6 +186,15 @@ public class BreakerGroup {
|
||||||
return Objects.equals(id, that.id);
|
return Objects.equals(id, that.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIdentical(BreakerGroup _o) {
|
||||||
|
if (this == _o)
|
||||||
|
return true;
|
||||||
|
if (_o == null)
|
||||||
|
return false;
|
||||||
|
return NullUtils.isEqual(id, _o.id) && accountId == _o.accountId && NullUtils.isEqual(name, _o.name) && CollectionUtils.isIdentical(subGroups, _o.subGroups) && CollectionUtils.isIdentical(breakers, _o.breakers);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(id);
|
return Objects.hash(id);
|
||||||
|
|
|
@ -96,8 +96,8 @@ public class BreakerGroupEnergy {
|
||||||
double secondFromGrid;
|
double secondFromGrid;
|
||||||
for (Map.Entry<MeterMinute, MeterMinuteValues> meter : meters.entrySet()) {
|
for (Map.Entry<MeterMinute, MeterMinuteValues> meter : meters.entrySet()) {
|
||||||
double monthkWh = monthFromGrid/3600000;
|
double monthkWh = monthFromGrid/3600000;
|
||||||
List<BillingRate> consumptionRates = CollectionUtils.filter(_rates, _r->_r.isApplicable(BillingMode.CONSUMPTION, meter.getKey().meter, monthkWh, meter.getKey().minute, timezone));
|
List<BillingRate> consumptionRates = CollectionUtils.filter(_rates, _r->_r.isApplicable(GridFlow.FROM, meter.getKey().meter, monthkWh, meter.getKey().minute, timezone));
|
||||||
List<BillingRate> productionRates = CollectionUtils.filter(_rates, _r->_r.isApplicable(BillingMode.PRODUCTION, meter.getKey().meter, monthkWh, meter.getKey().minute, timezone));
|
List<BillingRate> productionRates = CollectionUtils.filter(_rates, _r->_r.isApplicable(GridFlow.TO, meter.getKey().meter, monthkWh, meter.getKey().minute, timezone));
|
||||||
for (int i = 0; i < 60; i++) {
|
for (int i = 0; i < 60; i++) {
|
||||||
secondFromGrid = meter.getValue().usage[i] - meter.getValue().solar[i];
|
secondFromGrid = meter.getValue().usage[i] - meter.getValue().solar[i];
|
||||||
monthFromGrid += secondFromGrid;
|
monthFromGrid += secondFromGrid;
|
||||||
|
@ -351,7 +351,7 @@ public class BreakerGroupEnergy {
|
||||||
return charge(_selectedBreakers, true);
|
return charge(_selectedBreakers, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double charge(Set<String> _selectedBreakers, BillingMode _mode) {
|
public double charge(Set<String> _selectedBreakers, GridFlow _mode) {
|
||||||
return charge(_selectedBreakers, true, _mode);
|
return charge(_selectedBreakers, true, _mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +359,7 @@ public class BreakerGroupEnergy {
|
||||||
return charge(_selectedBreakers, _includeSubgroups, null);
|
return charge(_selectedBreakers, _includeSubgroups, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double charge(Set<String> _selectedBreakers, boolean _includeSubgroups, BillingMode _mode) {
|
public double charge(Set<String> _selectedBreakers, boolean _includeSubgroups, GridFlow _mode) {
|
||||||
double charge = 0.0;
|
double charge = 0.0;
|
||||||
if (_includeSubgroups) {
|
if (_includeSubgroups) {
|
||||||
for (BreakerGroupEnergy group : CollectionUtils.makeNotNull(subGroups)) {
|
for (BreakerGroupEnergy group : CollectionUtils.makeNotNull(subGroups)) {
|
||||||
|
@ -368,7 +368,7 @@ public class BreakerGroupEnergy {
|
||||||
}
|
}
|
||||||
if ((energyBlocks != null) && ((_selectedBreakers == null) || _selectedBreakers.contains(getGroupId()))) {
|
if ((energyBlocks != null) && ((_selectedBreakers == null) || _selectedBreakers.contains(getGroupId()))) {
|
||||||
for (EnergyBlock energy : energyBlocks) {
|
for (EnergyBlock energy : energyBlocks) {
|
||||||
if ((_mode == null) || ((_mode == BillingMode.PRODUCTION) && energy.getCharge() < 0.0) || (_mode == BillingMode.CONSUMPTION && energy.getCharge() > 0.0))
|
if ((_mode == null) || ((_mode == GridFlow.TO) && energy.getCharge() < 0.0) || (_mode == GridFlow.FROM && energy.getCharge() > 0.0))
|
||||||
charge += energy.getCharge();
|
charge += energy.getCharge();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package com.lanternsoftware.datamodel.currentmonitor;
|
package com.lanternsoftware.datamodel.currentmonitor;
|
||||||
|
|
||||||
|
|
||||||
|
import com.lanternsoftware.util.IIdentical;
|
||||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@DBSerializable
|
@DBSerializable
|
||||||
public class BreakerHub {
|
public class BreakerHub implements IIdentical<BreakerHub> {
|
||||||
private int hub;
|
private int hub;
|
||||||
private double voltageCalibrationFactor;
|
private double voltageCalibrationFactor;
|
||||||
private double portCalibrationFactor;
|
private double portCalibrationFactor;
|
||||||
|
@ -50,4 +53,23 @@ public class BreakerHub {
|
||||||
public void setBluetoothMac(String _bluetoothMac) {
|
public void setBluetoothMac(String _bluetoothMac) {
|
||||||
bluetoothMac = _bluetoothMac;
|
bluetoothMac = _bluetoothMac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object _o) {
|
||||||
|
if (this == _o) return true;
|
||||||
|
if (_o == null || getClass() != _o.getClass()) return false;
|
||||||
|
BreakerHub that = (BreakerHub) _o;
|
||||||
|
return hub == that.hub;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(hub);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package com.lanternsoftware.datamodel.currentmonitor;
|
package com.lanternsoftware.datamodel.currentmonitor;
|
||||||
|
|
||||||
|
import com.lanternsoftware.util.IIdentical;
|
||||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@DBSerializable
|
@DBSerializable
|
||||||
public class BreakerPanel {
|
public class BreakerPanel implements IIdentical<BreakerPanel> {
|
||||||
private int accountId;
|
private int accountId;
|
||||||
private String name;
|
private String name;
|
||||||
private int index;
|
private int index;
|
||||||
|
@ -49,4 +52,23 @@ public class BreakerPanel {
|
||||||
public void setMeter(int _meter) {
|
public void setMeter(int _meter) {
|
||||||
meter = _meter;
|
meter = _meter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object _o) {
|
||||||
|
if (this == _o) return true;
|
||||||
|
if (_o == null || getClass() != _o.getClass()) return false;
|
||||||
|
BreakerPanel that = (BreakerPanel) _o;
|
||||||
|
return accountId == that.accountId && index == that.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIdentical(BreakerPanel _o) {
|
||||||
|
if (this == _o) return true;
|
||||||
|
return accountId == _o.accountId && index == _o.index && spaces == _o.spaces && meter == _o.meter && Objects.equals(name, _o.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(accountId, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.lanternsoftware.datamodel.currentmonitor;
|
||||||
|
|
||||||
|
public enum GridFlow {
|
||||||
|
BOTH,
|
||||||
|
FROM,
|
||||||
|
TO;
|
||||||
|
}
|
|
@ -1,9 +1,12 @@
|
||||||
package com.lanternsoftware.datamodel.currentmonitor;
|
package com.lanternsoftware.datamodel.currentmonitor;
|
||||||
|
|
||||||
|
import com.lanternsoftware.util.IIdentical;
|
||||||
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
import com.lanternsoftware.util.dao.annotations.DBSerializable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@DBSerializable
|
@DBSerializable
|
||||||
public class Meter {
|
public class Meter implements IIdentical<Meter> {
|
||||||
private int accountId;
|
private int accountId;
|
||||||
private int index;
|
private int index;
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -31,4 +34,24 @@ public class Meter {
|
||||||
public void setName(String _name) {
|
public void setName(String _name) {
|
||||||
name = _name;
|
name = _name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object _o) {
|
||||||
|
if (this == _o) return true;
|
||||||
|
if (_o == null || getClass() != _o.getClass()) return false;
|
||||||
|
Meter meter = (Meter) _o;
|
||||||
|
return accountId == meter.accountId && index == meter.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIdentical(Meter _o) {
|
||||||
|
if (this == _o) return true;
|
||||||
|
if (_o == null) return false;
|
||||||
|
return accountId == _o.accountId && index == _o.index && Objects.equals(name, _o.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(accountId, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
package com.lanternsoftware.datamodel.currentmonitor.dao;
|
||||||
|
|
||||||
import com.lanternsoftware.datamodel.currentmonitor.BillingCurrency;
|
import com.lanternsoftware.datamodel.currentmonitor.BillingCurrency;
|
||||||
import com.lanternsoftware.datamodel.currentmonitor.BillingMode;
|
import com.lanternsoftware.datamodel.currentmonitor.GridFlow;
|
||||||
import com.lanternsoftware.datamodel.currentmonitor.BillingRate;
|
import com.lanternsoftware.datamodel.currentmonitor.BillingRate;
|
||||||
import com.lanternsoftware.util.dao.AbstractDaoSerializer;
|
import com.lanternsoftware.util.dao.AbstractDaoSerializer;
|
||||||
import com.lanternsoftware.util.dao.DaoEntity;
|
import com.lanternsoftware.util.dao.DaoEntity;
|
||||||
|
@ -29,7 +29,7 @@ public class BillingRateSerializer extends AbstractDaoSerializer<BillingRate>
|
||||||
DaoEntity d = new DaoEntity();
|
DaoEntity d = new DaoEntity();
|
||||||
d.put("meter", _o.getMeter());
|
d.put("meter", _o.getMeter());
|
||||||
d.put("day_billing_cycle_start", _o.getDayBillingCycleStart());
|
d.put("day_billing_cycle_start", _o.getDayBillingCycleStart());
|
||||||
d.put("mode", DaoSerializer.toEnumName(_o.getMode()));
|
d.put("flow", DaoSerializer.toEnumName(_o.getFlow()));
|
||||||
d.put("rate", _o.getRate());
|
d.put("rate", _o.getRate());
|
||||||
d.put("unit", DaoSerializer.toEnumName(_o.getCurrency()));
|
d.put("unit", DaoSerializer.toEnumName(_o.getCurrency()));
|
||||||
d.put("time_of_day_start", _o.getTimeOfDayStart());
|
d.put("time_of_day_start", _o.getTimeOfDayStart());
|
||||||
|
@ -48,7 +48,7 @@ public class BillingRateSerializer extends AbstractDaoSerializer<BillingRate>
|
||||||
BillingRate o = new BillingRate();
|
BillingRate o = new BillingRate();
|
||||||
o.setMeter(DaoSerializer.getInteger(_d, "meter"));
|
o.setMeter(DaoSerializer.getInteger(_d, "meter"));
|
||||||
o.setDayBillingCycleStart(DaoSerializer.getInteger(_d, "day_billing_cycle_start"));
|
o.setDayBillingCycleStart(DaoSerializer.getInteger(_d, "day_billing_cycle_start"));
|
||||||
o.setMode(DaoSerializer.getEnum(_d, "mode", BillingMode.class));
|
o.setFlow(DaoSerializer.getEnum(_d, "flow", GridFlow.class, GridFlow.BOTH));
|
||||||
o.setRate(DaoSerializer.getDouble(_d, "rate"));
|
o.setRate(DaoSerializer.getDouble(_d, "rate"));
|
||||||
o.setCurrency(DaoSerializer.getEnum(_d, "unit", BillingCurrency.class));
|
o.setCurrency(DaoSerializer.getEnum(_d, "unit", BillingCurrency.class));
|
||||||
o.setTimeOfDayStart(DaoSerializer.getInteger(_d, "time_of_day_start"));
|
o.setTimeOfDayStart(DaoSerializer.getInteger(_d, "time_of_day_start"));
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package com.lanternsoftware.currentmonitor.servlet;
|
package com.lanternsoftware.currentmonitor.servlet;
|
||||||
|
|
||||||
import com.lanternsoftware.currentmonitor.context.Globals;
|
import com.lanternsoftware.currentmonitor.context.Globals;
|
||||||
import com.lanternsoftware.util.dao.auth.AuthCode;
|
|
||||||
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
|
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
|
||||||
|
import com.lanternsoftware.util.dao.auth.AuthCode;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -10,6 +12,8 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
@WebServlet("/config/*")
|
@WebServlet("/config/*")
|
||||||
public class ConfigServlet extends SecureServlet {
|
public class ConfigServlet extends SecureServlet {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(ConfigServlet.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||||
if (isPath(_req, 0, "bin"))
|
if (isPath(_req, 0, "bin"))
|
||||||
|
@ -29,6 +33,7 @@ public class ConfigServlet extends SecureServlet {
|
||||||
_rep.setStatus(401);
|
_rep.setStatus(401);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
logger.info("Received config for account {}", config.getAccountId());
|
||||||
Globals.dao.putConfig(config);
|
Globals.dao.putConfig(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,30 @@ public class CollectionUtils {
|
||||||
return _arr[_arr.length - 1];
|
return _arr[_arr.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> boolean isEqual(Collection<T> _l1, Collection<T> _l2) {
|
||||||
|
if (size(_l1) != size(_l2))
|
||||||
|
return false;
|
||||||
|
Iterator<T> i1 = _l1.iterator();
|
||||||
|
Iterator<T> i2 = _l2.iterator();
|
||||||
|
while (i1.hasNext()) {
|
||||||
|
if (NullUtils.isNotEqual(i1.next(), i2.next()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends IIdentical<T>> boolean isIdentical(Collection<T> _l1, Collection<T> _l2) {
|
||||||
|
if (size(_l1) != size(_l2))
|
||||||
|
return false;
|
||||||
|
Iterator<T> i1 = _l1.iterator();
|
||||||
|
Iterator<T> i2 = _l2.iterator();
|
||||||
|
while (i1.hasNext()) {
|
||||||
|
if (NullUtils.isNotIdentical(i1.next(), i2.next()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> boolean contains(Collection<T> _coll, T _t) {
|
public static <T> boolean contains(Collection<T> _coll, T _t) {
|
||||||
if (_coll == null)
|
if (_coll == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package com.lanternsoftware.util;
|
package com.lanternsoftware.util;
|
||||||
|
|
||||||
import java.sql.Time;
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
public abstract class DateUtils {
|
public abstract class DateUtils {
|
||||||
|
@ -405,6 +405,14 @@ public abstract class DateUtils {
|
||||||
return dateFormat(_format, _tz).format(_dt);
|
return dateFormat(_format, _tz).format(_dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String formatDate(int _format, TimeZone _tz, Date _dt) {
|
||||||
|
if (_dt == null)
|
||||||
|
return null;
|
||||||
|
DateFormat format = DateFormat.getDateInstance(_format, Locale.getDefault());
|
||||||
|
format.setTimeZone(_tz);
|
||||||
|
return format.format(_dt);
|
||||||
|
}
|
||||||
|
|
||||||
public static Date parse(String _format, String _date) {
|
public static Date parse(String _format, String _date) {
|
||||||
return parse(_format, TimeZone.getTimeZone("UTC"), _date);
|
return parse(_format, TimeZone.getTimeZone("UTC"), _date);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.lanternsoftware.util;
|
||||||
|
|
||||||
|
public interface IIdentical<T> {
|
||||||
|
boolean isIdentical(T _other);
|
||||||
|
}
|
|
@ -23,6 +23,16 @@ public class NullUtils {
|
||||||
return (b == null);
|
return (b == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T extends IIdentical<T>> boolean isNotIdentical(T a, T b) {
|
||||||
|
return !isIdentical(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends IIdentical<T>> boolean isIdentical(T a, T b) {
|
||||||
|
if (a != null)
|
||||||
|
return (b != null) && a.isIdentical(b);
|
||||||
|
return (b == null);
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> boolean isNotEqual(T a, T b, IEquals<T> _equals) {
|
public static <T> boolean isNotEqual(T a, T b, IEquals<T> _equals) {
|
||||||
return !isEqual(a, b, _equals);
|
return !isEqual(a, b, _equals);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user