// // / Interval logging // private void initializeIntervalLogging() { synchronized (intervalLoggingLock) { if (vo.getLoggingType() != DataPointVO.LoggingTypes.INTERVAL) return; // Are we using a custom timer? if (this.timer == null) intervalLoggingTask = new TimeoutTask( new FixedRateTrigger( 0, Common.getMillis( vo.getIntervalLoggingPeriodType(), vo.getIntervalLoggingPeriod())), this); else intervalLoggingTask = new TimeoutTask( new FixedRateTrigger( 0, Common.getMillis( vo.getIntervalLoggingPeriodType(), vo.getIntervalLoggingPeriod())), this, this.timer); intervalValue = pointValue; if (vo.getIntervalLoggingType() == DataPointVO.IntervalLoggingTypes.AVERAGE) { intervalStartTime = System.currentTimeMillis(); averagingValues = new ArrayList<IValueTime>(); } } }
private void updatePoints() { // Get the points List<DataPointVO> dps = query( "select dp.id, dp.xid, dp.dataSourceId, dp.data, ds.name, " // + "ds.xid, ds.dataSourceType " // + "from dataPoints dp join dataSources ds on ds.id = dp.dataSourceId ", new DataPointRowMapper()); // Resave for (DataPointVO dp : dps) ejt.update( "update dataPoints set xid=?, name=?, deviceName=?, enabled=?, loggingType=?, " // + "intervalLoggingPeriodType=?, intervalLoggingPeriod=?, intervalLoggingType=?, " // + "tolerance=?, purgeType=?, purgePeriod=?, defaultCacheSize=?, discardExtremeValues=?, " // + "engineeringUnits=?, data=? where id=?", // new Object[] { dp.getXid(), dp.getName(), dp.getDeviceName(), boolToChar(dp.isEnabled()), dp.getLoggingType(), dp.getIntervalLoggingPeriodType(), dp.getIntervalLoggingPeriod(), dp.getIntervalLoggingType(), dp.getTolerance(), dp.getPurgeType(), dp.getPurgePeriod(), dp.getDefaultCacheSize(), boolToChar(dp.isDiscardExtremeValues()), dp.getEngineeringUnits(), SerializationHelper.writeObject(dp), dp.getId() }, // new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.CHAR, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.DOUBLE, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.CHAR, Types.INTEGER, Types.BLOB, Types.INTEGER }); }
// // / Purging // public void resetValues() { valueCache.reset(); if (vo.getLoggingType() != DataPointVO.LoggingTypes.NONE) pointValue = valueCache.getLatestPointValue(); }
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()) // This should never happen, but if it does it can have serious downstream consequences. Also, // we need // 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(); if (newd < vo.getDiscardLowLimit() || newd > vo.getDiscardHighLimit()) // Discard the value return; } if (newValue.getTime() > System.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.getStringValue() + ", 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: 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 logValue = !ObjectUtils.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); // add annotation to newValue before firing events so event detectors can // 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, source != null, false); } else fireEvents(null, newValue, false, true); }