Add billing rates and track cost for all energy readings.

This commit is contained in:
MarkBryanMilligan
2021-08-03 16:47:28 -05:00
parent 8221e8ebd5
commit 8d09ac39f2
26 changed files with 739 additions and 148 deletions

View File

@@ -0,0 +1,26 @@
package com.lanternsoftware.datamodel.currentmonitor;
import java.math.BigDecimal;
import java.math.RoundingMode;
public enum BillingCurrency {
DOLLAR("$"),
EURO(""),
POUND_STERLING("£");
public final String symbol;
BillingCurrency(String _symbol) {
symbol = _symbol;
}
public String format(double _value) {
return format(BigDecimal.valueOf(_value));
}
public String format(BigDecimal _value) {
if (_value.compareTo(BigDecimal.ZERO) < 0)
return "-" + symbol + _value.abs().setScale(2, RoundingMode.HALF_EVEN);
return symbol + _value.setScale(2, RoundingMode.HALF_EVEN);
}
}

View File

@@ -0,0 +1,6 @@
package com.lanternsoftware.datamodel.currentmonitor;
public enum BillingMode {
CONSUMPTION,
PRODUCTION;
}

View File

@@ -0,0 +1,179 @@
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.TimeZone;
@DBSerializable
public class BillingRate {
private int meter;
private int dayBillingCycleStart;
private BillingMode mode;
private double rate;
private BillingCurrency currency;
private int timeOfDayStart;
private int timeOfDayEnd;
private double monthKWhStart;
private double monthKWhEnd;
private Date beginEffective;
private Date endEffective;
boolean recursAnnually;
public int getMeter() {
return meter;
}
public void setMeter(int _meter) {
meter = _meter;
}
public int getDayBillingCycleStart() {
return dayBillingCycleStart;
}
public void setDayBillingCycleStart(int _dayBillingCycleStart) {
dayBillingCycleStart = _dayBillingCycleStart;
}
public BillingMode getMode() {
return mode;
}
public void setMode(BillingMode _mode) {
mode = _mode;
}
public double getRate() {
return rate;
}
public void setRate(double _rate) {
rate = _rate;
}
public BillingCurrency getCurrency() {
return currency;
}
public void setCurrency(BillingCurrency _currency) {
currency = _currency;
}
public int getTimeOfDayStart() {
return timeOfDayStart;
}
public void setTimeOfDayStart(int _timeOfDayStart) {
timeOfDayStart = _timeOfDayStart;
}
public int getTimeOfDayEnd() {
return timeOfDayEnd;
}
public void setTimeOfDayEnd(int _timeOfDayEnd) {
timeOfDayEnd = _timeOfDayEnd;
}
public double getMonthKWhStart() {
return monthKWhStart;
}
public void setMonthKWhStart(double _monthKWhStart) {
monthKWhStart = _monthKWhStart;
}
public double getMonthKWhEnd() {
return monthKWhEnd;
}
public void setMonthKWhEnd(double _monthKWhEnd) {
monthKWhEnd = _monthKWhEnd;
}
public Date getBeginEffective() {
return beginEffective;
}
public void setBeginEffective(Date _beginEffective) {
beginEffective = _beginEffective;
}
public Date getEndEffective() {
return endEffective;
}
public void setEndEffective(Date _endEffective) {
endEffective = _endEffective;
}
public boolean isRecursAnnually() {
return recursAnnually;
}
public void setRecursAnnually(boolean _recursAnnually) {
recursAnnually = _recursAnnually;
}
public boolean isApplicable(BillingMode _mode, int _meter, double _monthKWh, Date _time, TimeZone _tz) {
if (mode != _mode)
return false;
if (_meter != meter)
return false;
if ((monthKWhStart > 0) && (_monthKWh < monthKWhStart))
return false;
if ((monthKWhEnd > 0) && (_monthKWh >= monthKWhEnd))
return false;
if ((beginEffective != null) && (endEffective != null) && recursAnnually) {
Date begin = beginEffective;
Date end = endEffective;
while (_time.before(begin)) {
begin = DateUtils.addYears(begin, -1, _tz);
end = DateUtils.addYears(end, -1, _tz);
}
while (_time.after(end)) {
begin = DateUtils.addYears(begin, 1, _tz);
end = DateUtils.addYears(end, 1, _tz);
}
if (!DateUtils.isBetween(_time, begin, end))
return false;
}
else {
if ((beginEffective != null) && _time.before(beginEffective))
return false;
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);
}
public double apply(double _kWh) {
return rate * _kWh;
}
public BillingRate duplicate() {
BillingRate r = new BillingRate();
r.setMeter(meter);
r.setDayBillingCycleStart(dayBillingCycleStart);
r.setMode(mode);
r.setRate(rate);
r.setCurrency(currency);
r.setTimeOfDayStart(timeOfDayStart);
r.setTimeOfDayEnd(timeOfDayEnd);
r.setMonthKWhStart(monthKWhStart);
r.setMonthKWhEnd(monthKWhEnd);
r.setBeginEffective(beginEffective);
r.setEndEffective(endEffective);
r.setRecursAnnually(recursAnnually);
return r;
}
}

View File

@@ -17,6 +17,7 @@ public class BreakerConfig {
private List<BreakerPanel> panels;
private List<BreakerHub> breakerHubs;
private List<BreakerGroup> breakerGroups;
private List<BillingRate> billingRates;
private int version;
public BreakerConfig() {
@@ -66,6 +67,14 @@ public class BreakerConfig {
breakerGroups = _breakerGroups;
}
public List<BillingRate> getBillingRates() {
return billingRates;
}
public void setBillingRates(List<BillingRate> _billingRates) {
billingRates = _billingRates;
}
public int getVersion() {
return version;
}
@@ -169,4 +178,8 @@ public class BreakerConfig {
}
return null;
}
public BillingCurrency getCurrency() {
return CollectionUtils.getFirst(CollectionUtils.transformToSet(billingRates, BillingRate::getCurrency));
}
}

View File

@@ -7,12 +7,14 @@ import com.lanternsoftware.util.dao.DaoSerializer;
import com.lanternsoftware.util.dao.annotations.DBSerializable;
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.Objects;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeMap;
@@ -33,36 +35,18 @@ public class BreakerGroupEnergy {
public BreakerGroupEnergy() {
}
public BreakerGroupEnergy(BreakerGroup _group, Map<String, List<BreakerPower>> _powerReadings, EnergyBlockViewMode _viewMode, Date _start, TimeZone _timezone) {
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, _powerReadings, _viewMode, _start, timezone));
energyBlocks = new ArrayList<>();
List<String> breakerKeys = CollectionUtils.transform(_group.getBreakers(), Breaker::getKey);
if (!breakerKeys.isEmpty()) {
for (BreakerPower power : CollectionUtils.aggregate(breakerKeys, _powerReadings::get)) {
addEnergy(groupId, power.getReadTime(), power.getPower());
}
}
subGroups = CollectionUtils.transform(_group.getSubGroups(), _g -> new BreakerGroupEnergy(_g, null, _viewMode, _start, _month, _rates, timezone));
addEnergy(_group, _power, _month, _rates);
}
public BreakerGroupEnergy(BreakerGroup _group, List<HubPowerMinute> _power, EnergyBlockViewMode _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 BreakerGroupEnergy(_g, (List<HubPowerMinute>)null, _viewMode, _start, timezone));
energyBlocks = new ArrayList<>();
addEnergy(_group, _power);
}
public void addEnergy(BreakerGroup _group, List<HubPowerMinute> _hubPower) {
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()) {
@@ -70,16 +54,20 @@ public class BreakerGroupEnergy {
breakerKeyToGroup.put(b.getKey(), group);
}
}
addEnergy(breakers, breakerKeyToGroup, _hubPower);
addEnergy(breakers, breakerKeyToGroup, _hubPower, _month, _rates);
}
public void addEnergy(Map<String, Breaker> _breakers, Map<String, BreakerGroup> _breakerKeyToGroup, List<HubPowerMinute> _hubPower) {
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;
Date minute = CollectionUtils.getFirst(_hubPower).getMinuteAsDate();
resetEnergy(minute);
Map<Integer, MeterMinute> meters = new HashMap<>();
_hubPower.sort(Comparator.comparing(HubPowerMinute::getMinute));
for (Date minute : CollectionUtils.transformToSet(_hubPower, HubPowerMinute::getMinuteAsDate)) {
resetEnergy(minute);
}
int idx;
Map<MeterMinute, MeterMinuteValues> meters = new HashMap<>();
for (HubPowerMinute hubPower : _hubPower) {
Date minute = hubPower.getMinuteAsDate();
for (BreakerPowerMinute breaker : CollectionUtils.makeNotNull(hubPower.getBreakers())) {
Breaker b = _breakers.get(breaker.breakerKey());
if (b == null)
@@ -87,26 +75,68 @@ public class BreakerGroupEnergy {
BreakerGroup group = _breakerKeyToGroup.get(breaker.breakerKey());
if (group == null)
continue;
MeterMinute meter = meters.computeIfAbsent(b.getMeter(), _p->new MeterMinute());
int idx = 0;
for (Float power : CollectionUtils.makeNotNull(breaker.getReadings())) {
if (power > 0)
meter.usage[idx] += power;
else
meter.solar[idx] += -power;
if (power != 0.0)
addEnergy(group.getId(), minute, power);
idx++;
MeterMinuteValues meter = meters.computeIfAbsent(new MeterMinute(b.getMeter(), minute), _p->new MeterMinuteValues());
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++;
}
}
}
}
for (MeterMinute meter : meters.values()) {
double monthFromGrid = _month == null ? 0.0 : _month.getFromGrid();
double secondFromGrid;
for (Map.Entry<MeterMinute, MeterMinuteValues> meter : meters.entrySet()) {
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> productionRates = CollectionUtils.filter(_rates, _r->_r.isApplicable(BillingMode.PRODUCTION, meter.getKey().meter, monthkWh, meter.getKey().minute, timezone));
for (int i = 0; i < 60; i++) {
if (meter.usage[i] > meter.solar[i])
fromGrid += meter.usage[i] - meter.solar[i];
else
toGrid += meter.solar[i] - meter.usage[i];
secondFromGrid = meter.getValue().usage[i] - meter.getValue().solar[i];
monthFromGrid += secondFromGrid;
if (secondFromGrid > 0) {
fromGrid += secondFromGrid;
for (BillingRate rate : consumptionRates) {
meter.getValue().charges[i] += rate.apply(secondFromGrid/3600000);
}
}
else {
toGrid -= secondFromGrid;
for (BillingRate rate : productionRates) {
meter.getValue().charges[i] += rate.apply(secondFromGrid/3600000);
}
}
}
}
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;
MeterMinuteValues meter = meters.get(new MeterMinute(b.getMeter(), minute));
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);
}
}
}
@@ -120,16 +150,31 @@ public class BreakerGroupEnergy {
}
}
public void addEnergy(String _groupId, Date _readTime, double _joules) {
private EnergyBlock getBlock(String _groupId, Date _readTime) {
if (NullUtils.isEqual(groupId, _groupId))
getBlock(_readTime).addJoules(_joules);
return getBlock(_readTime);
else {
for (BreakerGroupEnergy subGroup : CollectionUtils.makeNotNull(subGroups)) {
subGroup.addEnergy(_groupId, _readTime, _joules);
EnergyBlock block = subGroup.getBlock(_groupId, _readTime);
if (block != null)
return block;
}
return null;
}
}
private void addEnergy(String _groupId, Date _readTime, double _joules) {
EnergyBlock block = getBlock(_groupId, _readTime);
if (block != null)
block.addJoules(_joules);
}
private void addCharge(String _groupId, Date _readTime, double _charge) {
EnergyBlock block = getBlock(_groupId, _readTime);
if (block != null)
block.addCharge(_charge);
}
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());
@@ -142,6 +187,7 @@ public class BreakerGroupEnergy {
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());
}
@@ -154,10 +200,10 @@ public class BreakerGroupEnergy {
private EnergyBlock getBlock(Date _readTime, boolean _add) {
int size = CollectionUtils.size(energyBlocks);
int idx = viewMode.blockIndex(_readTime, timezone);
int idx = viewMode.blockIndex(start, _readTime, timezone);
if (_add && (idx >= size)) {
if (energyBlocks == null)
energyBlocks = new ArrayList<>();
energyBlocks = new ArrayList<>(viewMode.initBlockCount());
LinkedList<EnergyBlock> newBlocks = new LinkedList<>();
Date end = viewMode.toBlockEnd(_readTime, timezone);
while (idx >= size) {
@@ -297,6 +343,38 @@ public class BreakerGroupEnergy {
return joules;
}
public double charge() {
return charge(null);
}
public double charge(Set<String> _selectedBreakers) {
return charge(_selectedBreakers, true);
}
public double charge(Set<String> _selectedBreakers, BillingMode _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, BillingMode _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 == BillingMode.PRODUCTION) && energy.getCharge() < 0.0) || (_mode == BillingMode.CONSUMPTION && energy.getCharge() > 0.0))
charge += energy.getCharge();
}
}
return charge;
}
public List<BreakerGroupEnergy> getAllGroups() {
Map<String, BreakerGroupEnergy> groups = new TreeMap<>();
getAllGroups(groups);
@@ -343,7 +421,31 @@ public class BreakerGroupEnergy {
}
private static class MeterMinute {
private final int meter;
private final Date minute;
public MeterMinute(int _meter, Date _minute) {
meter = _meter;
minute = _minute;
}
@Override
public boolean equals(Object _o) {
if (this == _o) return true;
if (_o == null || getClass() != _o.getClass()) return false;
MeterMinute that = (MeterMinute) _o;
return meter == that.meter && minute.equals(that.minute);
}
@Override
public int hashCode() {
return Objects.hash(meter, minute);
}
}
private static class MeterMinuteValues {
public double[] usage = new double[60];
public double[] solar = new double[60];
public double[] charges = new double[60];
}
}

View File

@@ -21,6 +21,7 @@ public class BreakerGroupSummary {
private Date start;
private List<BreakerGroupSummary> subGroups;
private double joules;
private double charge;
private double toGrid;
private double fromGrid;
@@ -35,6 +36,7 @@ public class BreakerGroupSummary {
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();
}
@@ -107,6 +109,14 @@ public class BreakerGroupSummary {
joules = _joules;
}
public double getCharge() {
return charge;
}
public void setCharge(double _charge) {
charge = _charge;
}
public double getToGrid() {
return toGrid;
}

View File

@@ -10,6 +10,7 @@ public class EnergyBlock {
private Date start;
private Date end;
private double joules;
private double charge;
public EnergyBlock() {
}
@@ -48,6 +49,17 @@ public class EnergyBlock {
joules = _joules;
}
public double getCharge() {
return charge;
}
public void setCharge(double _charge) {
charge = _charge;
}
public void addCharge(double _charge) {
charge += _charge;
}
public double wattHours() {
return joules / 3600;
}

View File

@@ -109,10 +109,19 @@ public enum EnergyBlockViewMode {
return blockCnt;
}
public int blockIndex(Date _readTime, TimeZone _tz) {
public int initBlockCount() {
if (this == ALL)
return 1;
if (this == YEAR)
return 12;
if (this == MONTH)
return 31;
return 1500;
}
public int blockIndex(Date _dayStart, Date _readTime, TimeZone _tz) {
if (this == DAY) {
Date start = DateUtils.getMidnightBefore(_readTime, _tz);
return (int)((_readTime.getTime() - start.getTime())/60000);
return (int)((_readTime.getTime() - _dayStart.getTime())/60000);
}
else if (this == MONTH) {
Calendar read = DateUtils.toCalendar(_readTime, _tz);

View File

@@ -45,4 +45,12 @@ public enum HubConfigCharacteristic {
public boolean isChar(String _char) {
return NullUtils.isEqual(name(), _char);
}
public static HubConfigCharacteristic fromUUID(UUID _uuid) {
for (HubConfigCharacteristic c : values()) {
if (c.uuid.equals(_uuid))
return c;
}
return null;
}
}

View File

@@ -0,0 +1,63 @@
package com.lanternsoftware.datamodel.currentmonitor.dao;
import com.lanternsoftware.datamodel.currentmonitor.BillingCurrency;
import com.lanternsoftware.datamodel.currentmonitor.BillingMode;
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 BillingRateSerializer extends AbstractDaoSerializer<BillingRate>
{
@Override
public Class<BillingRate> getSupportedClass()
{
return BillingRate.class;
}
@Override
public List<DaoProxyType> getSupportedProxies() {
return Collections.singletonList(DaoProxyType.MONGO);
}
@Override
public DaoEntity toDaoEntity(BillingRate _o)
{
DaoEntity d = new DaoEntity();
d.put("meter", _o.getMeter());
d.put("day_billing_cycle_start", _o.getDayBillingCycleStart());
d.put("mode", DaoSerializer.toEnumName(_o.getMode()));
d.put("rate", _o.getRate());
d.put("unit", 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());
d.put("month_kwh_end", _o.getMonthKWhEnd());
d.put("begin_effective", DaoSerializer.toLong(_o.getBeginEffective()));
d.put("end_effective", DaoSerializer.toLong(_o.getEndEffective()));
d.put("recurs_annually", _o.isRecursAnnually());
return d;
}
@Override
public BillingRate fromDaoEntity(DaoEntity _d)
{
BillingRate o = new BillingRate();
o.setMeter(DaoSerializer.getInteger(_d, "meter"));
o.setDayBillingCycleStart(DaoSerializer.getInteger(_d, "day_billing_cycle_start"));
o.setMode(DaoSerializer.getEnum(_d, "mode", BillingMode.class));
o.setRate(DaoSerializer.getDouble(_d, "rate"));
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"));
o.setMonthKWhEnd(DaoSerializer.getDouble(_d, "month_kwh_end"));
o.setBeginEffective(DaoSerializer.getDate(_d, "begin_effective"));
o.setEndEffective(DaoSerializer.getDate(_d, "end_effective"));
o.setRecursAnnually(DaoSerializer.getBoolean(_d, "recurs_annually"));
return o;
}
}

View File

@@ -1,5 +1,6 @@
package com.lanternsoftware.datamodel.currentmonitor.dao;
import com.lanternsoftware.datamodel.currentmonitor.BillingRate;
import com.lanternsoftware.datamodel.currentmonitor.BreakerConfig;
import com.lanternsoftware.datamodel.currentmonitor.BreakerGroup;
import com.lanternsoftware.datamodel.currentmonitor.BreakerHub;
@@ -35,6 +36,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_rates", DaoSerializer.toDaoEntities(_o.getBillingRates(), DaoProxyType.MONGO));
d.put("version", _o.getVersion());
return d;
}
@@ -48,6 +50,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.setBillingRates(DaoSerializer.getList(_d, "billing_rates", BillingRate.class));
o.setVersion(DaoSerializer.getInteger(_d, "version"));
return o;
}

View File

@@ -48,6 +48,7 @@ public class BreakerGroupEnergySerializer extends AbstractDaoSerializer<BreakerG
Date start = _o.getStart();
Date now = new Date();
ByteBuffer bb = ByteBuffer.allocate(_o.getViewMode().blockCount(start, tz) * 4);
ByteBuffer cb = ByteBuffer.allocate(_o.getViewMode().blockCount(start, tz) * 8);
for (EnergyBlock b : _o.getEnergyBlocks()) {
if (b.getStart().before(start))
continue;
@@ -55,15 +56,21 @@ public class BreakerGroupEnergySerializer extends AbstractDaoSerializer<BreakerG
break;
while (start.before(b.getStart())) {
bb.putFloat(0);
cb.putDouble(0);
start = _o.getViewMode().toBlockEnd(start, tz);
}
bb.putFloat((float) b.getJoules());
cb.putDouble(b.getCharge());
start = _o.getViewMode().toBlockEnd(start, tz);
}
if (bb.position() < bb.limit())
if (bb.position() < bb.limit()) {
d.put("blocks", Arrays.copyOfRange(bb.array(), 0, bb.position()));
else
d.put("charges", Arrays.copyOfRange(cb.array(), 0, cb.position()));
}
else {
d.put("blocks", bb.array());
d.put("charges", cb.array());
}
}
d.put("to_grid", _o.getToGrid());
d.put("from_grid", _o.getFromGrid());
@@ -93,6 +100,14 @@ public class BreakerGroupEnergySerializer extends AbstractDaoSerializer<BreakerG
}
}
o.setEnergyBlocks(blocks);
byte[] chargeData = DaoSerializer.getByteArray(_d, "charges");
int idx = 0;
if (CollectionUtils.length(chargeData) > 0) {
ByteBuffer bb = ByteBuffer.wrap(chargeData);
while (bb.hasRemaining()) {
blocks.get(idx++).setCharge(bb.getDouble());
}
}
o.setToGrid(DaoSerializer.getDouble(_d, "to_grid"));
o.setFromGrid(DaoSerializer.getDouble(_d, "from_grid"));
return o;

View File

@@ -33,6 +33,7 @@ public class BreakerGroupSummarySerializer extends AbstractDaoSerializer<Breaker
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());
return d;
@@ -48,6 +49,7 @@ public class BreakerGroupSummarySerializer extends AbstractDaoSerializer<Breaker
o.setStart(DaoSerializer.getDate(_d, "start"));
o.setSubGroups(DaoSerializer.getList(_d, "sub_groups", BreakerGroupSummary.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"));
return o;

View File

@@ -28,6 +28,7 @@ public class EnergyBlockSerializer extends AbstractDaoSerializer<EnergyBlock>
d.put("start", DaoSerializer.toLong(_o.getStart()));
d.put("end", DaoSerializer.toLong(_o.getEnd()));
d.put("joules", _o.getJoules());
d.put("charge", _o.getCharge());
return d;
}
@@ -38,6 +39,7 @@ public class EnergyBlockSerializer extends AbstractDaoSerializer<EnergyBlock>
o.setStart(DaoSerializer.getDate(_d, "start"));
o.setEnd(DaoSerializer.getDate(_d, "end"));
o.setJoules(DaoSerializer.getDouble(_d, "joules"));
o.setCharge(DaoSerializer.getDouble(_d, "charge"));
return o;
}
}

View File

@@ -1,4 +1,5 @@
com.lanternsoftware.datamodel.currentmonitor.dao.AccountSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.BillingRateSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.BreakerConfigSerializer
com.lanternsoftware.datamodel.currentmonitor.dao.BreakerGroupEnergySerializer
com.lanternsoftware.datamodel.currentmonitor.dao.BreakerGroupSerializer