use of com.serotonin.m2m2.view.stats.ValueChangeCounter in project ma-core-public by infiniteautomation.
the class StatisticsChartRenderer method addDataToModel.
@Override
public void addDataToModel(Map<String, Object> model, DataPointVO point) {
long startTime = getStartTime();
long endTime = startTime + getDuration();
PointValueFacade pointValueFacade = new PointValueFacade(point.getId());
List<PointValueTime> values = pointValueFacade.getPointValuesBetween(startTime, endTime);
PointValueTime startVT = null;
if (!values.isEmpty()) {
startVT = pointValueFacade.getPointValueBefore(startTime);
}
// Generate statistics on the values.
int dataTypeId = point.getPointLocator().getDataTypeId();
if (values.size() > 0) {
if (dataTypeId == DataTypes.BINARY || dataTypeId == DataTypes.MULTISTATE) {
// Runtime stats
StartsAndRuntimeList stats = new StartsAndRuntimeList(startTime, endTime, startVT, values);
model.put("start", startVT != null ? startTime : stats.getFirstTime());
model.put("end", endTime);
model.put("startsAndRuntimes", stats.getData());
} else if (dataTypeId == DataTypes.NUMERIC) {
AnalogStatistics stats = new AnalogStatistics(startTime, endTime, startVT, values);
model.put("start", startVT != null ? startTime : stats.getFirstTime());
model.put("end", endTime);
model.put("minimum", stats.getMinimumValue());
model.put("minTime", stats.getMinimumTime());
model.put("maximum", stats.getMaximumValue());
model.put("maxTime", stats.getMaximumTime());
model.put("average", stats.getAverage());
if (includeSum)
model.put("sum", stats.getSum());
model.put("count", stats.getCount());
model.put("noData", stats.getAverage() == null);
model.put("integral", stats.getIntegral());
} else if (dataTypeId == DataTypes.ALPHANUMERIC) {
ValueChangeCounter stats = new ValueChangeCounter(startTime, endTime, startVT, values);
model.put("changeCount", stats.getChanges());
}
}
model.put("logEntries", values.size());
}
use of com.serotonin.m2m2.view.stats.ValueChangeCounter in project ma-core-public by infiniteautomation.
the class AlphanumericPointWrapper method getStats.
public ValueChangeCounterWrapper getStats(long from, long to) {
PointValueTime start = point.getPointValueBefore(from);
List<PointValueTime> values = point.getPointValuesBetween(from, to);
ValueChangeCounter stats = new ValueChangeCounter(from, to, start, values);
ValueChangeCounterWrapper wrapper = new ValueChangeCounterWrapper(stats);
return wrapper;
}
use of com.serotonin.m2m2.view.stats.ValueChangeCounter in project ma-modules-public by infiniteautomation.
the class PointValueTimeJsonWriter method writeAllStatistics.
/*
* (non-Javadoc)
*
* @see
* com.serotonin.m2m2.web.mvc.rest.v1.model.pointValue.PointValueTimeWriter#writeAllStatistics(
* com.serotonin.m2m2.view.stats.ValueChangeCounter, com.serotonin.m2m2.vo.DataPointVO)
*/
@Override
public void writeAllStatistics(StatisticsGenerator statisticsGenerator, DataPointVO vo) throws IOException {
this.jgen.writeStartObject();
writeTimestamp(statisticsGenerator.getPeriodStartTime());
if (statisticsGenerator instanceof ValueChangeCounter) {
ValueChangeCounter stats = (ValueChangeCounter) statisticsGenerator;
if (vo.getPointLocator().getDataTypeId() == DataTypes.IMAGE)
this.writeImageValue(stats.getStartValue(), stats.getPeriodStartTime(), stats.getPeriodStartTime(), vo, RollupEnum.START.name());
else
this.writeDataValue(stats.getPeriodStartTime(), stats.getStartValue(), vo, RollupEnum.START.name());
if (vo.getPointLocator().getDataTypeId() == DataTypes.IMAGE)
this.writeImageValue(stats.getFirstValue(), stats.getFirstTime(), stats.getPeriodStartTime(), vo, RollupEnum.FIRST.name());
else
this.writeDataValue(stats.getPeriodStartTime(), stats.getFirstValue(), vo, RollupEnum.FIRST.name());
if (vo.getPointLocator().getDataTypeId() == DataTypes.IMAGE)
this.writeImageValue(stats.getLastValue(), stats.getLastTime(), stats.getPeriodStartTime(), vo, RollupEnum.LAST.name());
else
this.writeDataValue(stats.getPeriodStartTime(), stats.getLastValue(), vo, RollupEnum.LAST.name());
this.jgen.writeNumberField(RollupEnum.COUNT.name(), stats.getCount());
} else if (statisticsGenerator instanceof AnalogStatistics) {
AnalogStatistics stats = (AnalogStatistics) statisticsGenerator;
this.writeDouble(stats.getAverage(), vo, RollupEnum.AVERAGE.name());
this.writeDouble(stats.getDelta(), vo, RollupEnum.DELTA.name());
this.writeDouble(stats.getMinimumValue(), vo, RollupEnum.MINIMUM.name());
this.writeDouble(stats.getMaximumValue(), vo, RollupEnum.MAXIMUM.name());
Double acc = stats.getLastValue();
if (acc == null) {
acc = stats.getMaximumValue();
}
this.writeDouble(acc, vo, RollupEnum.ACCUMULATOR.name());
this.writeDouble(stats.getSum(), vo, RollupEnum.SUM.name());
this.writeDouble(stats.getStartValue(), vo, RollupEnum.START.name());
this.writeDouble(stats.getFirstValue(), vo, RollupEnum.FIRST.name());
this.writeDouble(stats.getLastValue(), vo, RollupEnum.LAST.name());
this.writeIntegral(stats.getIntegral(), vo, RollupEnum.INTEGRAL.name());
this.jgen.writeNumberField(RollupEnum.COUNT.name(), stats.getCount());
}
this.jgen.writeEndObject();
}
use of com.serotonin.m2m2.view.stats.ValueChangeCounter in project ma-modules-public by infiniteautomation.
the class ReportChartCreator method createContent.
/**
* Uses the given parameters to create the data for the fields of this class. Once the content has been created the
* getters for the fields can be used to retrieve.
*
* @param host - Mango's hostname
* @param port - Mango's port
* @param reportInstance
* @param reportDao
* @param inlinePrefix
* if this is non-null, it implies that the content should be inline.
* @param createExportFile
*/
public void createContent(String host, int port, ReportInstance reportInstance, ReportDao reportDao, String inlinePrefix, boolean createExportFile) {
this.inlinePrefix = inlinePrefix;
reportInstance.setTranslations(translations);
// Use a stream handler to get the report data from the database.
StreamHandler handler = new StreamHandler(host, port, reportInstance.getXidMap(), reportInstance.getReportStartTime(), reportInstance.getReportEndTime(), IMAGE_WIDTH, createExportFile, translations);
// Process the report content with the handler.
if (Common.databaseProxy.getNoSQLProxy() == null)
reportDao.reportInstanceDataSQL(reportInstance.getId(), handler);
else
reportDao.reportInstanceDataNoSQL(reportInstance.getId(), handler);
pointStatistics = handler.getPointStatistics();
devices = handler.getDevices();
pointMap = handler.getStatisticsMap();
UsedImagesDirective inlineImages = new UsedImagesDirective();
SubjectDirective subjectDirective = new SubjectDirective(translations);
// Prepare the model for the content rendering.
Map<String, Object> model = new HashMap<String, Object>();
model.put("fmt", new MessageFormatDirective(translations));
model.put("subject", subjectDirective);
model.put("img", inlineImages);
model.put("instance", reportInstance);
model.put("timezone", timeZone.getID());
model.put("points", pointStatistics);
model.put("inline", inlinePrefix == null ? "" : "cid:");
model.put("devices", devices);
model.put("mapped", pointMap);
model.put("ALPHANUMERIC", DataTypes.ALPHANUMERIC);
model.put("BINARY", DataTypes.BINARY);
model.put("MULTISTATE", DataTypes.MULTISTATE);
model.put("NUMERIC", DataTypes.NUMERIC);
model.put("IMAGE", DataTypes.IMAGE);
// Create the individual point charts
for (PointStatistics pointStat : pointStatistics) {
PointTimeSeriesCollection ptsc = new PointTimeSeriesCollection(timeZone);
if (pointStat.getNumericTimeSeries() != null)
ptsc.addNumericTimeSeries(pointStat.getNumericTimeSeries());
else if (pointStat.getDiscreteTimeSeries() != null)
ptsc.addDiscreteTimeSeries(pointStat.getDiscreteTimeSeries());
if (ptsc.hasData()) {
if (inlinePrefix != null)
model.put("chartName", inlinePrefix + pointStat.getChartName());
pointStat.setImageData(ImageChartUtils.getChartData(ptsc, POINT_IMAGE_WIDTH, POINT_IMAGE_HEIGHT, reportInstance.getReportStartTime(), reportInstance.getReportEndTime()));
}
// in the report I'll add it here while we are already iterating over the points that are included in the report
if (pointStat.getDataType() == DataTypes.IMAGE) {
ValueChangeCounter pointStatisticsGenerator = (ValueChangeCounter) pointStat.getStats();
ImageValue img = (ImageValue) (pointStatisticsGenerator.getLastValue());
if (img != null) {
try {
pointStat.setImageData(img.getImageData());
if (inlinePrefix != null)
model.put("chartName", inlinePrefix + pointStat.getChartName());
else {
// serve up the image using the reportImageChart servlet instead of the imageValueServlet that is used on flipbook page
// The path comes from the servlet path definition in web.xml.
model.put("chartName", IMAGE_SERVLET + pointStat.getChartName());
}
} catch (IOException e) {
LOG.error("failed to retrieve image data", e);
}
}
}
}
// consolidated chart
PointTimeSeriesCollection ptsc = handler.getPointTimeSeriesCollection();
if (ptsc.hasData()) {
if (inlinePrefix != null)
model.put("chartName", inlinePrefix + IMAGE_CONTENT_ID);
else {
chartName = "r" + reportInstance.getId() + ".png";
// The path comes from the servlet path definition in web.xml.
model.put("chartName", IMAGE_SERVLET + chartName);
}
imageData = ImageChartUtils.getChartData(ptsc, true, IMAGE_WIDTH, IMAGE_HEIGHT, reportInstance.getReportStartTime(), reportInstance.getReportEndTime());
}
List<EventInstance> events = null;
if (reportInstance.getIncludeEvents() != ReportVO.EVENTS_NONE) {
events = reportDao.getReportInstanceEvents(reportInstance.getId());
model.put("includeEvents", true);
model.put("events", events);
} else
model.put("includeEvents", false);
List<ReportUserComment> comments = null;
if (reportInstance.isIncludeUserComments()) {
comments = reportDao.getReportInstanceUserComments(reportInstance.getId());
// Only provide the list of point comments to the report. The event comments have already be correlated
// into the events list.
List<ReportUserComment> pointComments = new ArrayList<ReportUserComment>();
for (ReportUserComment c : comments) {
if (c.getCommentType() == UserCommentVO.TYPE_POINT)
pointComments.add(c);
}
model.put("includeUserComments", true);
model.put("userComments", pointComments);
} else
model.put("includeUserComments", false);
// Create the template.
Template ftl;
StringWriter writer = new StringWriter();
FileReader reader = null;
try {
File templateFile = ReportCommon.instance.getTemplateFile(reportInstance.getTemplateFile());
reader = new FileReader(templateFile);
ftl = new Template(reportInstance.getName(), reader, Common.freemarkerConfiguration);
ftl.process(model, writer);
} catch (FileNotFoundException e) {
LOG.error("Unable to find report template file: " + reportInstance.getName());
} catch (IOException e) {
// Couldn't load the template?
throw new ShouldNeverHappenException(e);
} catch (Exception e) {
// Error processing the FTL?
throw new ShouldNeverHappenException(e);
} finally {
if (reader != null)
try {
reader.close();
} catch (IOException e) {
LOG.error("Error closing template file reader: " + e.getMessage(), e);
}
}
// Save the content
html = writer.toString();
subject = subjectDirective.getSubject();
inlineImageList = inlineImages.getImageList();
// Save the export file (if any)
exportFile = handler.exportFile;
if (createExportFile && events != null) {
try {
eventFile = File.createTempFile("tempEventCSV", ".csv");
new EventCsvStreamer(new PrintWriter(new FileWriter(eventFile)), events, translations);
} catch (IOException e) {
LOG.error("Failed to create temp event file", e);
}
}
if (createExportFile && comments != null) {
try {
commentFile = File.createTempFile("tempCommentCSV", ".csv");
new UserCommentCsvStreamer(new PrintWriter(new FileWriter(commentFile)), comments, translations);
} catch (IOException e) {
LOG.error("Failed to create temp comment file", e);
}
}
}
use of com.serotonin.m2m2.view.stats.ValueChangeCounter in project ma-core-public by infiniteautomation.
the class ValueChangeCounterQuantizerTest method testStartValueNoPeriodValues.
@Test
public void testStartValueNoPeriodValues() throws IOException {
// Generate data at 12 noon for every day in the period
NextTimePeriodAdjuster adjuster = new NextTimePeriodAdjuster(TimePeriods.DAYS, 1);
// Reset time to track periods
time = ZonedDateTime.of(2017, 01, 01, 00, 00, 00, 0, zoneId);
MutableInt counter = new MutableInt(0);
BucketCalculator bc = new TimePeriodBucketCalculator(from, to, TimePeriods.DAYS, 1);
ValueChangeCounterQuantizer quantizer = new ValueChangeCounterQuantizer(bc, new StatisticsGeneratorQuantizerCallback<ValueChangeCounter>() {
@Override
public void quantizedStatistics(ValueChangeCounter statisticsGenerator) throws IOException {
counter.increment();
ValueChangeCounter stats = (ValueChangeCounter) statisticsGenerator;
// Test periodStart
Assert.assertEquals(time.toInstant().toEpochMilli(), stats.getPeriodStartTime());
// Test periodEnd
Assert.assertEquals(time.plusDays(1).toInstant().toEpochMilli(), stats.getPeriodEndTime());
// Test first
Assert.assertEquals(null, stats.getFirstValue());
Assert.assertEquals(null, stats.getFirstTime());
// Test last
Assert.assertEquals(null, stats.getLastValue());
Assert.assertEquals(null, stats.getLastTime());
// Test start
Assert.assertEquals(1, stats.getStartValue().getIntegerValue());
// Test count
Assert.assertEquals(0, stats.getCount());
// Test Changes
Assert.assertEquals(0, stats.getChanges());
// Move to next period time
time = (ZonedDateTime) adjuster.adjustInto(time);
}
});
quantizer.firstValue(new IdPointValueTime(1, new MultistateValue(1), time.minusHours(3).toInstant().toEpochMilli()), 0, true);
quantizer.done();
Assert.assertEquals(new Integer(31), counter.getValue());
}
Aggregations