use of com.infiniteautomation.mango.rest.latest.model.pointValue.PointValueField in project ma-modules-public by infiniteautomation.
the class PointValueTimeStreamCsvMessageConverter method writeInternal.
@Override
protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
MediaType contentType = outputMessage.getHeaders().getContentType();
JsonEncoding encoding = getJsonEncoding(contentType);
try {
PointValueTimeStream<?, ?> stream = (PointValueTimeStream<?, ?>) object;
stream.setContentType(StreamContentType.CSV);
JsonGenerator generator = this.objectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding);
// Set the schema
CsvSchema.Builder builder = CsvSchema.builder();
builder.setUseHeader(true);
// Setup our rendering parameters
LatestQueryInfo info = stream.getQueryInfo();
if (stream instanceof MultiPointTimeRangeDatabaseStream || stream instanceof MultiPointLatestDatabaseStream) {
if (info.isSingleArray()) {
if (info.isMultiplePointsPerArray()) {
Map<Integer, DataPointVO> voMap = stream.getVoMap();
Iterator<Integer> it = voMap.keySet().iterator();
boolean firstTimestamp = true;
while (it.hasNext()) {
String xid = voMap.get(it.next()).getXid();
for (PointValueField field : info.getFields()) {
if (field == PointValueField.TIMESTAMP) {
if (firstTimestamp)
field.createColumn(builder, xid);
firstTimestamp = false;
} else
field.createColumn(builder, xid);
}
}
} else {
for (PointValueField field : info.getFields()) field.createColumn(builder, null);
}
} else {
for (PointValueField field : info.getFields()) field.createColumn(builder, null);
}
} else if (stream instanceof MultiDataPointStatisticsQuantizerStream || stream instanceof MultiDataPointDefaultRollupStatisticsQuantizerStream) {
if (stream.getQueryInfo().isSingleArray()) {
if (stream.getQueryInfo().isMultiplePointsPerArray()) {
Map<Integer, DataPointVO> voMap = stream.getVoMap();
Iterator<Integer> it = voMap.keySet().iterator();
boolean firstTimestamp = true;
while (it.hasNext()) {
String xid = voMap.get(it.next()).getXid();
for (PointValueField field : info.getFields()) {
if (field == PointValueField.TIMESTAMP) {
if (firstTimestamp)
field.createColumn(builder, xid);
firstTimestamp = false;
} else if (field == PointValueField.VALUE) {
if (info.getRollup() == RollupEnum.ALL) {
for (RollupEnum rollup : getAllRollups()) {
builder.addColumn(xid + PointValueTimeWriter.DOT + rollup.name(), ColumnType.NUMBER_OR_STRING);
}
} else {
field.createColumn(builder, xid);
}
} else {
field.createColumn(builder, xid);
}
}
}
} else {
// Single array
if (info.getRollup() == RollupEnum.ALL) {
for (RollupEnum rollup : getAllRollups()) {
builder.addColumn(rollup.name(), ColumnType.NUMBER_OR_STRING);
}
for (PointValueField field : info.getFields()) {
if (field == PointValueField.VALUE)
continue;
field.createColumn(builder, null);
}
} else {
for (PointValueField field : info.getFields()) field.createColumn(builder, null);
}
}
} else {
if (info.getRollup() == RollupEnum.ALL) {
for (RollupEnum rollup : getAllRollups()) {
builder.addColumn(rollup.name(), ColumnType.NUMBER_OR_STRING);
}
for (PointValueField field : info.getFields()) {
if (field == PointValueField.VALUE)
continue;
field.createColumn(builder, null);
}
} else {
for (PointValueField field : info.getFields()) field.createColumn(builder, null);
}
}
}
generator.setSchema(builder.build());
PointValueTimeWriter writer = new PointValueTimeCsvWriter(stream.getQueryInfo(), stream.getVoMap().size(), generator);
try {
stream.start(writer);
stream.streamData(writer);
stream.finish(writer);
generator.flush();
} catch (QueryCancelledException e) {
throw new HttpMessageNotWritableException("Query Cancelled");
}
} catch (JsonProcessingException ex) {
throw new HttpMessageNotWritableException("Could not write content: " + ex.getMessage(), ex);
}
}
use of com.infiniteautomation.mango.rest.latest.model.pointValue.PointValueField in project ma-modules-public by infiniteautomation.
the class MultiPointStatisticsStreamTest method testSingleNumericPointBothChange.
@Test
public void testSingleNumericPointBothChange() throws IOException, QueryCancelledException {
// Setup the data to run once daily for 30 days
ZonedDateTime from = ZonedDateTime.of(2017, 01, 01, 00, 00, 00, 0, zoneId);
ZonedDateTime to = ZonedDateTime.of(2017, 02, 01, 00, 00, 00, 0, zoneId);
NextTimePeriodAdjuster adjuster = new NextTimePeriodAdjuster(TimePeriods.DAYS, 1);
int cacheSize = 10;
MockDataSourceVO ds = createDataSource();
DataPointVO dp = createDataPoint(ds.getId(), DataType.NUMERIC, cacheSize);
DataPointWrapper<AnalogStatistics> point = new DataPointWrapper<AnalogStatistics>(ds, dp, new PointValueTime(1.0, 0), (value) -> {
return new NumericValue(value.getDoubleValue() + 1.0);
}, (info, w) -> {
return new AnalogStatistics(info.getFromMillis(), info.getToMillis(), new PointValueTime(1.0, 0), w.values);
}, (w, gen, root) -> {
JsonNode stats = root.get(w.vo.getXid());
if (stats == null)
fail("Missing stats for point " + w.vo.getXid());
JsonNode stat = stats.get(PointValueTimeWriter.START);
if (stat == null)
fail("Missing " + PointValueTimeWriter.START + " entry");
PointValueTime value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getStartValue(), value.getDoubleValue(), 0.00001);
assertEquals(gen.getPeriodStartTime(), value.getTime());
stat = stats.get(PointValueTimeWriter.FIRST);
if (stat == null)
fail("Missing " + PointValueTimeWriter.FIRST + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getFirstValue(), value.getValue().getDoubleValue(), 0.00001);
assertEquals((long) gen.getFirstTime(), value.getTime());
stat = stats.get(PointValueTimeWriter.LAST);
if (stat == null)
fail("Missing " + PointValueTimeWriter.LAST + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getLastValue(), value.getValue().getDoubleValue(), 0.00001);
assertEquals((long) gen.getLastTime(), value.getTime());
stat = stats.get(PointValueTimeWriter.COUNT);
if (stat == null)
fail("Missing " + PointValueTimeWriter.COUNT + " entry");
assertEquals(gen.getCount(), stat.asInt());
stat = stats.get(PointValueTimeWriter.ACCUMULATOR);
if (stat == null)
fail("Missing " + PointValueTimeWriter.ACCUMULATOR + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
Double accumulatorValue = gen.getLastValue();
if (accumulatorValue == null)
accumulatorValue = gen.getMaximumValue();
assertEquals(accumulatorValue, value.getDoubleValue(), 0.00001);
stat = stats.get(PointValueTimeWriter.AVERAGE);
if (stat == null)
fail("Missing " + PointValueTimeWriter.AVERAGE + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getAverage(), value.getDoubleValue(), 0.00001);
stat = stats.get(PointValueTimeWriter.DELTA);
if (stat == null)
fail("Missing " + PointValueTimeWriter.DELTA + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getDelta(), value.getDoubleValue(), 0.00001);
stat = stats.get(PointValueTimeWriter.MINIMUM);
if (stat == null)
fail("Missing " + PointValueTimeWriter.MINIMUM + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getMinimumValue(), value.getValue().getDoubleValue(), 0.00001);
assertEquals((long) gen.getMinimumTime(), value.getTime());
stat = stats.get(PointValueTimeWriter.MAXIMUM);
if (stat == null)
fail("Missing " + PointValueTimeWriter.MAXIMUM + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getMaximumValue(), value.getValue().getDoubleValue(), 0.00001);
assertEquals((long) gen.getMaximumTime(), value.getTime());
stat = stats.get(PointValueTimeWriter.SUM);
if (stat == null)
fail("Missing " + PointValueTimeWriter.SUM + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getSum(), value.getDoubleValue(), 0.00001);
stat = stats.get(PointValueTimeWriter.INTEGRAL);
if (stat == null)
fail("Missing " + PointValueTimeWriter.INTEGRAL + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getIntegral(), value.getDoubleValue(), 0.00001);
});
// Insert the data skipping first day so we get the initial value
ZonedDateTime time = (ZonedDateTime) adjuster.adjustInto(from);
timer.setStartTime(time.toInstant().toEpochMilli());
while (time.toInstant().isBefore(to.toInstant())) {
point.updatePointValue(new PointValueTime(point.getNextValue(), time.toInstant().toEpochMilli()));
time = (ZonedDateTime) adjuster.adjustInto(time);
timer.fastForwardTo(time.toInstant().toEpochMilli());
}
// Insert some values directly into the cache
for (int i = 0; i < cacheSize; i++) {
time = (ZonedDateTime) adjuster.adjustInto(time);
timer.fastForwardTo(time.toInstant().toEpochMilli());
point.saveOnlyToCache(new PointValueTime(point.getNextValue(), timer.currentTimeMillis()));
}
// Ensure we get all the data
Instant now = Instant.ofEpochMilli(timer.currentTimeMillis() + 1);
to = ZonedDateTime.ofInstant(now, zoneId);
// Perform the query
String dateTimeFormat = null;
String timezone = zoneId.getId();
PointValueTimeCacheControl cache = PointValueTimeCacheControl.BOTH;
PointValueField[] fields = getFields();
ZonedDateTimeStatisticsQueryInfo info = new ZonedDateTimeStatisticsQueryInfo(from, to, dateTimeFormat, timezone, cache, fields);
test(info, point);
}
use of com.infiniteautomation.mango.rest.latest.model.pointValue.PointValueField in project ma-modules-public by infiniteautomation.
the class MultiPointStatisticsStreamTest method testSingleNumericPointOnlyCacheChange.
@Test
public void testSingleNumericPointOnlyCacheChange() throws IOException, QueryCancelledException {
// Setup the data to run once daily for 30 days
ZonedDateTime from = ZonedDateTime.of(2017, 01, 01, 00, 00, 00, 0, zoneId);
ZonedDateTime to = ZonedDateTime.of(2017, 02, 01, 00, 00, 00, 0, zoneId);
NextTimePeriodAdjuster adjuster = new NextTimePeriodAdjuster(TimePeriods.DAYS, 1);
int cacheSize = 10;
MockDataSourceVO ds = createDataSource();
DataPointVO dp = createDataPoint(ds.getId(), DataType.NUMERIC, cacheSize);
DataPointWrapper<AnalogStatistics> point = new DataPointWrapper<AnalogStatistics>(ds, dp, new PointValueTime(1.0, 0), (value) -> {
return new NumericValue(value.getDoubleValue() + 1.0);
}, (info, w) -> {
return new AnalogStatistics(info.getFromMillis(), info.getToMillis(), null, w.values);
}, (w, gen, root) -> {
JsonNode stats = root.get(w.vo.getXid());
if (stats == null)
fail("Missing stats for point " + w.vo.getXid());
JsonNode stat = stats.get(PointValueTimeWriter.START);
if (stat == null)
fail("Missing " + PointValueTimeWriter.START + " entry");
assertNull(gen.getStartValue());
assertTrue(stat.isNull());
stat = stats.get(PointValueTimeWriter.FIRST);
if (stat == null)
fail("Missing " + PointValueTimeWriter.FIRST + " entry");
PointValueTime value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getFirstValue(), value.getValue().getDoubleValue(), 0.00001);
assertEquals((long) gen.getFirstTime(), value.getTime());
stat = stats.get(PointValueTimeWriter.LAST);
if (stat == null)
fail("Missing " + PointValueTimeWriter.LAST + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getLastValue(), value.getValue().getDoubleValue(), 0.00001);
assertEquals((long) gen.getLastTime(), value.getTime());
stat = stats.get(PointValueTimeWriter.COUNT);
if (stat == null)
fail("Missing " + PointValueTimeWriter.COUNT + " entry");
assertEquals(gen.getCount(), stat.asInt());
stat = stats.get(PointValueTimeWriter.ACCUMULATOR);
if (stat == null)
fail("Missing " + PointValueTimeWriter.ACCUMULATOR + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
Double accumulatorValue = gen.getLastValue();
if (accumulatorValue == null)
accumulatorValue = gen.getMaximumValue();
assertEquals(accumulatorValue, value.getDoubleValue(), 0.00001);
stat = stats.get(PointValueTimeWriter.AVERAGE);
if (stat == null)
fail("Missing " + PointValueTimeWriter.AVERAGE + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getAverage(), value.getDoubleValue(), 0.00001);
stat = stats.get(PointValueTimeWriter.DELTA);
if (stat == null)
fail("Missing " + PointValueTimeWriter.DELTA + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getDelta(), value.getDoubleValue(), 0.00001);
stat = stats.get(PointValueTimeWriter.MINIMUM);
if (stat == null)
fail("Missing " + PointValueTimeWriter.MINIMUM + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getMinimumValue(), value.getValue().getDoubleValue(), 0.00001);
assertEquals((long) gen.getMinimumTime(), value.getTime());
stat = stats.get(PointValueTimeWriter.MAXIMUM);
if (stat == null)
fail("Missing " + PointValueTimeWriter.MAXIMUM + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getMaximumValue(), value.getValue().getDoubleValue(), 0.00001);
assertEquals((long) gen.getMaximumTime(), value.getTime());
stat = stats.get(PointValueTimeWriter.SUM);
if (stat == null)
fail("Missing " + PointValueTimeWriter.SUM + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getSum(), value.getDoubleValue(), 0.00001);
stat = stats.get(PointValueTimeWriter.INTEGRAL);
if (stat == null)
fail("Missing " + PointValueTimeWriter.INTEGRAL + " entry");
value = getPointValueTime(w.vo.getPointLocator().getDataType(), stat);
assertEquals(gen.getIntegral(), value.getDoubleValue(), 0.00001);
});
// Insert the data skipping first day so we get the initial value
ZonedDateTime time = (ZonedDateTime) adjuster.adjustInto(from);
timer.setStartTime(time.toInstant().toEpochMilli());
while (time.toInstant().isBefore(to.toInstant())) {
point.updatePointValue(new PointValueTime(point.getNextValue(), time.toInstant().toEpochMilli()));
time = (ZonedDateTime) adjuster.adjustInto(time);
timer.fastForwardTo(time.toInstant().toEpochMilli());
}
// Insert some values directly into the cache
point.values.clear();
for (int i = 0; i < cacheSize; i++) {
time = (ZonedDateTime) adjuster.adjustInto(time);
timer.fastForwardTo(time.toInstant().toEpochMilli());
point.saveOnlyToCache(new PointValueTime(point.getNextValue(), timer.currentTimeMillis()));
}
// Ensure we get all the data
Instant now = Instant.ofEpochMilli(timer.currentTimeMillis() + 1);
to = ZonedDateTime.ofInstant(now, zoneId);
// Perform the query
String dateTimeFormat = null;
String timezone = zoneId.getId();
PointValueTimeCacheControl cache = PointValueTimeCacheControl.CACHE_ONLY;
PointValueField[] fields = getFields();
ZonedDateTimeStatisticsQueryInfo info = new ZonedDateTimeStatisticsQueryInfo(from, to, dateTimeFormat, timezone, cache, fields);
test(info, point);
}
use of com.infiniteautomation.mango.rest.latest.model.pointValue.PointValueField in project ma-modules-public by infiniteautomation.
the class PointValueRestController method getStatistics.
@ApiOperation(value = "GET statistics for data point(s) over the given time range", notes = "From time inclusive, To time exclusive. Returns map of xid to Statistics object", response = PointValueTimeModel.class, responseContainer = "Map")
@RequestMapping(method = RequestMethod.GET, value = "/statistics/{xids}")
public Map<String, StreamingPointValueTimeModel> getStatistics(@ApiParam(value = "Point xids", required = true, allowMultiple = true) @PathVariable String[] xids, @ApiParam(value = "From time") @RequestParam(value = "from", required = false) @DateTimeFormat(iso = ISO.DATE_TIME) ZonedDateTime from, @ApiParam(value = "To time") @RequestParam(value = "to", required = false) @DateTimeFormat(iso = ISO.DATE_TIME) ZonedDateTime to, @ApiParam(value = "Time zone") @RequestParam(value = "timezone", required = false) String timezone, @ApiParam(value = "Date Time format pattern for timestamps as strings, if not included epoch milli number is used") @RequestParam(value = "dateTimeFormat", required = false) String dateTimeFormat, @ApiParam(value = "Fields to be included in the returned data, default is TIMESTAMP,VALUE") @RequestParam(required = false) PointValueField[] fields, Locale locale) {
var points = Arrays.stream(xids).distinct().map(dataPointService::get).collect(Collectors.toUnmodifiableSet());
var mapperBuilder = new StreamMapperBuilder().withDataPoints(points).withRollup(RollupEnum.ALL).withFields(fields).withDateTimeFormat(dateTimeFormat).withTimezone(timezone, from, to).withLocale(locale).withTimestampSource(TimestampSource.STATISTIC);
var aggregateMapper = mapperBuilder.build(AggregateValueMapper::new);
var rollupPeriod = Duration.between(from, to);
return points.stream().collect(Collectors.toUnmodifiableMap(DataPointVO::getXid, point -> {
var aggregateDao = dao.getAggregateDao();
try (var stream = aggregateDao.query(point, from, to, null, rollupPeriod)) {
return stream.map(aggregateMapper).findAny().orElseThrow();
}
}));
}
use of com.infiniteautomation.mango.rest.latest.model.pointValue.PointValueField in project ma-modules-public by infiniteautomation.
the class MultiPointStatisticsStreamTest method testSingleMultistatePointNoCacheNoChangeInitialValue.
/**
* Start with a value of 1 at time 0
* Then insert a value of 1 at midnight every day during Jan 2017
*/
@Test
public void testSingleMultistatePointNoCacheNoChangeInitialValue() {
// Setup the data to run once daily for 30 days
ZonedDateTime from = ZonedDateTime.of(2017, 1, 1, 0, 0, 0, 0, zoneId);
ZonedDateTime to = ZonedDateTime.of(2017, 2, 1, 0, 0, 0, 0, zoneId);
Duration adjuster = Duration.ofDays(1);
MockDataSourceVO ds = createDataSource();
DataPointVO dp = createDataPoint(ds.getId(), DataType.MULTISTATE, 1);
DataPointWrapper<StartsAndRuntimeList> point = new DataPointWrapper<>(ds, dp, new PointValueTime(1, 0), // no change
Function.identity(), (w) -> new StartsAndRuntimeList(from.toInstant().toEpochMilli(), to.toInstant().toEpochMilli(), w.initialValue, w.values), new StartsAndRuntimeListVerifier());
// Insert the data skipping first day so we get the initial value
ZonedDateTime time = from.plus(adjuster);
timer.setStartTime(time.toInstant().toEpochMilli());
while (time.toInstant().isBefore(to.toInstant())) {
point.updatePointValue(new PointValueTime(point.getNextValue(), time.toInstant().toEpochMilli()));
time = time.plus(adjuster);
timer.fastForwardTo(time.toInstant().toEpochMilli());
}
// Perform the query
String timezone = zoneId.getId();
PointValueField[] fields = getFields();
var result = getStatistics(List.of(dp), from, to, timezone, fields);
test(result, point);
}
Aggregations