package com.henrypump.poc; import org.bson.Document; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Date; import java.util.Set; import static java.lang.Math.abs; /** * Created by patrickjmcd on 2/3/17. */ public class Measurement { private String tagName; private double currentValue; private double lastValue; private double average; private double total; private double dailyMax; private double dailyMin; private double[] totalHistory = new double[30]; private double[] averageHistory = new double[30]; private long numMeasurements; private double lastSentValue; private double sendDelta; private Database db; private long lastSentTimestamp; private long sendTimeDelta; private String units = null; private boolean useTotal; private boolean useAverage; Measurement(String tagName, Database db){ this.tagName = tagName; average = 0; total = 0; numMeasurements = 0; dailyMax = Double.MIN_VALUE; dailyMin = Double.MAX_VALUE; // Database code this.db = db; this.lastSentValue = 0.0; Document lastStored = this.db.getLastStoredMeasurement(this.tagName); try { Date lastStoredTimestamp = (Date) lastStored.get("dateStored"); ZonedDateTime timestamp = ZonedDateTime.ofInstant(lastStoredTimestamp.toInstant(), ZoneId.systemDefault()); if (isToday(timestamp)){ this.average = lastStored.getDouble("averageValue"); this.total = lastStored.getDouble("totalValue"); // this.lastSentValue = lastStored.getDouble("currentValue"); this.dailyMax = lastStored.getDouble("maxValue"); this.dailyMin = lastStored.getDouble("minValue"); this.sendDelta = lastStored.getDouble("storeDelta"); this.sendTimeDelta = lastStored.getLong("storeTime"); this.units = lastStored.getString("units"); // this.lastSentTimestamp = timestamp.toEpochSecond(); Document values = (Document) lastStored.get("values"); Object[] hours = values.keySet().toArray(); String maxHour = (String) hours[hours.length - 1]; Document maxHourDoc = (Document) values.get(maxHour); Object[] minutes = maxHourDoc.keySet().toArray(); String maxMinute = (String) minutes[minutes.length - 1]; this.lastSentValue = maxHourDoc.getDouble(maxMinute); this.numMeasurements = lastStored.getLong("numMeasurements"); System.out.println("Using stored value from " + ZonedDateTime.of(timestamp.getYear(), timestamp.getMonthValue(), timestamp.getDayOfMonth(), Integer.parseInt(maxHour), Integer.parseInt(maxMinute), 0, 0, timestamp.getZone()).toString() + " for " + this.tagName); } else { System.out.println("Cannot use stored value from " + timestamp.toString() + " for " + this.tagName); } } catch (NullPointerException e){ System.out.println("There was no previous measurement in the database for " + this.tagName); } } public double getCurrentValue() { return currentValue; } public double getLastValue() { return lastValue; } public double getAverage() { return average; } public double getTotal() { return total; } public long getNumMeasurements() { return numMeasurements; } public String getTagName() { return tagName; } public double getDailyMax() { return dailyMax; } public double getDailyMin() { return dailyMin; } public double getSendDelta() { return sendDelta; } public void setSendDelta(double sendDelta) { this.sendDelta = sendDelta; } public long getSendTimeDelta() { return sendTimeDelta; } public void setSendTimeDelta(long sendTimeDelta) { this.sendTimeDelta = sendTimeDelta; } public String getUnits() { return units; } public void setUnits(String units) { this.units = units; } public boolean isUseTotal() { return useTotal; } public void setUseTotal(boolean useTotal) { this.useTotal = useTotal; } public boolean isUseAverage() { return useAverage; } public void setUseAverage(boolean useAverage) { this.useAverage = useAverage; } private static boolean isToday(ZonedDateTime inpZDT){ ZonedDateTime now = ZonedDateTime.now(); if (now.toLocalDate().equals(inpZDT.toLocalDate())){ return true; } return false; }; void update(double value) { long currentTimestamp = ZonedDateTime.now().toEpochSecond(); lastValue = currentValue; currentValue = value; numMeasurements = numMeasurements + 1; average = average * (((float)numMeasurements - 1)/(float)numMeasurements) + (currentValue / (float)numMeasurements); total = total + value; dailyMax = Math.max(dailyMax, currentValue); dailyMin = Math.min(dailyMin, currentValue); if(abs(currentValue - lastSentValue) > sendDelta || (currentTimestamp - lastSentTimestamp) > (sendTimeDelta)){ long l = db.newMeasurement(this); lastSentValue = currentValue; lastSentTimestamp = currentTimestamp; } } void endOfDay(){ db.newDailyTotal(this); System.arraycopy(totalHistory, 0, totalHistory, 1, totalHistory.length-1); System.arraycopy(averageHistory, 0, averageHistory, 1, averageHistory.length-1); totalHistory[0] = total; averageHistory[0] = average; total = 0; average = 0; dailyMax = Double.MIN_VALUE; dailyMin = Double.MAX_VALUE; numMeasurements = 0; } }