use of com.serotonin.m2m2.rt.dataImage.SetPointSource in project ma-core-public by infiniteautomation.
the class PointValueDaoSQL method updatePointValueSync.
/**
* Only the PointValueCache should call this method during runtime. Do not use.
*/
@Override
public PointValueTime updatePointValueSync(int dataPointId, PointValueTime pvt, SetPointSource source) {
long id = updatePointValueImpl(dataPointId, pvt, source, false);
PointValueTime savedPointValue;
int retries = 5;
while (true) {
try {
savedPointValue = getPointValue(id);
break;
} catch (ConcurrencyFailureException e) {
if (retries <= 0)
throw e;
retries--;
}
}
return savedPointValue;
}
use of com.serotonin.m2m2.rt.dataImage.SetPointSource 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.SetPointSource in project ma-modules-public by infiniteautomation.
the class PointValueRestController method setPointValue.
/**
* Helper method for setting a point value
*
* @param xid
* @param data
* @param unitConversion
* @return
*/
private RestProcessResult<PointValueTimeModel> setPointValue(User user, String xid, PointValueTimeModel model, boolean unitConversion, UriComponentsBuilder builder) {
RestProcessResult<PointValueTimeModel> result = new RestProcessResult<PointValueTimeModel>(HttpStatus.OK);
DataPointVO existingDp = DataPointDao.instance.getByXid(xid);
if (existingDp == null) {
result.addRestMessage(getDoesNotExistMessage());
return result;
}
try {
if (Permissions.hasDataPointSetPermission(user, existingDp)) {
// Set the time to now if it is not present
if (model.getTimestamp() == 0) {
model.setTimestamp(Common.timer.currentTimeMillis());
}
// Validate the model's data type for compatibility
if (DataTypeEnum.convertFrom(model.getType()) != existingDp.getPointLocator().getDataTypeId()) {
result.addRestMessage(HttpStatus.NOT_ACCEPTABLE, new TranslatableMessage("event.ds.dataType"));
return result;
}
// Validate the timestamp for future dated
if (model.getTimestamp() > Common.timer.currentTimeMillis() + SystemSettingsDao.getFutureDateLimit()) {
result.addRestMessage(HttpStatus.NOT_ACCEPTABLE, new TranslatableMessage("common.default", "Future dated points not acceptable."));
return result;
}
// Are we converting from the rendered Unit?
if (unitConversion) {
if ((model.getType() == DataTypeEnum.NUMERIC) && (model.getValue() instanceof Number)) {
double value;
if (model.getValue() instanceof Integer) {
value = (double) ((Integer) model.getValue());
} else {
value = (double) ((Double) model.getValue());
}
model.setValue(existingDp.getRenderedUnit().getConverterTo(existingDp.getUnit()).convert(value));
} else {
result.addRestMessage(HttpStatus.NOT_ACCEPTABLE, new TranslatableMessage("common.default", "[" + xid + "]Cannot perform unit conversion on Non Numeric data types."));
return result;
}
}
// to convert it
if ((model.getType() == DataTypeEnum.MULTISTATE) && (model.getValue() instanceof String)) {
try {
DataValue value = existingDp.getTextRenderer().parseText((String) model.getValue(), existingDp.getPointLocator().getDataTypeId());
model.setValue(value.getObjectValue());
} catch (Exception e) {
// Lots can go wrong here so let the user know
result.addRestMessage(HttpStatus.NOT_ACCEPTABLE, new TranslatableMessage("common.default", "[" + xid + "]Unable to convert Multistate String representation to any known value."));
}
}
final PointValueTime pvt;
try {
pvt = model.getData();
} catch (Exception e) {
result.addRestMessage(HttpStatus.NOT_ACCEPTABLE, new TranslatableMessage("common.default", "[" + xid + "]Invalid Format"));
return result;
}
// one last check to ensure we are inserting the correct data type
if (DataTypes.getDataType(pvt.getValue()) != existingDp.getPointLocator().getDataTypeId()) {
result.addRestMessage(HttpStatus.NOT_ACCEPTABLE, new TranslatableMessage("event.ds.dataType"));
return result;
}
final int dataSourceId = existingDp.getDataSourceId();
SetPointSource source = null;
if (model.getAnnotation() != null) {
source = new SetPointSource() {
@Override
public String getSetPointSourceType() {
return "REST";
}
@Override
public int getSetPointSourceId() {
return dataSourceId;
}
@Override
public TranslatableMessage getSetPointSourceMessage() {
return ((AnnotatedPointValueTime) pvt).getSourceMessage();
}
@Override
public void raiseRecursionFailureEvent() {
LOG.error("Recursive failure while setting point via REST");
}
};
}
try {
Common.runtimeManager.setDataPointValue(existingDp.getId(), pvt, source);
// This URI may not always be accurate if the Data Source doesn't use the
// provided time...
URI location = builder.path("/v1/point-values/{xid}/{time}").buildAndExpand(xid, pvt.getTime()).toUri();
result.addRestMessage(getResourceCreatedMessage(location));
return result;
} catch (RTException e) {
// Ok its probably not enabled or settable
result.addRestMessage(new RestMessage(HttpStatus.NOT_ACCEPTABLE, new TranslatableMessage("common.default", "[" + xid + "]" + e.getMessage())));
return result;
} catch (Exception e) {
LOG.error(e.getMessage(), e);
result.addRestMessage(getInternalServerErrorMessage(e.getMessage()));
return result;
}
} else {
result.addRestMessage(getUnauthorizedMessage());
return result;
}
} catch (PermissionException e) {
LOG.error(e.getMessage(), e);
result.addRestMessage(getUnauthorizedMessage());
return result;
}
}
use of com.serotonin.m2m2.rt.dataImage.SetPointSource in project ma-modules-public by infiniteautomation.
the class SerialDataSourceRT method setPointValueImpl.
@Override
public void setPointValueImpl(DataPointRT dataPoint, PointValueTime valueTime, SetPointSource source) {
// Are we connected?
if (this.port == null && !connect()) {
raiseEvent(POINT_WRITE_EXCEPTION_EVENT, Common.timer.currentTimeMillis(), true, new TranslatableMessage("event.serial.writeFailedPortNotSetup"));
return;
}
try {
setPointValueImplTransport(dataPoint, valueTime);
returnToNormal(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis());
} catch (IOException e) {
if (vo.getRetries() == 0)
LOG.error("Failed setting serial point " + dataPoint.getVO().getExtendedName() + ": " + e.getMessage(), e);
// Try and reset the connection
Exception ex = e;
int retries = vo.getRetries();
while (retries > 0) {
try {
retries -= 1;
if (this.port != null)
Common.serialPortManager.close(this.port);
if (this.connect()) {
setPointValueImplTransport(dataPoint, valueTime);
returnToNormal(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis());
return;
}
} catch (Exception e2) {
ex = e2;
}
}
if (ex != null) {
raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new TranslatableMessage("event.serial.writeFailed", e.getMessage()));
LOG.error("Error re-connecting to serial port.", ex);
}
}
}
use of com.serotonin.m2m2.rt.dataImage.SetPointSource in project ma-core-public by infiniteautomation.
the class RuntimeManagerImpl method setDataPointValue.
/* (non-Javadoc)
* @see com.serotonin.m2m2.rt.RuntimeManager#setDataPointValue(int, com.serotonin.m2m2.rt.dataImage.PointValueTime, com.serotonin.m2m2.rt.dataImage.SetPointSource)
*/
@Override
public void setDataPointValue(int dataPointId, PointValueTime valueTime, SetPointSource source) {
DataPointRT dataPoint = dataPoints.get(dataPointId);
if (dataPoint == null)
throw new RTException("Point is not enabled");
if (!dataPoint.getPointLocator().isSettable())
throw new RTException("Point is not settable");
// Tell the data source to set the value of the point.
DataSourceRT<? extends DataSourceVO<?>> ds = getRunningDataSource(dataPoint.getDataSourceId());
// The data source may have been disabled. Just make sure.
if (ds != null)
ds.setPointValue(dataPoint, valueTime, source);
}
Aggregations