use of com.serotonin.m2m2.rt.dataImage.types.ImageValue in project ma-core-public by infiniteautomation.
the class PointValueDaoSQL method updatePointValueImpl.
long updatePointValueImpl(final int pointId, final PointValueTime pvt, final SetPointSource source, boolean async) {
DataValue value = pvt.getValue();
final int dataType = DataTypes.getDataType(value);
double dvalue = 0;
String svalue = null;
if (dataType == DataTypes.IMAGE) {
ImageValue imageValue = (ImageValue) value;
dvalue = imageValue.getType();
if (imageValue.isSaved())
svalue = Long.toString(imageValue.getId());
} else if (value.hasDoubleRepresentation())
dvalue = value.getDoubleValue();
else
svalue = value.getStringValue();
// Check if we need to create an annotation.
long id;
try {
if (svalue != null || source != null || dataType == DataTypes.IMAGE)
async = false;
id = updatePointValue(pointId, dataType, dvalue, pvt.getTime(), svalue, source, async);
} catch (ConcurrencyFailureException e) {
// Still failed to insert after all of the retries. Store the data
synchronized (UNSAVED_POINT_UPDATES) {
UNSAVED_POINT_UPDATES.add(new UnsavedPointUpdate(pointId, pvt, source));
}
return -1;
}
// Check if we need to save an image
if (dataType == DataTypes.IMAGE) {
ImageValue imageValue = (ImageValue) value;
if (!imageValue.isSaved()) {
imageValue.setId(id);
File file = new File(Common.getFiledataPath(), imageValue.getFilename());
// Write the file.
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
StreamUtils.transfer(new ByteArrayInputStream(imageValue.getData()), out);
} catch (IOException e) {
// Rethrow as an RTE
throw new ImageSaveException(e);
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
// no op
}
}
// Allow the data to be GC'ed
imageValue.setData(null);
}
}
clearUnsavedPointUpdates();
return id;
}
use of com.serotonin.m2m2.rt.dataImage.types.ImageValue in project ma-core-public by infiniteautomation.
the class DataPointRT method savePointValue.
private void savePointValue(PointValueTime newValue, SetPointSource source, boolean async, boolean saveToDatabase) {
// Null values are not very nice, and since they don't have a specific meaning they are hereby ignored.
if (newValue == null)
return;
// Check the data type of the value against that of the locator, just for fun.
int valueDataType = DataTypes.getDataType(newValue.getValue());
if (valueDataType != DataTypes.UNKNOWN && valueDataType != vo.getPointLocator().getDataTypeId())
// to know how it happened, and the stack trace here provides the best information.
throw new ShouldNeverHappenException("Data type mismatch between new value and point locator: newValue=" + DataTypes.getDataType(newValue.getValue()) + ", locator=" + vo.getPointLocator().getDataTypeId());
// Check if this value qualifies for discardation.
if (vo.isDiscardExtremeValues() && DataTypes.getDataType(newValue.getValue()) == DataTypes.NUMERIC) {
double newd = newValue.getDoubleValue();
// Discard if NaN
if (Double.isNaN(newd))
return;
if (newd < vo.getDiscardLowLimit() || newd > vo.getDiscardHighLimit())
// Discard the value
return;
}
if (newValue.getTime() > Common.timer.currentTimeMillis() + SystemSettingsDao.getFutureDateLimit()) {
// Too far future dated. Toss it. But log a message first.
LOG.warn("Future dated value detected: pointId=" + vo.getId() + ", value=" + newValue.getValue().toString() + ", type=" + vo.getPointLocator().getDataTypeId() + ", ts=" + newValue.getTime(), new Exception());
return;
}
boolean backdated = pointValue != null && newValue.getTime() < pointValue.getTime();
// Determine whether the new value qualifies for logging.
boolean logValue;
// ... or even saving in the cache.
boolean saveValue = true;
switch(vo.getLoggingType()) {
case DataPointVO.LoggingTypes.ON_CHANGE_INTERVAL:
case DataPointVO.LoggingTypes.ON_CHANGE:
if (pointValue == null)
logValue = true;
else if (backdated)
// Backdated. Ignore it
logValue = false;
else {
if (newValue.getValue() instanceof NumericValue) {
// Get the new double
double newd = newValue.getDoubleValue();
// See if the new value is outside of the tolerance.
double diff = toleranceOrigin - newd;
if (diff < 0)
diff = -diff;
if (diff > vo.getTolerance()) {
toleranceOrigin = newd;
logValue = true;
} else
logValue = false;
} else if (newValue.getValue() instanceof ImageValue) {
logValue = !((ImageValue) newValue.getValue()).equalDigests(((ImageValue) pointValue.getValue()).getDigest());
} else
logValue = !Objects.equals(newValue.getValue(), pointValue.getValue());
}
saveValue = logValue;
break;
case DataPointVO.LoggingTypes.ALL:
logValue = true;
break;
case DataPointVO.LoggingTypes.ON_TS_CHANGE:
if (pointValue == null)
logValue = true;
else if (backdated)
// Backdated. Ignore it
logValue = false;
else
logValue = newValue.getTime() != pointValue.getTime();
saveValue = logValue;
break;
case DataPointVO.LoggingTypes.INTERVAL:
if (!backdated)
intervalSave(newValue);
default:
logValue = false;
}
if (!saveToDatabase)
logValue = false;
if (saveValue) {
valueCache.savePointValue(newValue, source, logValue, async);
if (vo.getLoggingType() == DataPointVO.LoggingTypes.ON_CHANGE_INTERVAL)
rescheduleChangeInterval(Common.getMillis(vo.getIntervalLoggingPeriodType(), vo.getIntervalLoggingPeriod()));
}
// fetch the annotation
if (source != null) {
newValue = new AnnotatedPointValueTime(newValue.getValue(), newValue.getTime(), source.getSetPointSourceMessage());
}
// Ignore historical values.
if (pointValue == null || newValue.getTime() >= pointValue.getTime()) {
PointValueTime oldValue = pointValue;
pointValue = newValue;
fireEvents(oldValue, newValue, null, source != null, false, logValue, true, false);
} else
fireEvents(null, newValue, null, false, true, logValue, false, false);
}
use of com.serotonin.m2m2.rt.dataImage.types.ImageValue in project ma-modules-public by infiniteautomation.
the class SimpleImageComponent method addDataToModel.
@Override
public void addDataToModel(Map<String, Object> model, PointValueTime pointValue) {
if (pointValue == null || pointValue.getValue() == null) {
model.put("error", "common.noData");
return;
}
if (!(pointValue.getValue() instanceof ImageValue)) {
model.put("error", "common.thumb.invalidValue");
return;
}
ImageValue imageValue = (ImageValue) pointValue.getValue();
model.put("imageType", imageValue.getTypeExtension());
}
use of com.serotonin.m2m2.rt.dataImage.types.ImageValue in project ma-modules-public by infiniteautomation.
the class ThumbnailComponent method addDataToModel.
@Override
public void addDataToModel(Map<String, Object> model, PointValueTime pointValue) {
if (pointValue == null || pointValue.getValue() == null) {
model.put("error", "common.noData");
return;
}
if (!(pointValue.getValue() instanceof ImageValue)) {
model.put("error", "common.thumb.invalidValue");
return;
}
ImageValue imageValue = (ImageValue) pointValue.getValue();
model.put("imageType", imageValue.getTypeExtension());
model.put("scalePercent", scalePercent);
}
use of com.serotonin.m2m2.rt.dataImage.types.ImageValue in project ma-modules-public by infiniteautomation.
the class PointValueRestController method firstAndLastPointValues.
@ApiOperation(value = "First and last point values", notes = "Retrieves the first and last point values within a time range, used to read accumulators")
@RequestMapping(method = RequestMethod.GET, value = "/{xid}/first-last", produces = { "application/json", "text/csv" })
public ResponseEntity<List<PointValueTimeModel>> firstAndLastPointValues(HttpServletRequest request, @ApiParam(value = "Point xid", required = true, allowMultiple = false) @PathVariable String xid, @ApiParam(value = "Return rendered value as String", required = false, defaultValue = "false", allowMultiple = false) @RequestParam(required = false, defaultValue = "false") boolean useRendered, @ApiParam(value = "Return converted value using displayed unit", required = false, defaultValue = "false", allowMultiple = false) @RequestParam(required = false, defaultValue = "false") boolean unitConversion, @ApiParam(value = "From time", required = false, allowMultiple = false) @RequestParam(value = "from", required = false) @DateTimeFormat(iso = ISO.DATE_TIME) DateTime from, @ApiParam(value = "To time", required = false, allowMultiple = false) @RequestParam(value = "to", required = false) @DateTimeFormat(iso = ISO.DATE_TIME) DateTime to, @ApiParam(value = "Time zone of output, used if formatted times are returned", required = false, allowMultiple = false) @RequestParam(value = "timezone", required = false) String timezone) {
RestProcessResult<List<PointValueTimeModel>> result = new RestProcessResult<List<PointValueTimeModel>>(HttpStatus.OK);
User user = this.checkUser(request, result);
if (result.isOk()) {
if (timezone != null) {
try {
ZoneId.of(timezone);
} catch (Exception e) {
RestValidationResult vr = new RestValidationResult();
vr.addError("validate.invalidValue", "timezone");
throw new ValidationFailedRestException(vr);
}
}
DataPointVO vo = DataPointDao.instance.getByXid(xid);
if (vo == null) {
result.addRestMessage(getDoesNotExistMessage());
return result.createResponseEntity();
}
try {
if (Permissions.hasDataPointReadPermission(user, vo)) {
long current = Common.timer.currentTimeMillis();
if (from == null)
from = new DateTime(current);
if (to == null)
to = new DateTime(current);
// better not to for RESTfulness
if (timezone != null) {
DateTimeZone zone = DateTimeZone.forID(timezone);
from = from.withZone(zone);
to = to.withZone(zone);
}
PointValueFacade pointValueFacade = new PointValueFacade(vo.getId(), false);
PointValueTime first = pointValueFacade.getPointValueAfter(from.getMillis());
PointValueTime last = pointValueFacade.getPointValueBefore(to.getMillis());
List<PointValueTimeModel> models = new ArrayList<PointValueTimeModel>(2);
if (useRendered) {
if (first != null) {
PointValueTimeModel model = new PointValueTimeModel();
model.setType(DataTypeEnum.convertTo(first.getValue().getDataType()));
model.setValue(Functions.getRenderedText(vo, first));
model.setTimestamp(first.getTime());
if (first.isAnnotated())
model.setAnnotation(((AnnotatedPointValueTime) first).getAnnotation(Common.getTranslations()));
models.add(model);
}
if (last != null) {
PointValueTimeModel model = new PointValueTimeModel();
model.setType(DataTypeEnum.convertTo(last.getValue().getDataType()));
model.setValue(Functions.getRenderedText(vo, last));
model.setTimestamp(last.getTime());
if (last.isAnnotated())
model.setAnnotation(((AnnotatedPointValueTime) last).getAnnotation(Common.getTranslations()));
models.add(model);
}
} else if (unitConversion) {
if (first != null) {
PointValueTimeModel model = new PointValueTimeModel();
model.setType(DataTypeEnum.convertTo(first.getValue().getDataType()));
model.setValue(vo.getUnit().getConverterTo(vo.getRenderedUnit()).convert(first.getValue().getDoubleValue()));
model.setTimestamp(first.getTime());
if (first.isAnnotated())
model.setAnnotation(((AnnotatedPointValueTime) first).getAnnotation(Common.getTranslations()));
models.add(model);
}
if (last != null) {
PointValueTimeModel model = new PointValueTimeModel();
model.setType(DataTypeEnum.convertTo(last.getValue().getDataType()));
model.setValue(vo.getUnit().getConverterTo(vo.getRenderedUnit()).convert(last.getValue().getDoubleValue()));
model.setTimestamp(last.getTime());
if (last.isAnnotated())
model.setAnnotation(((AnnotatedPointValueTime) last).getAnnotation(Common.getTranslations()));
models.add(model);
}
} else {
models.add(first == null ? null : new PointValueTimeModel(first));
models.add(last == null ? null : new PointValueTimeModel(last));
}
if (vo.getPointLocator().getDataTypeId() == DataTypes.IMAGE) {
// If we are an image type we should build the URLS
UriComponentsBuilder imageServletBuilder = UriComponentsBuilder.fromPath("/imageValue/hst{ts}_{id}.jpg");
for (PointValueTimeModel model : models) {
model.setValue(imageServletBuilder.buildAndExpand(model.getTimestamp(), vo.getId()).toUri());
}
}
return result.createResponseEntity(models);
} else {
result.addRestMessage(getUnauthorizedMessage());
return result.createResponseEntity();
}
} catch (PermissionException e) {
LOG.error(e.getMessage(), e);
result.addRestMessage(getUnauthorizedMessage());
return result.createResponseEntity();
}
} else {
return result.createResponseEntity();
}
}
Aggregations