Add billing plans so different plans can be compared. Performance enhancements to charge calculations.

This commit is contained in:
MarkBryanMilligan
2021-10-18 15:46:25 -05:00
parent ecbf438082
commit 883cf7865d
35 changed files with 2123 additions and 813 deletions

View File

@@ -23,4 +23,14 @@ public enum BillingCurrency {
return "-" + symbol + _value.abs().setScale(2, RoundingMode.HALF_EVEN);
return symbol + _value.setScale(2, RoundingMode.HALF_EVEN);
}
public String formatValue(double _value) {
return formatValue(BigDecimal.valueOf(_value));
}
public String formatValue(BigDecimal _value) {
if (_value.compareTo(BigDecimal.ZERO) < 0)
return "-" + _value.abs().setScale(2, RoundingMode.HALF_EVEN);
return _value.setScale(2, RoundingMode.HALF_EVEN).toString();
}
}

View File

@@ -0,0 +1,86 @@
package com.lanternsoftware.datamodel.currentmonitor;
import com.lanternsoftware.util.CollectionUtils;
import com.lanternsoftware.util.DateUtils;
import com.lanternsoftware.util.IIdentical;
import com.lanternsoftware.util.dao.annotations.DBSerializable;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
@DBSerializable
public class BillingPlan implements IIdentical<BillingPlan> {
private int accountId;
private int planId;
private int billingDay;
private String name;
private List<BillingRate> rates;
public int getAccountId() {
return accountId;
}
public void setAccountId(int _accountId) {
accountId = _accountId;
}
public int getPlanId() {
return planId;
}
public void setPlanId(int _planId) {
planId = _planId;
}
public int getBillingDay() {
return billingDay;
}
public void setBillingDay(int _billingDay) {
billingDay = _billingDay;
}
public Date getBillingCycleStart(Date _for, TimeZone _tz) {
Calendar cal = DateUtils.getStartOfMonthCal(_for, _tz);
if (billingDay < 100) {
cal.set(Calendar.DAY_OF_MONTH, (billingDay == 0) ? 1 : billingDay);
if (cal.getTime().after(_for))
cal.add(Calendar.MONTH, -1);
return cal.getTime();
}
int dayOfWeek = (billingDay-101)%7 + 1;
int weekOfMonth = (billingDay-101)/7;
int dayOfMonthOffset = dayOfWeek-cal.get(Calendar.DAY_OF_WEEK);
if (dayOfMonthOffset < 0)
dayOfMonthOffset += 7;
cal.set(Calendar.DAY_OF_MONTH, dayOfMonthOffset+(7*weekOfMonth)+1);
return cal.getTime();
}
public Date getBillingCycleEnd(Date _for, TimeZone _tz) {
return getBillingCycleStart(DateUtils.addMonths(_for, 1, _tz), _tz);
}
public String getName() {
return name;
}
public void setName(String _name) {
name = _name;
}
public List<BillingRate> getRates() {
return rates;
}
public void setRates(List<BillingRate> _rates) {
rates = _rates;
}
@Override
public boolean isIdentical(BillingPlan _other) {
return accountId == _other.accountId && planId == _other.planId && billingDay == _other.billingDay && CollectionUtils.isEqual(rates, _other.rates);
}
}

View File

@@ -3,7 +3,6 @@ package com.lanternsoftware.datamodel.currentmonitor;
import com.lanternsoftware.util.DateUtils;
import com.lanternsoftware.util.dao.annotations.DBSerializable;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import java.util.TimeZone;
@@ -11,7 +10,6 @@ import java.util.TimeZone;
@DBSerializable
public class BillingRate {
private int meter;
private int dayBillingCycleStart;
private GridFlow flow;
private double rate;
private BillingCurrency currency;
@@ -31,14 +29,6 @@ public class BillingRate {
meter = _meter;
}
public int getDayBillingCycleStart() {
return dayBillingCycleStart;
}
public void setDayBillingCycleStart(int _dayBillingCycleStart) {
dayBillingCycleStart = _dayBillingCycleStart;
}
public GridFlow getFlow() {
return flow;
}
@@ -119,7 +109,7 @@ public class BillingRate {
recursAnnually = _recursAnnually;
}
public boolean isApplicable(GridFlow _mode, int _meter, double _monthKWh, Date _time, TimeZone _tz) {
public boolean isApplicable(GridFlow _mode, int _meter, double _monthKWh, int _secondsIntoDay) {
if ((flow != GridFlow.BOTH) && (flow != _mode))
return false;
if ((meter != -1) && (_meter != meter))
@@ -128,6 +118,14 @@ public class BillingRate {
return false;
if ((monthKWhEnd > 0) && (_monthKWh >= monthKWhEnd))
return false;
if ((timeOfDayStart == 0) && (timeOfDayEnd == 0))
return true;
if ((timeOfDayStart > 0) && (_secondsIntoDay < timeOfDayStart))
return false;
return (timeOfDayEnd == 0) || (_secondsIntoDay < timeOfDayEnd);
}
public boolean isApplicableForDay(Date _time, TimeZone _tz) {
if ((beginEffective != null) && (endEffective != null) && recursAnnually) {
Date begin = beginEffective;
Date end = endEffective;
@@ -148,13 +146,7 @@ public class BillingRate {
if ((endEffective != null) && endEffective.before(_time))
return false;
}
if ((timeOfDayStart == 0) && (timeOfDayEnd == 0))
return true;
Calendar midnight = DateUtils.getMidnightBeforeCal(_time, _tz);
int timeOfDay = (int)((_time.getTime() - midnight.getTimeInMillis()) / 1000);
if ((timeOfDayStart > 0) && (timeOfDay < timeOfDayStart))
return false;
return (timeOfDayEnd == 0) || (timeOfDay < timeOfDayEnd);
return true;
}
public double apply(double _kWh) {
@@ -166,18 +158,17 @@ public class BillingRate {
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);
return meter == that.meter && 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);
return Objects.hash(meter, flow, rate, currency, timeOfDayStart, timeOfDayEnd, monthKWhStart, monthKWhEnd, beginEffective, endEffective, recursAnnually);
}
public BillingRate duplicate() {
BillingRate r = new BillingRate();
r.setMeter(meter);
r.setDayBillingCycleStart(dayBillingCycleStart);
r.setFlow(flow);
r.setRate(rate);
r.setCurrency(currency);

View File

@@ -20,6 +20,7 @@ public class BreakerConfig implements IIdentical<BreakerConfig> {
private List<BreakerHub> breakerHubs;
private List<BreakerGroup> breakerGroups;
private List<BillingRate> billingRates;
private List<BillingPlan> billingPlans;
private int version;
public BreakerConfig() {
@@ -69,6 +70,14 @@ public class BreakerConfig implements IIdentical<BreakerConfig> {
breakerGroups = _breakerGroups;
}
public List<BillingPlan> getBillingPlans() {
return billingPlans;
}
public void setBillingPlans(List<BillingPlan> _billingPlans) {
billingPlans = _billingPlans;
}
public List<BillingRate> getBillingRates() {
return billingRates;
}
@@ -85,6 +94,10 @@ public class BreakerConfig implements IIdentical<BreakerConfig> {
version = _version;
}
public BreakerGroup getRootGroup() {
return CollectionUtils.getFirst(breakerGroups);
}
public List<Breaker> getAllBreakers() {
List<Breaker> allBreakers = new ArrayList<>();
for (BreakerGroup g : CollectionUtils.makeNotNull(breakerGroups)) {
@@ -190,13 +203,13 @@ public class BreakerConfig implements IIdentical<BreakerConfig> {
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);
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(billingPlans, that.billingPlans);
}
@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);
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(billingPlans, _o.billingPlans);
}
@Override

View File

@@ -8,7 +8,9 @@ import com.lanternsoftware.util.dao.annotations.DBSerializable;
import com.lanternsoftware.util.dao.annotations.PrimaryKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -170,6 +172,16 @@ public class BreakerGroup implements IIdentical<BreakerGroup> {
return null;
}
public Map<String, Integer> mapToMeters() {
Map<String, Integer> groups = new HashMap<>();
for (BreakerGroup group : getAllBreakerGroups()) {
Breaker b = CollectionUtils.getFirst(group.getBreakers());
if (b != null)
groups.put(group.getId(), b.getMeter());
}
return groups;
}
public boolean removeInvalidGroups(Set<Integer> _validPanels) {
if (subGroups != null)
subGroups.removeIf(_g->!_g.removeInvalidGroups(_validPanels));

View File

@@ -2,524 +2,220 @@ 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 com.lanternsoftware.util.mutable.MutableDouble;
import java.util.ArrayList;
import java.util.Comparator;
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;
private double peakToGrid;
private double peakFromGrid;
private double peakConsumption;
private double peakProduction;
private TimeZone timezone;
private int accountId;
private String groupId;
private String groupName;
private EnergyViewMode viewMode;
private Date start;
private List<BreakerGroupEnergy> subGroups;
private List<EnergyBlock> energyBlocks;
private double toGrid;
private double fromGrid;
private double peakToGrid;
private double peakFromGrid;
private double peakConsumption;
private double peakProduction;
private TimeZone timezone;
public BreakerGroupEnergy() {
}
public BreakerGroupEnergy() {
}
public BreakerGroupEnergy(BreakerGroup _group, List<HubPowerMinute> _power, EnergyBlockViewMode _viewMode, Date _start, BreakerGroupSummary _month, List<BillingRate> _rates, TimeZone _timezone) {
groupId = _group.getId();
groupName = _group.getName();
viewMode = _viewMode;
start = _start;
accountId = _group.getAccountId();
timezone = _timezone;
subGroups = CollectionUtils.transform(_group.getSubGroups(), _g -> new BreakerGroupEnergy(_g, null, _viewMode, _start, _month, _rates, timezone));
addEnergy(_group, _power, _month, _rates);
}
public BreakerGroupEnergy(EnergySummary _summary, List<BillingRate> _rates, Map<String, Integer> _breakerGroupMeters) {
groupId = _summary.getGroupId();
groupName = _summary.getGroupName();
viewMode = _summary.getViewMode();
start = _summary.getStart();
accountId = _summary.getAccountId();
timezone = _summary.getTimeZone();
peakToGrid = _summary.getPeakToGrid();
peakFromGrid = _summary.getPeakFromGrid();
peakConsumption = _summary.getPeakConsumption();
peakProduction = _summary.getPeakProduction();
Date readTime = start;
if (_summary.getEnergy() != null) {
for (float joules : _summary.getEnergy()) {
addEnergy(readTime, joules);
readTime = viewMode.incrementBlock(readTime, timezone);
}
}
readTime = start;
ChargeSummary charges = _summary.toChargeSummary(0, _rates, _breakerGroupMeters, new MutableDouble(0.0));
for (double charge : charges.chargeBlocks(CollectionUtils.asHashSet(groupId), GridFlow.BOTH)) {
addCharge(readTime, charge);
readTime = viewMode.incrementBlock(readTime, timezone);
}
subGroups = CollectionUtils.transform(_summary.getSubGroups(), _e->new BreakerGroupEnergy(_e, _rates, _breakerGroupMeters));
}
public void addEnergy(BreakerGroup _group, List<HubPowerMinute> _hubPower, BreakerGroupSummary _month, List<BillingRate> _rates) {
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, _month, _rates);
}
private void addEnergy(Date _readTime, double _joules) {
EnergyBlock block = getBlock(_readTime);
if (block != null)
block.addJoules(_joules);
}
public void addEnergy(Map<String, Breaker> _breakers, Map<String, BreakerGroup> _breakerKeyToGroup, List<HubPowerMinute> _hubPower, BreakerGroupSummary _month, List<BillingRate> _rates) {
if (CollectionUtils.isEmpty(_hubPower) || CollectionUtils.anyQualify(_hubPower, _p->_p.getAccountId() != accountId))
return;
_hubPower.sort(Comparator.comparing(HubPowerMinute::getMinute));
for (Date minute : CollectionUtils.transformToSet(_hubPower, HubPowerMinute::getMinuteAsDate)) {
resetEnergy(minute);
}
int idx;
Map<Integer, Map<Integer, MeterMinute>> minutes = new TreeMap<>();
for (HubPowerMinute hubPower : _hubPower) {
Date minute = hubPower.getMinuteAsDate();
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 = minutes.computeIfAbsent(hubPower.getMinute(), _p->new TreeMap<>()).computeIfAbsent(b.getMeter(), _m->new MeterMinute(b.getMeter(), hubPower.getMinuteAsDate()));
idx = 0;
EnergyBlock block = getBlock(group.getId(), minute);
if (block != null) {
for (Float power : CollectionUtils.makeNotNull(breaker.getReadings())) {
if (idx >= 60)
break;
if (power > 0)
meter.usage[idx] += power;
else
meter.solar[idx] -= power;
block.addJoules(power);
idx++;
}
}
}
}
double monthFromGrid = _month == null ? 0.0 : _month.getFromGrid();
double secondFromGrid;
for (MeterMinute minute : CollectionUtils.aggregate(minutes.values(), Map::values)) {
double monthkWh = monthFromGrid/3600000;
List<BillingRate> consumptionRates = CollectionUtils.filter(_rates, _r->_r.isApplicable(GridFlow.FROM, minute.getMeter(), monthkWh, minute.getMinute(), timezone));
List<BillingRate> productionRates = CollectionUtils.filter(_rates, _r->_r.isApplicable(GridFlow.TO, minute.getMeter(), monthkWh, minute.getMinute(), timezone));
for (int i = 0; i < 60; i++) {
if (minute.usage[i] > peakConsumption)
peakConsumption = minute.usage[i];
if (minute.solar[i] > peakProduction)
peakProduction = minute.solar[i];
secondFromGrid = minute.usage[i] - minute.solar[i];
monthFromGrid += secondFromGrid;
if (secondFromGrid > 0) {
fromGrid += secondFromGrid;
if (secondFromGrid > peakFromGrid)
peakFromGrid = secondFromGrid;
for (BillingRate rate : consumptionRates) {
minute.charges[i] += rate.apply(secondFromGrid/3600000);
}
}
else {
secondFromGrid = -secondFromGrid;
toGrid += secondFromGrid;
if (secondFromGrid > peakToGrid)
peakToGrid = secondFromGrid;
for (BillingRate rate : productionRates) {
minute.charges[i] -= rate.apply(secondFromGrid/3600000);
}
}
}
}
double curConsumption;
double curProduction;
double curToGrid;
double curFromGrid;
for (Map<Integer, MeterMinute> meters : minutes.values()) {
for (int i=0; i < 60; i++) {
curConsumption = 0;
curProduction = 0;
curToGrid = 0;
curFromGrid = 0;
for (MeterMinute meterValues : meters.values()) {
curConsumption += meterValues.usage[i];
curProduction += meterValues.solar[i];
if (meterValues.solar[i] > meterValues.usage[i])
curToGrid += meterValues.solar[i] - meterValues.usage[i];
else
curFromGrid += meterValues.usage[i] - meterValues.solar[i];
}
if (curConsumption > peakConsumption)
peakConsumption = curConsumption;
if (curProduction > peakProduction)
peakProduction = curProduction;
if (curToGrid > peakToGrid)
peakToGrid = curToGrid;
if (curFromGrid > peakFromGrid)
peakFromGrid = curFromGrid;
}
}
for (HubPowerMinute hubPower : _hubPower) {
Date minute = hubPower.getMinuteAsDate();
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 = minutes.get(hubPower.getMinute()).get(b.getMeter());
idx = 0;
double charge = 0.0;
for (Float power : CollectionUtils.makeNotNull(breaker.getReadings())) {
if (b.getPolarity() == BreakerPolarity.SOLAR) {
if (meter.charges[idx] < 0.0)
charge -= meter.charges[idx] * (power/meter.solar[idx]);
}
else if (meter.charges[idx] > 0.0)
charge += meter.charges[idx] * (power/meter.usage[idx]);
idx++;
}
addCharge(group.getId(), minute, charge);
}
}
}
private void addCharge(Date _readTime, double _charge) {
EnergyBlock block = getBlock(_readTime);
if (block != null)
block.addCharge(_charge);
}
public void resetEnergy(Date _readTime) {
EnergyBlock block = getBlock(_readTime, false);
if (block != null)
block.setJoules(0);
for (BreakerGroupEnergy subGroup : CollectionUtils.makeNotNull(subGroups)) {
subGroup.resetEnergy(_readTime);
}
}
private EnergyBlock getBlock(Date _readTime) {
int size = CollectionUtils.size(energyBlocks);
int idx = viewMode.blockIndex(start, _readTime, timezone);
if (idx >= size) {
if (energyBlocks == null)
energyBlocks = new ArrayList<>(viewMode.initBlockCount());
LinkedList<EnergyBlock> newBlocks = new LinkedList<>();
Date end = viewMode.toBlockEnd(_readTime, timezone);
while (idx >= size) {
Date start = viewMode.decrementBlock(end, timezone);
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);
}
private EnergyBlock getBlock(String _groupId, Date _readTime) {
if (NullUtils.isEqual(groupId, _groupId))
return getBlock(_readTime);
else {
for (BreakerGroupEnergy subGroup : CollectionUtils.makeNotNull(subGroups)) {
EnergyBlock block = subGroup.getBlock(_groupId, _readTime);
if (block != null)
return block;
}
return null;
}
}
public String getId() {
return toId(accountId, groupId, viewMode, start);
}
private void addEnergy(String _groupId, Date _readTime, double _joules) {
EnergyBlock block = getBlock(_groupId, _readTime);
if (block != null)
block.addJoules(_joules);
}
public static String toId(int _accountId, String _groupId, EnergyViewMode _viewMode, Date _start) {
return _accountId + "-" + _groupId + "-" + DaoSerializer.toEnumName(_viewMode) + "-" + _start.getTime();
}
private void addCharge(String _groupId, Date _readTime, double _charge) {
EnergyBlock block = getBlock(_groupId, _readTime);
if (block != null)
block.addCharge(_charge);
}
public int getAccountId() {
return accountId;
}
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.setTimeZone(_tz);
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());
block.addJoules(curEnergy.getJoules());
block.addCharge(curEnergy.getCharge());
energy.setToGrid(energy.getToGrid()+curEnergy.getToGrid());
energy.setFromGrid(energy.getFromGrid()+curEnergy.getFromGrid());
if (curEnergy.getPeakFromGrid() > energy.getPeakFromGrid())
energy.setPeakFromGrid(curEnergy.getPeakFromGrid());
if (curEnergy.getPeakToGrid() > energy.getPeakToGrid())
energy.setPeakToGrid(curEnergy.getPeakToGrid());
if (curEnergy.getPeakConsumption() > energy.getPeakConsumption())
energy.setPeakConsumption(curEnergy.getPeakConsumption());
if (curEnergy.getPeakProduction() > energy.getPeakProduction())
energy.setPeakProduction(curEnergy.getPeakProduction());
}
return energy;
}
public void setAccountId(int _accountId) {
accountId = _accountId;
}
private EnergyBlock getBlock(Date _readTime) {
return getBlock(_readTime, true);
}
public String getGroupId() {
return groupId;
}
private EnergyBlock getBlock(Date _readTime, boolean _add) {
int size = CollectionUtils.size(energyBlocks);
int idx = viewMode.blockIndex(start, _readTime, timezone);
if (_add && (idx >= size)) {
if (energyBlocks == null)
energyBlocks = new ArrayList<>(viewMode.initBlockCount());
LinkedList<EnergyBlock> newBlocks = new LinkedList<>();
Date end = viewMode.toBlockEnd(_readTime, timezone);
while (idx >= size) {
Date start = viewMode.decrementBlock(end, timezone);
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 void setGroupId(String _groupId) {
groupId = _groupId;
}
public String getId() {
return toId(accountId, groupId, viewMode, start);
}
public String getGroupName() {
return groupName;
}
public static String toId(int _accountId, String _groupId, EnergyBlockViewMode _viewMode, Date _start) {
return _accountId + "-" + _groupId + "-" + DaoSerializer.toEnumName(_viewMode) + "-" + _start.getTime();
}
public void setGroupName(String _groupName) {
groupName = _groupName;
}
public int getAccountId() {
return accountId;
}
public BreakerGroupEnergy getSubGroup(String _groupId) {
return CollectionUtils.filterOne(subGroups, _g -> _groupId.equals(_g.getGroupId()));
}
public void setAccountId(int _accountId) {
accountId = _accountId;
}
public List<BreakerGroupEnergy> getSubGroups() {
return subGroups;
}
public String getGroupId() {
return groupId;
}
public EnergyViewMode getViewMode() {
return viewMode;
}
public void setGroupId(String _groupId) {
groupId = _groupId;
}
public void setViewMode(EnergyViewMode _viewMode) {
viewMode = _viewMode;
}
public String getGroupName() {
return groupName;
}
public Date getStart() {
return start;
}
public void setGroupName(String _groupName) {
groupName = _groupName;
}
public void setStart(Date _start) {
start = _start;
}
public BreakerGroupEnergy getSubGroup(String _groupId) {
return CollectionUtils.filterOne(subGroups, _g->_groupId.equals(_g.getGroupId()));
}
public void setSubGroups(List<BreakerGroupEnergy> _subGroups) {
subGroups = _subGroups;
}
public List<BreakerGroupEnergy> getSubGroups() {
return subGroups;
}
public List<EnergyBlock> getEnergyBlocks() {
return energyBlocks;
}
public EnergyBlockViewMode getViewMode() {
return viewMode;
}
public void setEnergyBlocks(List<EnergyBlock> _energyBlocks) {
energyBlocks = _energyBlocks;
}
public void setViewMode(EnergyBlockViewMode _viewMode) {
viewMode = _viewMode;
}
public double getToGrid() {
return toGrid;
}
public Date getStart() {
return start;
}
public void setToGrid(double _toGrid) {
toGrid = _toGrid;
}
public void setStart(Date _start) {
start = _start;
}
public double getFromGrid() {
return fromGrid;
}
public void setSubGroups(List<BreakerGroupEnergy> _subGroups) {
subGroups = _subGroups;
}
public void setFromGrid(double _fromGrid) {
fromGrid = _fromGrid;
}
public List<EnergyBlock> getEnergyBlocks() {
return energyBlocks;
}
public double getPeakToGrid() {
return peakToGrid;
}
public void setEnergyBlocks(List<EnergyBlock> _energyBlocks) {
energyBlocks = _energyBlocks;
}
public void setPeakToGrid(double _peakToGrid) {
peakToGrid = _peakToGrid;
}
public double getToGrid() {
return toGrid;
}
public double getPeakFromGrid() {
return peakFromGrid;
}
public void setToGrid(double _toGrid) {
toGrid = _toGrid;
}
public void setPeakFromGrid(double _peakFromGrid) {
peakFromGrid = _peakFromGrid;
}
public double getFromGrid() {
return fromGrid;
}
public double getPeakConsumption() {
return peakConsumption;
}
public void setFromGrid(double _fromGrid) {
fromGrid = _fromGrid;
}
public void setPeakConsumption(double _peakConsumption) {
peakConsumption = _peakConsumption;
}
public double getPeakToGrid() {
return peakToGrid;
}
public double getPeakProduction() {
return peakProduction;
}
public void setPeakToGrid(double _peakToGrid) {
peakToGrid = _peakToGrid;
}
public void setPeakProduction(double _peakProduction) {
peakProduction = _peakProduction;
}
public double getPeakFromGrid() {
return peakFromGrid;
}
public TimeZone getTimeZone() {
return timezone;
}
public void setPeakFromGrid(double _peakFromGrid) {
peakFromGrid = _peakFromGrid;
}
public double getPeakConsumption() {
return peakConsumption;
}
public void setPeakConsumption(double _peakConsumption) {
peakConsumption = _peakConsumption;
}
public double getPeakProduction() {
return peakProduction;
}
public void setPeakProduction(double _peakProduction) {
peakProduction = _peakProduction;
}
public TimeZone getTimeZone() {
return timezone;
}
public void setTimeZone(TimeZone _timezone) {
timezone = _timezone;
}
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 double charge() {
return charge(null);
}
public double charge(Set<String> _selectedBreakers) {
return charge(_selectedBreakers, true);
}
public double charge(Set<String> _selectedBreakers, GridFlow _mode) {
return charge(_selectedBreakers, true, _mode);
}
public double charge(Set<String> _selectedBreakers, boolean _includeSubgroups) {
return charge(_selectedBreakers, _includeSubgroups, null);
}
public double charge(Set<String> _selectedBreakers, boolean _includeSubgroups, GridFlow _mode) {
double charge = 0.0;
if (_includeSubgroups) {
for (BreakerGroupEnergy group : CollectionUtils.makeNotNull(subGroups)) {
charge += group.charge(_selectedBreakers, true, _mode);
}
}
if ((energyBlocks != null) && ((_selectedBreakers == null) || _selectedBreakers.contains(getGroupId()))) {
for (EnergyBlock energy : energyBlocks) {
if ((_mode == null) || ((_mode == GridFlow.TO) && energy.getCharge() < 0.0) || (_mode == GridFlow.FROM && energy.getCharge() > 0.0))
charge += energy.getCharge();
}
}
return charge;
}
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());
b.addCharge(block.getCharge());
}
}
}
for (BreakerGroupEnergy group : CollectionUtils.makeNotNull(subGroups)) {
group.getAllEnergyBlocks(_selectedGroups, _energyBlocks, _type);
}
}
private static class MeterMinute {
private final int meter;
private final Date minute;
public MeterMinute(int _meter, Date _minute) {
meter = _meter;
minute = _minute;
}
public int getMeter() {
return meter;
}
public Date getMinute() {
return minute;
}
public double[] usage = new double[60];
public double[] solar = new double[60];
public double[] charges = new double[60];
}
public void setTimeZone(TimeZone _timezone) {
timezone = _timezone;
}
}

View File

@@ -0,0 +1,285 @@
package com.lanternsoftware.datamodel.currentmonitor;
import com.lanternsoftware.util.CollectionUtils;
import com.lanternsoftware.util.DateUtils;
import com.lanternsoftware.util.dao.DaoSerializer;
import com.lanternsoftware.util.dao.annotations.DBSerializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
@DBSerializable(autogen = false)
public class ChargeSummary {
private int accountId;
private int planId;
private String groupId;
private String groupName;
private EnergyViewMode viewMode;
private Date start;
private List<ChargeSummary> subGroups;
private TimeZone timezone;
private double[] charges;
private double totalUsageJoules;
private double totalSolarJoules;
private double fromGridJoules;
private double toGridJoules;
private double peakToGrid;
private double peakFromGrid;
private double peakConsumption;
private double peakProduction;
public ChargeSummary() {
}
public ChargeSummary(int _accountId, int _planId, String _groupId, String _groupName, EnergyViewMode _viewMode, Date _start, TimeZone _timezone) {
accountId = _accountId;
planId = _planId;
groupId = _groupId;
groupName = _groupName;
viewMode = _viewMode;
start = _start;
timezone = _timezone;
}
public ChargeSummary(BreakerGroup _group, BillingPlan _plan, Map<String, List<ChargeTotal>> _charges, EnergyViewMode _viewMode, Date _start, TimeZone _timezone) {
this(_group.getAccountId(), _plan.getPlanId(), _group.getId(), _group.getName(), _viewMode, _start, _timezone);
subGroups = CollectionUtils.transform(_group.getSubGroups(), _g -> new ChargeSummary(_g, _plan, _charges, _viewMode, _start, _timezone));
if (_viewMode == EnergyViewMode.MONTH) {
charges = new double[DateUtils.getDaysBetween(_start, _plan.getBillingCycleEnd(_start, _timezone), _timezone)];
}
else
charges = new double[_viewMode.blockCount(_start, _timezone)];
for (ChargeTotal charge : CollectionUtils.makeNotNull(_charges.get(_group.getId()))) {
int idx;
if (_viewMode == EnergyViewMode.MONTH)
idx = DateUtils.getDaysBetween(_start, charge.getStart(), _timezone);
else
idx = viewMode.blockIndex(start, charge.getStart(), timezone);
if (idx < charges.length)
charges[idx] += charge.getCharge();
}
totalUsageJoules = CollectionUtils.sum(CollectionUtils.transform(_charges.get(_group.getId()), ChargeTotal::getTotalUsageJoules));
totalSolarJoules = CollectionUtils.sum(CollectionUtils.transform(_charges.get(_group.getId()), ChargeTotal::getTotalSolarJoules));
fromGridJoules = CollectionUtils.sum(CollectionUtils.transform(_charges.get(_group.getId()), ChargeTotal::getFromGridJoules));
toGridJoules = CollectionUtils.sum(CollectionUtils.transform(_charges.get(_group.getId()), ChargeTotal::getToGridJoules));
peakToGrid = DaoSerializer.toDouble(CollectionUtils.getLargest(CollectionUtils.transform(_charges.get(_group.getId()), ChargeTotal::getPeakToGrid)));
peakFromGrid = DaoSerializer.toDouble(CollectionUtils.getLargest(CollectionUtils.transform(_charges.get(_group.getId()), ChargeTotal::getPeakFromGrid)));
peakConsumption = DaoSerializer.toDouble(CollectionUtils.getLargest(CollectionUtils.transform(_charges.get(_group.getId()), ChargeTotal::getPeakConsumption)));
peakProduction = DaoSerializer.toDouble(CollectionUtils.getLargest(CollectionUtils.transform(_charges.get(_group.getId()), ChargeTotal::getPeakProduction)));
}
public String getId() {
return toId(accountId, planId, groupId, viewMode, start);
}
public int getAccountId() {
return accountId;
}
public void setAccountId(int _accountId) {
accountId = _accountId;
}
public int getPlanId() {
return planId;
}
public void setPlanId(int _planId) {
planId = _planId;
}
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 EnergyViewMode getViewMode() {
return viewMode;
}
public void setViewMode(EnergyViewMode _viewMode) {
viewMode = _viewMode;
}
public Date getStart() {
return start;
}
public void setStart(Date _start) {
start = _start;
}
public List<ChargeSummary> getSubGroups() {
return subGroups;
}
public void setSubGroups(List<ChargeSummary> _subGroups) {
subGroups = _subGroups;
}
public double[] getCharges() {
return charges;
}
public void setCharges(double[] _charges) {
charges = _charges;
}
public TimeZone getTimezone() {
return timezone;
}
public void setTimezone(TimeZone _timezone) {
timezone = _timezone;
}
public double getTotalUsageJoules() {
return totalUsageJoules;
}
public void setTotalUsageJoules(double _totalUsageJoules) {
totalUsageJoules = _totalUsageJoules;
}
public double getTotalSolarJoules() {
return totalSolarJoules;
}
public void setTotalSolarJoules(double _totalSolarJoules) {
totalSolarJoules = _totalSolarJoules;
}
public double getFromGridJoules() {
return fromGridJoules;
}
public void setFromGridJoules(double _fromGridJoules) {
fromGridJoules = _fromGridJoules;
}
public double getToGridJoules() {
return toGridJoules;
}
public void setToGridJoules(double _toGridJoules) {
toGridJoules = _toGridJoules;
}
public double getPeakToGrid() {
return peakToGrid;
}
public void setPeakToGrid(double _peakToGrid) {
peakToGrid = _peakToGrid;
}
public double getPeakFromGrid() {
return peakFromGrid;
}
public void setPeakFromGrid(double _peakFromGrid) {
peakFromGrid = _peakFromGrid;
}
public double getPeakConsumption() {
return peakConsumption;
}
public void setPeakConsumption(double _peakConsumption) {
peakConsumption = _peakConsumption;
}
public double getPeakProduction() {
return peakProduction;
}
public void setPeakProduction(double _peakProduction) {
peakProduction = _peakProduction;
}
public double charge() {
return charge(null);
}
public double charge(Set<String> _selectedBreakers) {
return charge(_selectedBreakers, true);
}
public double charge(Set<String> _selectedBreakers, GridFlow _mode) {
return charge(_selectedBreakers, true, _mode);
}
public double charge(Set<String> _selectedBreakers, boolean _includeSubgroups) {
return charge(_selectedBreakers, _includeSubgroups, null);
}
public double charge(Set<String> _selectedBreakers, boolean _includeSubgroups, GridFlow _mode) {
double charge = 0.0;
if (_includeSubgroups) {
for (ChargeSummary group : CollectionUtils.makeNotNull(subGroups)) {
charge += group.charge(_selectedBreakers, true, _mode);
}
}
if ((charges != null) && ((_selectedBreakers == null) || _selectedBreakers.contains(getGroupId()))) {
for (double c : charges) {
if ((_mode == null) || ((_mode == GridFlow.TO) && c < 0.0) || (_mode == GridFlow.FROM && c > 0.0))
charge += c;
}
}
return charge;
}
public float[] chargeBlocks() {
return chargeBlocks(null);
}
public float[] chargeBlocks(Set<String> _selectedGroups) {
return chargeBlocks(_selectedGroups, GridFlow.BOTH);
}
public float[] chargeBlocks(Set<String> _selectedGroups, GridFlow _flow) {
float[] blocks = new float[blockCount()];
chargeBlocks(_selectedGroups, blocks, _flow);
return blocks;
}
private void chargeBlocks(Set<String> _selectedGroups, float[] _chargeBlocks, GridFlow _flow) {
if ((charges != null) && ((_selectedGroups == null) || _selectedGroups.contains(getGroupId()))) {
for (int i = 0; i < charges.length; i++) {
if ((_flow == GridFlow.BOTH) || ((_flow == GridFlow.FROM) && charges[i] >= 0.0) || ((_flow == GridFlow.TO) && charges[i] <= 0.0))
_chargeBlocks[i] += charges[i];
}
}
for (ChargeSummary group : CollectionUtils.makeNotNull(subGroups)) {
group.chargeBlocks(_selectedGroups, _chargeBlocks, _flow);
}
}
private int blockCount() {
int blocks = 0;
for (ChargeSummary s : CollectionUtils.makeNotNull(subGroups)) {
blocks = Math.max(blocks, s.blockCount());
}
if ((charges != null) && (charges.length > blocks))
return charges.length;
return blocks;
}
public static String toId(int _accountId, int _planId, String _groupId, EnergyViewMode _viewMode, Date _start) {
return _accountId + "-" + _planId + "-" + _groupId + "-" + DaoSerializer.toEnumName(_viewMode) + "-" + _start.getTime();
}
}

View File

@@ -0,0 +1,199 @@
package com.lanternsoftware.datamodel.currentmonitor;
import com.lanternsoftware.util.CollectionUtils;
import com.lanternsoftware.util.dao.annotations.DBSerializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@DBSerializable(autogen = false)
public class ChargeTotal {
private int accountId;
private String groupId;
private int planId;
private EnergyViewMode viewMode;
private Date start;
private double charge;
private List<ChargeTotal> subGroups;
private double totalUsageJoules;
private double totalSolarJoules;
private double fromGridJoules;
private double toGridJoules;
private double peakToGrid;
private double peakFromGrid;
private double peakConsumption;
private double peakProduction;
public ChargeTotal() {
}
public ChargeTotal(ChargeSummary _summary) {
accountId = _summary.getAccountId();
groupId = _summary.getGroupId();
planId = _summary.getPlanId();
viewMode = _summary.getViewMode();
start = _summary.getStart();
if (_summary.getCharges() != null) {
for (double c : _summary.getCharges()) {
charge += c;
}
}
subGroups = CollectionUtils.transform(_summary.getSubGroups(), ChargeTotal::new);
totalUsageJoules = _summary.getTotalUsageJoules();
totalSolarJoules = _summary.getTotalSolarJoules();
fromGridJoules = _summary.getFromGridJoules();
toGridJoules = _summary.getToGridJoules();
peakToGrid = _summary.getPeakToGrid();
peakFromGrid = _summary.getPeakFromGrid();
peakConsumption = _summary.getPeakConsumption();
peakProduction = _summary.getPeakProduction();
}
public String getId() {
return ChargeSummary.toId(accountId, planId, groupId, viewMode, start);
}
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 int getPlanId() {
return planId;
}
public void setPlanId(int _planId) {
planId = _planId;
}
public EnergyViewMode getViewMode() {
return viewMode;
}
public void setViewMode(EnergyViewMode _viewMode) {
viewMode = _viewMode;
}
public Date getStart() {
return start;
}
public void setStart(Date _start) {
start = _start;
}
public double getCharge() {
return charge;
}
public void setCharge(double _charge) {
charge = _charge;
}
public List<ChargeTotal> getSubGroups() {
return subGroups;
}
public void setSubGroups(List<ChargeTotal> _subGroups) {
subGroups = _subGroups;
}
public double getTotalUsageJoules() {
return totalUsageJoules;
}
public void setTotalUsageJoules(double _totalUsageJoules) {
totalUsageJoules = _totalUsageJoules;
}
public double getTotalSolarJoules() {
return totalSolarJoules;
}
public void setTotalSolarJoules(double _totalSolarJoules) {
totalSolarJoules = _totalSolarJoules;
}
public double getFromGridJoules() {
return fromGridJoules;
}
public void setFromGridJoules(double _fromGridJoules) {
fromGridJoules = _fromGridJoules;
}
public double getToGridJoules() {
return toGridJoules;
}
public void setToGridJoules(double _toGridJoules) {
toGridJoules = _toGridJoules;
}
public double getPeakToGrid() {
return peakToGrid;
}
public void setPeakToGrid(double _peakToGrid) {
peakToGrid = _peakToGrid;
}
public double getPeakFromGrid() {
return peakFromGrid;
}
public void setPeakFromGrid(double _peakFromGrid) {
peakFromGrid = _peakFromGrid;
}
public double getPeakConsumption() {
return peakConsumption;
}
public void setPeakConsumption(double _peakConsumption) {
peakConsumption = _peakConsumption;
}
public double getPeakProduction() {
return peakProduction;
}
public void setPeakProduction(double _peakProduction) {
peakProduction = _peakProduction;
}
public double chargeTotal() {
double retCharge = charge;
for (ChargeTotal t : CollectionUtils.makeNotNull(subGroups)) {
retCharge += t.chargeTotal();
}
return retCharge;
}
public List<ChargeTotal> flatten() {
List<ChargeTotal> totals = new ArrayList<>();
flatten(totals);
return totals;
}
private void flatten(List<ChargeTotal> _totals) {
_totals.add(this);
for (ChargeTotal total : CollectionUtils.makeNotNull(subGroups)) {
total.flatten(_totals);
}
}
}

View File

@@ -56,6 +56,7 @@ public class EnergyBlock {
public void setCharge(double _charge) {
charge = _charge;
}
public void addCharge(double _charge) {
charge += _charge;
}
@@ -63,10 +64,4 @@ public class EnergyBlock {
public double wattHours() {
return joules / 3600;
}
public double getAveragePower() {
if ((end == null) || (start == null))
return 0;
return 1000*joules/(end.getTime()-start.getTime());
}
}

View File

@@ -0,0 +1,503 @@
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 com.lanternsoftware.util.mutable.MutableDouble;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
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 EnergySummary {
private int accountId;
private String groupId;
private String groupName;
private EnergyViewMode viewMode;
private Date start;
private List<EnergySummary> subGroups;
private float[] energy;
private float[] gridEnergy;
private double peakToGrid;
private double peakFromGrid;
private double peakConsumption;
private double peakProduction;
private TimeZone timezone;
public EnergySummary() {
}
public EnergySummary(BreakerGroup _group, List<HubPowerMinute> _power, EnergyViewMode _viewMode, Date _start, TimeZone _timezone) {
groupId = _group.getId();
groupName = _group.getName();
viewMode = _viewMode;
start = _start;
accountId = _group.getAccountId();
timezone = _timezone;
subGroups = CollectionUtils.transform(_group.getSubGroups(), _g -> new EnergySummary(_g, null, _viewMode, _start, timezone));
if (_power != null)
addEnergy(_group, _power);
}
public void addEnergy(BreakerGroup _group, List<HubPowerMinute> _hubPower) {
Map<String, Breaker> breakers = CollectionUtils.transformToMap(_group.getAllBreakers(), Breaker::getKey);
Map<String, BreakerGroup> breakerKeyToGroup = new HashMap<>();
for (BreakerGroup group : _group.getAllBreakerGroups()) {
for (Breaker b : CollectionUtils.makeNotNull(group.getBreakers())) {
breakerKeyToGroup.put(b.getKey(), group);
}
}
addEnergy(breakers, breakerKeyToGroup, _hubPower);
}
public void addEnergy(Map<String, Breaker> _breakers, Map<String, BreakerGroup> _breakerKeyToGroup, List<HubPowerMinute> _hubPower) {
if (CollectionUtils.isEmpty(_hubPower) || CollectionUtils.anyQualify(_hubPower, _p -> _p.getAccountId() != accountId))
return;
_hubPower.sort(Comparator.comparing(HubPowerMinute::getMinute));
for (Date minute : CollectionUtils.transformToSet(_hubPower, HubPowerMinute::getMinuteAsDate)) {
resetEnergy(minute);
}
int idx;
Map<Integer, Map<Integer, MeterMinute>> minutes = new HashMap<>();
for (HubPowerMinute hubPower : _hubPower) {
Date minute = hubPower.getMinuteAsDate();
for (BreakerPowerMinute breaker : CollectionUtils.makeNotNull(hubPower.getBreakers())) {
String key = breaker.breakerKey();
Breaker b = _breakers.get(key);
if (b == null)
continue;
BreakerGroup group = _breakerKeyToGroup.get(key);
if (group == null)
continue;
MeterMinute meter = minutes.computeIfAbsent(hubPower.getMinute(), _p -> new HashMap<>()).computeIfAbsent(b.getMeter(), _m -> new MeterMinute(b.getMeter(), minute));
idx = 0;
for (Float power : CollectionUtils.makeNotNull(breaker.getReadings())) {
if (idx >= 60)
break;
if (power > 0)
meter.usage[idx] += power;
else
meter.solar[idx] -= power;
addEnergy(group.getId(), minute, power);
idx++;
}
}
}
double curConsumption;
double curProduction;
double curToGrid;
double curFromGrid;
for (Map<Integer, MeterMinute> meters : minutes.values()) {
for (int i = 0; i < 60; i++) {
curConsumption = 0;
curProduction = 0;
curToGrid = 0;
curFromGrid = 0;
for (MeterMinute minute : meters.values()) {
curConsumption += minute.usage[i];
curProduction += minute.solar[i];
minute.flow[i] = minute.usage[i] - minute.solar[i];
if (minute.flow[i] > 0)
curFromGrid += minute.flow[i];
else
curToGrid -= minute.flow[i];
}
if (curConsumption > peakConsumption)
peakConsumption = curConsumption;
if (curProduction > peakProduction)
peakProduction = curProduction;
if (curToGrid > peakToGrid)
peakToGrid = curToGrid;
if (curFromGrid > peakFromGrid)
peakFromGrid = curFromGrid;
}
}
for (HubPowerMinute hubPower : _hubPower) {
Date minute = hubPower.getMinuteAsDate();
for (BreakerPowerMinute breaker : CollectionUtils.makeNotNull(hubPower.getBreakers())) {
String key = breaker.breakerKey();
Breaker b = _breakers.get(key);
if (b == null)
continue;
BreakerGroup group = _breakerKeyToGroup.get(key);
if (group == null)
continue;
MeterMinute meter = minutes.get(hubPower.getMinute()).get(b.getMeter());
idx = 0;
double flow = 0.0;
for (Float power : CollectionUtils.makeNotNull(breaker.getReadings())) {
if ((b.getPolarity() == BreakerPolarity.SOLAR) && (meter.flow[idx] < 0.0))
flow -= meter.flow[idx] * (power / meter.solar[idx]);
else if ((b.getPolarity() != BreakerPolarity.SOLAR) && (meter.flow[idx] > 0.0))
flow += meter.flow[idx] * (power / meter.usage[idx]);
idx++;
}
addFlow(group.getId(), minute, flow);
}
}
}
public void resetEnergy(Date _readTime) {
if (energy == null)
return;
int idx = viewMode.blockIndex(start, _readTime, timezone);
if (idx < energy.length)
energy[idx] = 0f;
for (EnergySummary subGroup : CollectionUtils.makeNotNull(subGroups)) {
subGroup.resetEnergy(_readTime);
}
}
public static EnergySummary summary(BreakerGroup _group, Map<String, List<EnergyTotal>> _energies, EnergyViewMode _viewMode, Date _start, TimeZone _tz) {
EnergySummary energy = new EnergySummary();
energy.setGroupId(_group.getId());
energy.setGroupName(_group.getName());
energy.setAccountId(_group.getAccountId());
energy.setViewMode(_viewMode);
energy.setStart(_start);
energy.setTimeZone(_tz);
energy.setSubGroups(CollectionUtils.transform(_group.getSubGroups(), _g -> EnergySummary.summary(_g, _energies, _viewMode, _start, _tz)));
for (EnergyTotal curEnergy : CollectionUtils.makeNotNull(_energies.get(_group.getId()))) {
energy.addEnergy(curEnergy.getStart(), curEnergy.getJoules());
energy.addFlow(curEnergy.getStart(), curEnergy.getFlow());
if (curEnergy.getPeakFromGrid() > energy.getPeakFromGrid())
energy.setPeakFromGrid(curEnergy.getPeakFromGrid());
if (curEnergy.getPeakToGrid() > energy.getPeakToGrid())
energy.setPeakToGrid(curEnergy.getPeakToGrid());
if (curEnergy.getPeakConsumption() > energy.getPeakConsumption())
energy.setPeakConsumption(curEnergy.getPeakConsumption());
if (curEnergy.getPeakProduction() > energy.getPeakProduction())
energy.setPeakProduction(curEnergy.getPeakProduction());
}
return energy;
}
private boolean addEnergy(String _groupId, Date _readTime, double _joules) {
if (NullUtils.isEqual(groupId, _groupId)) {
addEnergy(_readTime, _joules);
return true;
} else {
for (EnergySummary subGroup : CollectionUtils.makeNotNull(subGroups)) {
if (subGroup.addEnergy(_groupId, _readTime, _joules))
return true;
}
}
return false;
}
private void addEnergy(Date _readTime, double _joules) {
if (energy == null)
energy = new float[blockCount()];
int idx = viewMode.blockIndex(start, _readTime, timezone);
if (idx < energy.length)
energy[idx] += _joules;
}
private boolean addFlow(String _groupId, Date _readTime, double _joules) {
if (NullUtils.isEqual(groupId, _groupId)) {
addFlow(_readTime, _joules);
return true;
} else {
for (EnergySummary subGroup : CollectionUtils.makeNotNull(subGroups)) {
if (subGroup.addFlow(_groupId, _readTime, _joules))
return true;
}
}
return false;
}
private void addFlow(Date _readTime, double _joules) {
if (gridEnergy == null)
gridEnergy = new float[blockCount()];
int idx = viewMode.blockIndex(start, _readTime, timezone);
if (idx < gridEnergy.length)
gridEnergy[idx] += _joules;
}
private int blockCount() {
return viewMode.blockCount(start, timezone);
}
public String getId() {
return toId(accountId, groupId, viewMode, start);
}
public static String toId(int _accountId, String _groupId, EnergyViewMode _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 EnergySummary getSubGroup(String _groupId) {
return CollectionUtils.filterOne(subGroups, _g -> _groupId.equals(_g.getGroupId()));
}
public List<EnergySummary> getSubGroups() {
return subGroups;
}
public EnergyViewMode getViewMode() {
return viewMode;
}
public void setViewMode(EnergyViewMode _viewMode) {
viewMode = _viewMode;
}
public Date getStart() {
return start;
}
public void setStart(Date _start) {
start = _start;
}
public void setSubGroups(List<EnergySummary> _subGroups) {
subGroups = _subGroups;
}
public float[] getEnergy() {
return energy;
}
public void setEnergy(float[] _energy) {
energy = _energy;
}
public float[] getGridEnergy() {
return gridEnergy;
}
public void setGridEnergy(float[] _gridEnergy) {
gridEnergy = _gridEnergy;
}
public double getPeakToGrid() {
return peakToGrid;
}
public void setPeakToGrid(double _peakToGrid) {
peakToGrid = _peakToGrid;
}
public double getPeakFromGrid() {
return peakFromGrid;
}
public void setPeakFromGrid(double _peakFromGrid) {
peakFromGrid = _peakFromGrid;
}
public double getPeakConsumption() {
return peakConsumption;
}
public void setPeakConsumption(double _peakConsumption) {
peakConsumption = _peakConsumption;
}
public double getPeakProduction() {
return peakProduction;
}
public void setPeakProduction(double _peakProduction) {
peakProduction = _peakProduction;
}
public TimeZone getTimeZone() {
return timezone;
}
public void setTimeZone(TimeZone _timezone) {
timezone = _timezone;
}
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, GridFlow.BOTH);
}
public double joules(Set<String> _selectedBreakers, boolean _includeSubgroups, GridFlow _mode) {
double joules = 0.0;
if (_includeSubgroups) {
for (EnergySummary group : CollectionUtils.makeNotNull(subGroups)) {
joules += group.joules(_selectedBreakers, true, _mode);
}
}
if ((energy != null) && ((_selectedBreakers == null) || _selectedBreakers.contains(getGroupId()))) {
for (float block : energy) {
if ((_mode == GridFlow.BOTH) || ((_mode == GridFlow.FROM) && (block > 0f)) || ((_mode == GridFlow.TO) && (block < 0f)))
joules += block;
}
}
return joules;
}
public double flow() {
return flow(null);
}
public double flow(Set<String> _selectedBreakers) {
return flow(_selectedBreakers, true, GridFlow.BOTH);
}
public double flow(Set<String> _selectedBreakers, boolean _includeSubgroups, GridFlow _mode) {
double flow = 0.0;
if (_includeSubgroups) {
for (EnergySummary group : CollectionUtils.makeNotNull(subGroups)) {
flow += group.flow(_selectedBreakers, true, _mode);
}
}
if ((gridEnergy != null) && ((_selectedBreakers == null) || _selectedBreakers.contains(getGroupId()))) {
for (float block : gridEnergy) {
if ((_mode == GridFlow.BOTH) || ((_mode == GridFlow.FROM) && (block > 0f)) || ((_mode == GridFlow.TO) && (block < 0f)))
flow += block;
}
}
return flow;
}
public List<EnergySummary> getAllGroups() {
Map<String, EnergySummary> groups = new TreeMap<>();
getAllGroups(groups);
return new ArrayList<>(groups.values());
}
public void getAllGroups(Map<String, EnergySummary> _groups) {
_groups.put(getGroupId(), this);
for (EnergySummary group : CollectionUtils.makeNotNull(subGroups)) {
group.getAllGroups(_groups);
}
}
public float[] energyBlocks() {
return energyBlocks(null);
}
public float[] energyBlocks(Set<String> _selectedGroups) {
return energyBlocks(_selectedGroups, GridFlow.BOTH);
}
public float[] energyBlocks(Set<String> _selectedGroups, GridFlow _flow) {
float[] blocks = new float[blockCount()];
energyBlocks(_selectedGroups, blocks, _flow);
return blocks;
}
private void energyBlocks(Set<String> _selectedGroups, float[] _energyBlocks, GridFlow _flow) {
if ((energy != null) && ((_selectedGroups == null) || _selectedGroups.contains(getGroupId()))) {
for (int i = 0; i < energy.length; i++) {
if ((_flow == GridFlow.BOTH) || ((_flow == GridFlow.FROM) && energy[i] >= 0.0) || ((_flow == GridFlow.TO) && energy[i] <= 0.0))
_energyBlocks[i] += energy[i];
}
}
for (EnergySummary group : CollectionUtils.makeNotNull(subGroups)) {
group.energyBlocks(_selectedGroups, _energyBlocks, _flow);
}
}
public List<ChargeSummary> toChargeSummaries(BreakerConfig _config, List<EnergyTotal> _totals) {
Map<String, Integer> breakerGroupMeters = _config.getRootGroup().mapToMeters();
return CollectionUtils.transform(_config.getBillingPlans(), _p->{
double monthKwh = CollectionUtils.sum(CollectionUtils.transform(CollectionUtils.filter(_totals, _t->_t.getStart().getTime() >= _p.getBillingCycleStart(start, timezone).getTime()), EnergyTotal::totalJoules))/3600000.0;
return toChargeSummary(_p.getPlanId(), _p.getRates(), breakerGroupMeters, new MutableDouble(monthKwh));
});
}
public ChargeSummary toChargeSummary(int _planId, List<BillingRate> _rates, Map<String, Integer> _breakerGroupMeters, MutableDouble _monthKwh) {
return toChargeSummaryForRates(_planId, CollectionUtils.filter(_rates, _r->_r.isApplicableForDay(start, timezone)), _breakerGroupMeters, _monthKwh);
}
private ChargeSummary toChargeSummaryForRates(int _planId, List<BillingRate> _rates, Map<String, Integer> _breakerGroupMeters, MutableDouble _monthKwh) {
ChargeSummary summary = new ChargeSummary(accountId, _planId, groupId, groupName, viewMode, start, timezone);
if (gridEnergy != null) {
double[] charges = new double[gridEnergy.length];
for (int i = 0; i < gridEnergy.length; i++) {
_monthKwh.add(gridEnergy[i]/3600000.0);
for (BillingRate rate : _rates) {
if (gridEnergy[i] > 0f) {
if (rate.isApplicable(GridFlow.FROM, DaoSerializer.toInteger(_breakerGroupMeters.get(groupId)), _monthKwh.getValue(), i*60))
charges[i] += rate.apply(((double) gridEnergy[i]) / 3600000.0);
} else if (rate.isApplicable(GridFlow.TO, DaoSerializer.toInteger(_breakerGroupMeters.get(groupId)), _monthKwh.getValue(), i*60))
charges[i] += rate.apply(((double) gridEnergy[i]) / 3600000.0);
}
}
summary.setCharges(charges);
}
summary.setSubGroups(CollectionUtils.transform(subGroups, _s->_s.toChargeSummary(_planId, _rates, _breakerGroupMeters, _monthKwh)));
summary.setTotalUsageJoules(joules(null, true, GridFlow.FROM));
summary.setTotalSolarJoules(Math.abs(joules(null, true, GridFlow.TO)));
summary.setFromGridJoules(flow(null, true, GridFlow.FROM));
summary.setToGridJoules(Math.abs(flow(null, true, GridFlow.TO)));
summary.setPeakConsumption(peakConsumption);
summary.setPeakProduction(peakProduction);
summary.setPeakFromGrid(peakFromGrid);
summary.setPeakToGrid(peakToGrid);
return summary;
}
private static class MeterMinute {
private final int meter;
private final Date minute;
public MeterMinute(int _meter, Date _minute) {
meter = _meter;
minute = _minute;
}
public int getMeter() {
return meter;
}
public Date getMinute() {
return minute;
}
public double[] usage = new double[60];
public double[] solar = new double[60];
public double[] flow = new double[60];
}
}

View File

@@ -2,47 +2,38 @@ 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 {
public class EnergyTotal {
private int accountId;
private String groupId;
private String groupName;
private EnergyBlockViewMode viewMode;
private EnergyViewMode viewMode;
private Date start;
private List<BreakerGroupSummary> subGroups;
private List<EnergyTotal> subGroups;
private double joules;
private double charge;
private double toGrid;
private double fromGrid;
private double flow;
private double peakToGrid;
private double peakFromGrid;
private double peakConsumption;
private double peakProduction;
public BreakerGroupSummary() {
public EnergyTotal() {
}
public BreakerGroupSummary(BreakerGroupEnergy _energy) {
public EnergyTotal(EnergySummary _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);
charge = _energy.charge(null, false);
toGrid = _energy.getToGrid();
fromGrid = _energy.getFromGrid();
subGroups = CollectionUtils.transform(_energy.getSubGroups(), EnergyTotal::new);
joules = _energy.joules(null, false, GridFlow.BOTH);
flow = _energy.flow(null, false, GridFlow.BOTH);
peakToGrid = _energy.getPeakToGrid();
peakFromGrid = _energy.getPeakFromGrid();
peakConsumption = _energy.getPeakConsumption();
@@ -53,7 +44,7 @@ public class BreakerGroupSummary {
return toId(accountId, groupId, viewMode, start);
}
public static String toId(int _accountId, String _groupId, EnergyBlockViewMode _viewMode, Date _start) {
public static String toId(int _accountId, String _groupId, EnergyViewMode _viewMode, Date _start) {
return _accountId + "-" + _groupId + "-" + DaoSerializer.toEnumName(_viewMode) + "-" + _start.getTime();
}
@@ -73,27 +64,19 @@ public class BreakerGroupSummary {
groupId = _groupId;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String _groupName) {
groupName = _groupName;
}
public BreakerGroupSummary getSubGroup(String _groupId) {
public EnergyTotal getSubGroup(String _groupId) {
return CollectionUtils.filterOne(subGroups, _g->_groupId.equals(_g.getGroupId()));
}
public List<BreakerGroupSummary> getSubGroups() {
public List<EnergyTotal> getSubGroups() {
return subGroups;
}
public EnergyBlockViewMode getViewMode() {
public EnergyViewMode getViewMode() {
return viewMode;
}
public void setViewMode(EnergyBlockViewMode _viewMode) {
public void setViewMode(EnergyViewMode _viewMode) {
viewMode = _viewMode;
}
@@ -105,7 +88,7 @@ public class BreakerGroupSummary {
start = _start;
}
public void setSubGroups(List<BreakerGroupSummary> _subGroups) {
public void setSubGroups(List<EnergyTotal> _subGroups) {
subGroups = _subGroups;
}
@@ -117,28 +100,12 @@ public class BreakerGroupSummary {
joules = _joules;
}
public double getCharge() {
return charge;
public double getFlow() {
return flow;
}
public void setCharge(double _charge) {
charge = _charge;
}
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 void setFlow(double _flow) {
flow = _flow;
}
public double getPeakConsumption() {
@@ -173,17 +140,24 @@ public class BreakerGroupSummary {
peakFromGrid = _peakFromGrid;
}
public List<BreakerGroupSummary> getAllGroups() {
Map<String, BreakerGroupSummary> groups = new TreeMap<>();
getAllGroups(groups);
return new ArrayList<>(groups.values());
public double totalJoules() {
double total = joules;
for (EnergyTotal t : CollectionUtils.makeNotNull(subGroups)) {
total += t.totalJoules();
}
return total;
}
public void getAllGroups(Map<String, BreakerGroupSummary> _groups) {
if (NullUtils.isNotEmpty(getGroupId()))
_groups.put(getGroupId(), this);
for (BreakerGroupSummary group : CollectionUtils.makeNotNull(subGroups)) {
group.getAllGroups(_groups);
public List<EnergyTotal> flatten() {
List<EnergyTotal> totals = new ArrayList<>();
flatten(totals);
return totals;
}
private void flatten(List<EnergyTotal> _totals) {
_totals.add(this);
for (EnergyTotal total : CollectionUtils.makeNotNull(subGroups)) {
total.flatten(_totals);
}
}
}

View File

@@ -7,7 +7,7 @@ import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public enum EnergyBlockViewMode {
public enum EnergyViewMode {
DAY,
MONTH,
YEAR,
@@ -54,59 +54,58 @@ public enum EnergyBlockViewMode {
}
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);
return DateUtils.addMinutes(_dt, 1);
if (this == MONTH)
return DateUtils.addDays(_dt, 1, _tz);
if (this == YEAR)
cal.add(Calendar.MONTH, 1);
return cal.getTime();
return DateUtils.addMonths(_dt, 1, _tz);
return _dt;
}
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);
return DateUtils.addMinutes(_dt, -1);
if (this == MONTH)
return DateUtils.addDays(_dt, -1, _tz);
if (this == YEAR)
cal.add(Calendar.MONTH, -1);
return cal.getTime();
return DateUtils.addMonths(_dt, -1, _tz);
return _dt;
}
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);
return DateUtils.addDays(_dt, 1, _tz);
if (this == MONTH)
return DateUtils.addMonths(_dt, 1, _tz);
if (this == YEAR)
cal.add(Calendar.YEAR, 1);
return cal.getTime();
return DateUtils.addYears(_dt, 1, _tz);
return _dt;
}
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);
return DateUtils.addDays(_dt, -1, _tz);
if (this == MONTH)
return DateUtils.addMonths(_dt, -1, _tz);
if (this == YEAR)
cal.add(Calendar.YEAR, -1);
return cal.getTime();
return DateUtils.addYears(_dt, -1, _tz);
return _dt;
}
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);
if (this == YEAR)
return 12;
if (this == MONTH) {
Calendar end = DateUtils.getEndOfMonthCal(_start, _tz);
end.add(Calendar.MINUTE, -2);
return end.get(Calendar.DAY_OF_MONTH);
}
return blockCnt;
if (this == DAY) {
Date end = DateUtils.getMidnightAfter(_start, _tz);
return (int)((end.getTime() - _start.getTime()) / 60000);
}
return 1;
}
public int initBlockCount() {

View File

@@ -5,7 +5,7 @@ import com.lanternsoftware.util.dao.annotations.DBSerializable;
import java.util.Date;
import java.util.List;
@DBSerializable
@DBSerializable(autogen = false)
public class HubPowerMinute {
private int accountId;
private int hub;

View File

@@ -0,0 +1,48 @@
package com.lanternsoftware.datamodel.currentmonitor.dao;
import com.lanternsoftware.datamodel.currentmonitor.BillingPlan;
import com.lanternsoftware.datamodel.currentmonitor.BillingRate;
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 BillingPlanSerializer extends AbstractDaoSerializer<BillingPlan>
{
@Override
public Class<BillingPlan> getSupportedClass()
{
return BillingPlan.class;
}
@Override
public List<DaoProxyType> getSupportedProxies() {
return Collections.singletonList(DaoProxyType.MONGO);
}
@Override
public DaoEntity toDaoEntity(BillingPlan _o)
{
DaoEntity d = new DaoEntity();
d.put("account_id", _o.getAccountId());
d.put("plan_id", _o.getPlanId());
d.put("billing_day", _o.getBillingDay());
d.put("name", _o.getName());
d.put("rates", DaoSerializer.toDaoEntities(_o.getRates(), DaoProxyType.MONGO));
return d;
}
@Override
public BillingPlan fromDaoEntity(DaoEntity _d)
{
BillingPlan o = new BillingPlan();
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
o.setPlanId(DaoSerializer.getInteger(_d, "plan_id"));
o.setBillingDay(DaoSerializer.getInteger(_d, "billing_day"));
o.setName(DaoSerializer.getString(_d, "name"));
o.setRates(DaoSerializer.getList(_d, "rates", BillingRate.class));
return o;
}
}

View File

@@ -1,12 +1,13 @@
package com.lanternsoftware.datamodel.currentmonitor.dao;
import com.lanternsoftware.datamodel.currentmonitor.BillingCurrency;
import com.lanternsoftware.datamodel.currentmonitor.GridFlow;
import com.lanternsoftware.datamodel.currentmonitor.BillingRate;
import com.lanternsoftware.datamodel.currentmonitor.GridFlow;
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;
@@ -28,10 +29,10 @@ public class BillingRateSerializer extends AbstractDaoSerializer<BillingRate>
{
DaoEntity d = new DaoEntity();
d.put("meter", _o.getMeter());
d.put("day_billing_cycle_start", _o.getDayBillingCycleStart());
d.put("flow", DaoSerializer.toEnumName(_o.getFlow()));
d.put("rate", _o.getRate());
d.put("unit", DaoSerializer.toEnumName(_o.getCurrency()));
d.put("unit", DaoSerializer.toEnumName(_o.getCurrency())); //TODO: Remove post migration
d.put("currency", DaoSerializer.toEnumName(_o.getCurrency()));
d.put("time_of_day_start", _o.getTimeOfDayStart());
d.put("time_of_day_end", _o.getTimeOfDayEnd());
d.put("month_kwh_start", _o.getMonthKWhStart());
@@ -47,10 +48,11 @@ public class BillingRateSerializer extends AbstractDaoSerializer<BillingRate>
{
BillingRate o = new BillingRate();
o.setMeter(DaoSerializer.getInteger(_d, "meter"));
o.setDayBillingCycleStart(DaoSerializer.getInteger(_d, "day_billing_cycle_start"));
o.setFlow(DaoSerializer.getEnum(_d, "flow", GridFlow.class, GridFlow.BOTH));
o.setFlow(DaoSerializer.getEnum(_d, "flow", GridFlow.class));
o.setRate(DaoSerializer.getDouble(_d, "rate"));
o.setCurrency(DaoSerializer.getEnum(_d, "unit", BillingCurrency.class));
o.setCurrency(DaoSerializer.getEnum(_d, "currency", BillingCurrency.class));
if (o.getCurrency() == null)
o.setCurrency(DaoSerializer.getEnum(_d, "unit", BillingCurrency.class));
o.setTimeOfDayStart(DaoSerializer.getInteger(_d, "time_of_day_start"));
o.setTimeOfDayEnd(DaoSerializer.getInteger(_d, "time_of_day_end"));
o.setMonthKWhStart(DaoSerializer.getDouble(_d, "month_kwh_start"));

View File

@@ -1,5 +1,6 @@
package com.lanternsoftware.datamodel.currentmonitor.dao;
import com.lanternsoftware.datamodel.currentmonitor.BillingPlan;
import com.lanternsoftware.datamodel.currentmonitor.BillingRate;
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
@@ -36,6 +37,7 @@ public class BreakerConfigSerializer extends AbstractDaoSerializer<BreakerConfig
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));
d.put("billing_plans", DaoSerializer.toDaoEntities(_o.getBillingPlans(), DaoProxyType.MONGO));
d.put("billing_rates", DaoSerializer.toDaoEntities(_o.getBillingRates(), DaoProxyType.MONGO));
d.put("version", _o.getVersion());
return d;
@@ -50,6 +52,7 @@ public class BreakerConfigSerializer extends AbstractDaoSerializer<BreakerConfig
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));
o.setBillingPlans(DaoSerializer.getList(_d, "billing_plans", BillingPlan.class));
o.setBillingRates(DaoSerializer.getList(_d, "billing_rates", BillingRate.class));
o.setVersion(DaoSerializer.getInteger(_d, "version"));
return o;

View File

@@ -2,7 +2,7 @@ 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.datamodel.currentmonitor.EnergyViewMode;
import com.lanternsoftware.util.CollectionUtils;
import com.lanternsoftware.util.DateUtils;
import com.lanternsoftware.util.dao.AbstractDaoSerializer;
@@ -11,12 +11,7 @@ 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;
import java.util.*;
public class BreakerGroupEnergySerializer extends AbstractDaoSerializer<BreakerGroupEnergy>
{
@@ -88,7 +83,7 @@ public class BreakerGroupEnergySerializer extends AbstractDaoSerializer<BreakerG
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.setViewMode(DaoSerializer.getEnum(_d, "view_mode", EnergyViewMode.class));
o.setStart(DaoSerializer.getDate(_d, "start"));
o.setSubGroups(DaoSerializer.getList(_d, "sub_groups", BreakerGroupEnergy.class));
o.setTimeZone(DateUtils.fromTimeZoneId(DaoSerializer.getString(_d, "timezone")));

View File

@@ -0,0 +1,78 @@
package com.lanternsoftware.datamodel.currentmonitor.dao;
import com.lanternsoftware.datamodel.currentmonitor.ChargeSummary;
import com.lanternsoftware.datamodel.currentmonitor.EnergyViewMode;
import com.lanternsoftware.util.CollectionUtils;
import com.lanternsoftware.util.DateUtils;
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 ChargeSummarySerializer extends AbstractDaoSerializer<ChargeSummary>
{
@Override
public Class<ChargeSummary> getSupportedClass()
{
return ChargeSummary.class;
}
@Override
public List<DaoProxyType> getSupportedProxies() {
return Collections.singletonList(DaoProxyType.MONGO);
}
@Override
public DaoEntity toDaoEntity(ChargeSummary _o)
{
DaoEntity d = new DaoEntity();
d.put("_id", _o.getId());
d.put("account_id", _o.getAccountId());
d.put("plan_id", _o.getPlanId());
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));
TimeZone tz = DateUtils.defaultTimeZone(_o.getTimezone());
d.put("timezone", tz.getID());
if (_o.getCharges() != null)
d.put("charges", CollectionUtils.toByteArray(_o.getCharges()));
d.put("total_usage_joules", _o.getTotalUsageJoules());
d.put("total_solar_joules", _o.getTotalSolarJoules());
d.put("from_grid_joules", _o.getFromGridJoules());
d.put("to_grid_joules", _o.getToGridJoules());
d.put("peak_to_grid", _o.getPeakToGrid());
d.put("peak_from_grid", _o.getPeakFromGrid());
d.put("peak_production", _o.getPeakProduction());
d.put("peak_consumption", _o.getPeakConsumption());
return d;
}
@Override
public ChargeSummary fromDaoEntity(DaoEntity _d)
{
ChargeSummary o = new ChargeSummary();
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
o.setPlanId(DaoSerializer.getInteger(_d, "plan_id"));
o.setGroupId(DaoSerializer.getString(_d, "group_id"));
o.setGroupName(DaoSerializer.getString(_d, "group_name"));
o.setViewMode(DaoSerializer.getEnum(_d, "view_mode", EnergyViewMode.class));
o.setStart(DaoSerializer.getDate(_d, "start"));
o.setSubGroups(DaoSerializer.getList(_d, "sub_groups", ChargeSummary.class));
o.setTimezone(DateUtils.fromTimeZoneId(DaoSerializer.getString(_d, "timezone")));
o.setCharges(CollectionUtils.toDoubleArray(DaoSerializer.getByteArray(_d, "charges")));
o.setTotalUsageJoules(DaoSerializer.getDouble(_d, "total_usage_joules"));
o.setTotalSolarJoules(DaoSerializer.getDouble(_d, "total_solar_joules"));
o.setFromGridJoules(DaoSerializer.getDouble(_d, "from_grid_joules"));
o.setToGridJoules(DaoSerializer.getDouble(_d, "to_grid_joules"));
o.setPeakToGrid(DaoSerializer.getDouble(_d, "peak_to_grid"));
o.setPeakFromGrid(DaoSerializer.getDouble(_d, "peak_from_grid"));
o.setPeakProduction(DaoSerializer.getDouble(_d, "peak_production"));
o.setPeakConsumption(DaoSerializer.getDouble(_d, "peak_consumption"));
return o;
}
}

View File

@@ -0,0 +1,69 @@
package com.lanternsoftware.datamodel.currentmonitor.dao;
import com.lanternsoftware.datamodel.currentmonitor.ChargeTotal;
import com.lanternsoftware.datamodel.currentmonitor.EnergyViewMode;
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 ChargeTotalSerializer extends AbstractDaoSerializer<ChargeTotal>
{
@Override
public Class<ChargeTotal> getSupportedClass()
{
return ChargeTotal.class;
}
@Override
public List<DaoProxyType> getSupportedProxies() {
return Collections.singletonList(DaoProxyType.MONGO);
}
@Override
public DaoEntity toDaoEntity(ChargeTotal _o)
{
DaoEntity d = new DaoEntity();
d.put("_id", _o.getId());
d.put("account_id", _o.getAccountId());
d.put("group_id", _o.getGroupId());
d.put("plan_id", _o.getPlanId());
d.put("view_mode", DaoSerializer.toEnumName(_o.getViewMode()));
d.put("start", DaoSerializer.toLong(_o.getStart()));
d.put("charge", _o.getCharge());
d.put("sub_groups", DaoSerializer.toDaoEntities(_o.getSubGroups(), DaoProxyType.MONGO));
d.put("total_usage_joules", _o.getTotalUsageJoules());
d.put("total_solar_joules", _o.getTotalSolarJoules());
d.put("from_grid_joules", _o.getFromGridJoules());
d.put("to_grid_joules", _o.getToGridJoules());
d.put("peak_to_grid", _o.getPeakToGrid());
d.put("peak_from_grid", _o.getPeakFromGrid());
d.put("peak_production", _o.getPeakProduction());
d.put("peak_consumption", _o.getPeakConsumption());
return d;
}
@Override
public ChargeTotal fromDaoEntity(DaoEntity _d)
{
ChargeTotal o = new ChargeTotal();
o.setAccountId(DaoSerializer.getInteger(_d, "account_id"));
o.setGroupId(DaoSerializer.getString(_d, "group_id"));
o.setPlanId(DaoSerializer.getInteger(_d, "plan_id"));
o.setViewMode(DaoSerializer.getEnum(_d, "view_mode", EnergyViewMode.class));
o.setStart(DaoSerializer.getDate(_d, "start"));
o.setCharge(DaoSerializer.getDouble(_d, "charge"));
o.setSubGroups(DaoSerializer.getList(_d, "sub_groups", ChargeTotal.class));
o.setTotalUsageJoules(DaoSerializer.getDouble(_d, "total_usage_joules"));
o.setTotalSolarJoules(DaoSerializer.getDouble(_d, "total_solar_joules"));
o.setFromGridJoules(DaoSerializer.getDouble(_d, "from_grid_joules"));
o.setToGridJoules(DaoSerializer.getDouble(_d, "to_grid_joules"));
o.setPeakToGrid(DaoSerializer.getDouble(_d, "peak_to_grid"));
o.setPeakFromGrid(DaoSerializer.getDouble(_d, "peak_from_grid"));
o.setPeakProduction(DaoSerializer.getDouble(_d, "peak_production"));
o.setPeakConsumption(DaoSerializer.getDouble(_d, "peak_consumption"));
return o;
}
}

View File

@@ -0,0 +1,73 @@
package com.lanternsoftware.datamodel.currentmonitor.dao;
import com.lanternsoftware.datamodel.currentmonitor.EnergySummary;
import com.lanternsoftware.datamodel.currentmonitor.EnergyViewMode;
import com.lanternsoftware.util.CollectionUtils;
import com.lanternsoftware.util.DateUtils;
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.Collections;
import java.util.List;
import java.util.TimeZone;
public class EnergySummarySerializer extends AbstractDaoSerializer<EnergySummary>
{
@Override
public Class<EnergySummary> getSupportedClass()
{
return EnergySummary.class;
}
@Override
public List<DaoProxyType> getSupportedProxies() {
return Collections.singletonList(DaoProxyType.MONGO);
}
@Override
public DaoEntity toDaoEntity(EnergySummary _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));
TimeZone tz = DateUtils.defaultTimeZone(_o.getTimeZone());
d.put("timezone", tz.getID());
if (_o.getEnergy() != null)
d.put("energy", CollectionUtils.toByteArray(_o.getEnergy()));
if (_o.getGridEnergy() != null)
d.put("grid_energy", CollectionUtils.toByteArray(_o.getGridEnergy()));
d.put("peak_to_grid", _o.getPeakToGrid());
d.put("peak_from_grid", _o.getPeakFromGrid());
d.put("peak_production", _o.getPeakProduction());
d.put("peak_consumption", _o.getPeakConsumption());
return d;
}
@Override
public EnergySummary fromDaoEntity(DaoEntity _d)
{
EnergySummary o = new EnergySummary();
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", EnergyViewMode.class));
o.setStart(DaoSerializer.getDate(_d, "start"));
o.setSubGroups(DaoSerializer.getList(_d, "sub_groups", EnergySummary.class));
o.setTimeZone(DateUtils.fromTimeZoneId(DaoSerializer.getString(_d, "timezone")));
o.setEnergy(CollectionUtils.toFloatArray(DaoSerializer.getByteArray(_d, "energy")));
o.setGridEnergy(CollectionUtils.toFloatArray(DaoSerializer.getByteArray(_d, "grid_energy")));
o.setPeakToGrid(DaoSerializer.getDouble(_d, "peak_to_grid"));
o.setPeakFromGrid(DaoSerializer.getDouble(_d, "peak_from_grid"));
o.setPeakProduction(DaoSerializer.getDouble(_d, "peak_production"));
o.setPeakConsumption(DaoSerializer.getDouble(_d, "peak_consumption"));
return o;
}
}

View File

@@ -1,7 +1,7 @@
package com.lanternsoftware.datamodel.currentmonitor.dao;
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroupSummary;
import com.lanternsoftware.datamodel.currentmonitor.EnergyBlockViewMode;
import com.lanternsoftware.datamodel.currentmonitor.EnergyTotal;
import com.lanternsoftware.datamodel.currentmonitor.EnergyViewMode;
import com.lanternsoftware.util.dao.AbstractDaoSerializer;
import com.lanternsoftware.util.dao.DaoEntity;
import com.lanternsoftware.util.dao.DaoProxyType;
@@ -9,12 +9,11 @@ import com.lanternsoftware.util.dao.DaoSerializer;
import java.util.Collections;
import java.util.List;
import java.util.TimeZone;
public class BreakerGroupSummarySerializer extends AbstractDaoSerializer<BreakerGroupSummary> {
public class EnergyTotalSerializer extends AbstractDaoSerializer<EnergyTotal> {
@Override
public Class<BreakerGroupSummary> getSupportedClass() {
return BreakerGroupSummary.class;
public Class<EnergyTotal> getSupportedClass() {
return EnergyTotal.class;
}
@Override
@@ -23,19 +22,16 @@ public class BreakerGroupSummarySerializer extends AbstractDaoSerializer<Breaker
}
@Override
public DaoEntity toDaoEntity(BreakerGroupSummary _o) {
public DaoEntity toDaoEntity(EnergyTotal _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("charge", _o.getCharge());
d.put("to_grid", _o.getToGrid());
d.put("from_grid", _o.getFromGrid());
d.put("flow", _o.getFlow());
d.put("peak_to_grid", _o.getPeakToGrid());
d.put("peak_from_grid", _o.getPeakFromGrid());
d.put("peak_production", _o.getPeakProduction());
@@ -44,18 +40,15 @@ public class BreakerGroupSummarySerializer extends AbstractDaoSerializer<Breaker
}
@Override
public BreakerGroupSummary fromDaoEntity(DaoEntity _d) {
BreakerGroupSummary o = new BreakerGroupSummary();
public EnergyTotal fromDaoEntity(DaoEntity _d) {
EnergyTotal o = new EnergyTotal();
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.setViewMode(DaoSerializer.getEnum(_d, "view_mode", EnergyViewMode.class));
o.setStart(DaoSerializer.getDate(_d, "start"));
o.setSubGroups(DaoSerializer.getList(_d, "sub_groups", BreakerGroupSummary.class));
o.setSubGroups(DaoSerializer.getList(_d, "sub_groups", EnergyTotal.class));
o.setJoules(DaoSerializer.getDouble(_d, "joules"));
o.setCharge(DaoSerializer.getDouble(_d, "charge"));
o.setToGrid(DaoSerializer.getDouble(_d, "to_grid"));
o.setFromGrid(DaoSerializer.getDouble(_d, "from_grid"));
o.setFlow(DaoSerializer.getDouble(_d, "flow"));
o.setPeakToGrid(DaoSerializer.getDouble(_d, "peak_to_grid"));
o.setPeakFromGrid(DaoSerializer.getDouble(_d, "peak_from_grid"));
o.setPeakProduction(DaoSerializer.getDouble(_d, "peak_production"));

View File

@@ -26,6 +26,7 @@ public class HubPowerMinuteSerializer extends AbstractDaoSerializer<HubPowerMinu
public DaoEntity toDaoEntity(HubPowerMinute _o)
{
DaoEntity d = new DaoEntity();
d.put("_id", _o.getId());
d.put("account_id", _o.getAccountId());
d.put("hub", _o.getHub());
d.put("minute", _o.getMinute());

View File

@@ -1,15 +1,19 @@
com.lanternsoftware.datamodel.currentmonitor.dao.AccountSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.BillingPlanSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.BillingRateSerializer
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.ChargeSummarySerializer
com.lanternsoftware.datamodel.currentmonitor.dao.ChargeTotalSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.EnergyBlockSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.EnergySummarySerializer
com.lanternsoftware.datamodel.currentmonitor.dao.EnergyTotalSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.HubPowerMinuteSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.MeterSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.NetworkStatusSerializer