Search in sources :

Example 1 with MutableIntegral

use of me.retrodaredevil.solarthing.util.integration.MutableIntegral in project solarthing by wildmountainfarms.

the class BatteryRecordCacheNodeCreator method create.

@Override
public IdentificationCacheNode<BatteryRecordDataCache> create(IdentifierFragment identifierFragment, List<TimestampedPacket<BatteryVoltage>> timestampedPackets, Instant periodStart, Duration periodDuration) {
    long periodStartDateMillis = periodStart.toEpochMilli();
    long previousPeriodStartDateMillis = periodStartDateMillis - periodDuration.toMillis();
    long unknownCutOffDateMillis = periodStartDateMillis - CacheHandler.INFO_DURATION.toMillis();
    long periodEndDateMillis = periodStart.toEpochMilli() + periodDuration.toMillis();
    boolean firstInPeriod = true;
    // initializations to -1 are necessary. We will use firstInPeriod to know if they have been initialized
    float min = -1;
    long minDateMillis = -1;
    float max = -1;
    long maxDateMillis = -1;
    MutableIntegral mainVoltHourIntegral = new TrapezoidalRuleAccumulator();
    TimestampedPacket<BatteryVoltage> lastDataBeforePreviousPeriodStart = null;
    TimestampedPacket<BatteryVoltage> lastDataBeforePeriodStart = null;
    TimestampedPacket<BatteryVoltage> firstDataAfterPeriodStart = null;
    TimestampedPacket<BatteryVoltage> lastDataBeforePeriodEnd = null;
    for (TimestampedPacket<BatteryVoltage> packet : timestampedPackets) {
        final float voltage = packet.getPacket().getBatteryVoltage();
        final long dateMillis = packet.getDateMillis();
        if (dateMillis >= periodEndDateMillis) {
            break;
        }
        if (dateMillis < unknownCutOffDateMillis) {
            continue;
        }
        if (dateMillis < previousPeriodStartDateMillis) {
            lastDataBeforePreviousPeriodStart = packet;
        } else if (dateMillis < periodStartDateMillis) {
            lastDataBeforePeriodStart = packet;
        } else {
            if (firstDataAfterPeriodStart == null) {
                firstDataAfterPeriodStart = packet;
            }
            lastDataBeforePeriodEnd = packet;
            if (firstInPeriod || voltage < min) {
                min = voltage;
                minDateMillis = dateMillis;
            }
            if (firstInPeriod || voltage > max) {
                max = voltage;
                maxDateMillis = dateMillis;
            }
            if (firstInPeriod && lastDataBeforePeriodStart != null) {
                double hours = lastDataBeforePeriodStart.getDateMillis() / (1000.0 * 60 * 60);
                mainVoltHourIntegral.add(hours, lastDataBeforePeriodStart.getPacket().getBatteryVoltage());
            }
            double hours = dateMillis / (1000.0 * 60 * 60);
            mainVoltHourIntegral.add(hours, voltage);
            firstInPeriod = false;
        }
    }
    final BatteryRecordDataCache.Record record;
    final Long firstDateMillis;
    final Long lastDateMillis;
    final Long unknownStartDateMillis;
    if (firstInPeriod) {
        record = null;
        firstDateMillis = null;
        lastDateMillis = null;
        unknownStartDateMillis = null;
    } else {
        final double unknownBatteryVoltageHours;
        final long unknownDurationMillis;
        if (lastDataBeforePeriodStart == null) {
            // we have no data from the previous period
            firstDateMillis = firstDataAfterPeriodStart.getDateMillis();
            // we will only have "unknown" data if there is no data in the previous period and we were able to get data from before the previous period
            if (lastDataBeforePreviousPeriodStart == null) {
                unknownStartDateMillis = null;
                unknownDurationMillis = 0;
                unknownBatteryVoltageHours = 0.0;
            } else {
                unknownStartDateMillis = lastDataBeforePreviousPeriodStart.getDateMillis();
                unknownDurationMillis = firstDataAfterPeriodStart.getDateMillis() - unknownStartDateMillis;
                double unknownPeriodAverageVoltage = (lastDataBeforePreviousPeriodStart.getPacket().getBatteryVoltage() + firstDataAfterPeriodStart.getPacket().getBatteryVoltage()) / 2.0;
                double hours = unknownDurationMillis / (1000.0 * 60 * 60);
                unknownBatteryVoltageHours = unknownPeriodAverageVoltage * hours;
            }
        } else {
            firstDateMillis = lastDataBeforePeriodStart.getDateMillis();
            unknownStartDateMillis = null;
            unknownDurationMillis = 0;
            unknownBatteryVoltageHours = 0.0;
        }
        lastDateMillis = lastDataBeforePeriodEnd.getDateMillis();
        record = new BatteryRecordDataCache.Record(min, minDateMillis, max, maxDateMillis, unknownBatteryVoltageHours, unknownDurationMillis, mainVoltHourIntegral.getIntegral(), lastDataBeforePeriodEnd.getDateMillis() - firstDateMillis, 0.0, 0L);
    }
    return new IdentificationCacheNode<>(identifierFragment.getFragmentId(), new BatteryRecordDataCache(identifierFragment.getIdentifier(), firstDateMillis, lastDateMillis, unknownStartDateMillis, record));
}
Also used : MutableIntegral(me.retrodaredevil.solarthing.util.integration.MutableIntegral) TrapezoidalRuleAccumulator(me.retrodaredevil.solarthing.util.integration.TrapezoidalRuleAccumulator) BatteryRecordDataCache(me.retrodaredevil.solarthing.type.cache.packets.data.BatteryRecordDataCache) IdentificationCacheNode(me.retrodaredevil.solarthing.type.cache.packets.IdentificationCacheNode) BatteryVoltage(me.retrodaredevil.solarthing.solar.common.BatteryVoltage)

Aggregations

BatteryVoltage (me.retrodaredevil.solarthing.solar.common.BatteryVoltage)1 IdentificationCacheNode (me.retrodaredevil.solarthing.type.cache.packets.IdentificationCacheNode)1 BatteryRecordDataCache (me.retrodaredevil.solarthing.type.cache.packets.data.BatteryRecordDataCache)1 MutableIntegral (me.retrodaredevil.solarthing.util.integration.MutableIntegral)1 TrapezoidalRuleAccumulator (me.retrodaredevil.solarthing.util.integration.TrapezoidalRuleAccumulator)1