private void intervalSave(PointValueTime pvt) { synchronized (intervalLoggingLock) { if (vo.getIntervalLoggingType() == DataPointVO.IntervalLoggingTypes.MAXIMUM) { if (intervalValue == null) intervalValue = pvt; else if (pvt != null) { if (intervalValue.getDoubleValue() < pvt.getDoubleValue()) intervalValue = pvt; } } else if (vo.getIntervalLoggingType() == DataPointVO.IntervalLoggingTypes.MINIMUM) { if (intervalValue == null) intervalValue = pvt; else if (pvt != null) { if (intervalValue.getDoubleValue() > pvt.getDoubleValue()) intervalValue = pvt; } } else if (vo.getIntervalLoggingType() == DataPointVO.IntervalLoggingTypes.AVERAGE) { // Using the averaging values, ensure we keep the most recent values and pop off the old // ones if (vo.isOverrideIntervalLoggingSamples()) { while (averagingValues.size() >= vo.getIntervalLoggingSampleWindowSize()) { averagingValues.remove(0); // Size -1 for the next item we are going to add } } averagingValues.add(pvt); } } }
// // // Data points // public void saveDataPoint(DataPointVO point) { stopDataPoint(point.getId()); // Since the point's data type may have changed, we must ensure that the other attrtibutes are // still ok with // it. int dataType = point.getPointLocator().getDataTypeId(); // Chart renderer if (point.getChartRenderer() != null && !point.getChartRenderer().getDef().supports(dataType)) // Return to a default renderer point.setChartRenderer(null); // Text renderer if (point.getTextRenderer() != null && !point.getTextRenderer().getDef().supports(dataType)) // Return to a default renderer point.defaultTextRenderer(); // Event detectors Iterator<PointEventDetectorVO> peds = point.getEventDetectors().iterator(); while (peds.hasNext()) { PointEventDetectorVO ped = peds.next(); if (!ped.getDef().supports(dataType)) // Remove the detector. peds.remove(); } new DataPointDao().saveDataPoint(point); if (point.isEnabled()) startDataPoint(point); }
private boolean initializeDataSource(DataSourceVO<?> vo) { synchronized (runningDataSources) { // If the data source is already running, just quit. if (isDataSourceRunning(vo.getId())) return false; // Ensure that the data source is enabled. Assert.isTrue(vo.isEnabled()); // Create and initialize the runtime version of the data source. DataSourceRT dataSource = vo.createDataSourceRT(); dataSource.initialize(); // Add it to the list of running data sources. runningDataSources.add(dataSource); // Add the enabled points to the data source. List<DataPointVO> dataSourcePoints = new DataPointDao().getDataPoints(vo.getId(), null); for (DataPointVO dataPoint : dataSourcePoints) { if (dataPoint.isEnabled()) startDataPoint(dataPoint); } LOG.info("Data source '" + vo.getName() + "' initialized"); return true; } }
@DwrPermission(user = true) public ProcessResult getHistoryTableData(int limit) { DataPointVO pointVO = Common.getUser().getEditPoint(); PointValueFacade facade = new PointValueFacade(pointVO.getId()); List<PointValueTime> rawData = facade.getLatestPointValues(limit); List<RenderedPointValueTime> renderedData = new ArrayList<RenderedPointValueTime>(rawData.size()); for (PointValueTime pvt : rawData) { RenderedPointValueTime rpvt = new RenderedPointValueTime(); rpvt.setValue(Functions.getHtmlText(pointVO, pvt)); rpvt.setTime(Functions.getTime(pvt)); if (pvt.isAnnotated()) { AnnotatedPointValueTime apvt = (AnnotatedPointValueTime) pvt; rpvt.setAnnotation(apvt.getAnnotation(getTranslations())); } renderedData.add(rpvt); } ProcessResult response = new ProcessResult(); response.addData("history", renderedData); addAsof(response); return response; }
public static PointDetailsState getPointData() { // Get the point from the user's session. It should have been set by the controller. HttpServletRequest request = WebContextFactory.get().getHttpServletRequest(); User user = Common.getUser(request); DataPointVO pointVO = user.getEditPoint(); // Create the watch list state. Map<String, Object> model = new HashMap<String, Object>(); // Get the data point status from the data image. DataPointRT pointRT = Common.runtimeManager.getDataPoint(pointVO.getId()); PointDetailsState state = new PointDetailsState(); state.setId(Integer.toString(pointVO.getId())); PointValueTime pointValue = prepareBasePointState(Integer.toString(pointVO.getId()), state, pointVO, pointRT, model); setPrettyText(request, state, pointVO, model, pointValue); setChange(pointVO, state, pointRT, request, model, user); setEvents(pointVO, user, model); setMessages(state, request, "dataPointMessages.jsp", model); return state; }
@DwrPermission(user = true) public ProcessResult getFlipbookData(int limit) { HttpServletRequest request = WebContextFactory.get().getHttpServletRequest(); DataPointVO vo = Common.getUser(request).getEditPoint(); PointValueFacade facade = new PointValueFacade(vo.getId()); List<PointValueTime> values = facade.getLatestPointValues(limit); Collections.reverse(values); List<ImageValueBean> result = new ArrayList<ImageValueBean>(); for (PointValueTime pvt : values) { ImageValue imageValue = (ImageValue) pvt.getValue(); String uri = ImageValueServlet.servletPath + ImageValueServlet.historyPrefix + pvt.getTime() + "_" + vo.getId() + "." + imageValue.getTypeExtension(); result.add(new ImageValueBean(Functions.getTime(pvt), uri)); } ProcessResult response = new ProcessResult(); response.addData("images", result); addAsof(response); return response; }
public void jsonWrite(ObjectWriter writer) throws IOException, JsonException { DataPointDao dataPointDao = new DataPointDao(); DataPointVO dp = dataPointDao.getDataPoint(dataPointId); String xid; if (dp == null) xid = null; else xid = dp.getXid(); writer.writeEntry("dataPointId", xid); }
public void jsonRead(JsonReader reader, JsonObject jsonObject) throws JsonException { DataPointDao dataPointDao = new DataPointDao(); String xid = jsonObject.getString("dataPointId"); if (xid == null) throw new TranslatableJsonException("emport.error.publishedPoint.missing", "dataPointId"); DataPointVO vo = dataPointDao.getDataPoint(xid); if (vo == null) throw new TranslatableJsonException("emport.error.missingPoint", xid); dataPointId = vo.getId(); }
@Override public void terminate() { terminateIntervalLogging(); if (detectors != null) { for (PointEventDetectorRT pedRT : detectors) { Common.runtimeManager.removeDataPointListener(vo.getId(), pedRT); pedRT.terminate(); } } Common.eventManager.cancelEventsForDataPoint(vo.getId()); }
public static void jsonWriteVarContext(ObjectWriter writer, List<IntStringPair> context) throws IOException, JsonException { DataPointDao dataPointDao = new DataPointDao(); JsonArray pointList = new JsonArray(); for (IntStringPair p : context) { DataPointVO dp = dataPointDao.getDataPoint(p.getKey()); if (dp != null) { JsonObject point = new JsonObject(); pointList.add(point); point.put("varName", new JsonString(p.getValue())); point.put("dataPointXid", new JsonString(dp.getXid())); } } writer.writeEntry("context", pointList); }
public static String contextToString(List<IntStringPair> context) { DataPointDao dataPointDao = new DataPointDao(); StringBuilder sb = new StringBuilder(); boolean first = true; for (IntStringPair ivp : context) { DataPointVO dp = dataPointDao.getDataPoint(ivp.getKey()); if (first) first = false; else sb.append(", "); if (dp == null) sb.append("?="); else sb.append(dp.getName()).append("="); sb.append(ivp.getValue()); } return sb.toString(); }
// // / // / Listeners // / // private void fireEvents( PointValueTime oldValue, PointValueTime newValue, boolean set, boolean backdate) { DataPointListener l = Common.runtimeManager.getDataPointListeners(vo.getId()); if (l != null) Common.backgroundProcessing.addWorkItem( new EventNotifyWorkItem(l, oldValue, newValue, set, backdate)); }
// // // Single value // @Override public PointValueTime getPointValueBefore(long time) { for (PointValueTime pvt : valueCache.getCacheContents()) { if (pvt.getTime() < time) return pvt; } return Common.databaseProxy.newPointValueDao().getPointValueBefore(vo.getId(), time); }
@Override public PointValueTime getPointValueAfter(long time) { List<PointValueTime> pvts = valueCache.getCacheContents(); for (int i = pvts.size() - 1; i >= 0; i--) { PointValueTime pvt = pvts.get(i); if (pvt.getTime() >= time) return pvt; } return Common.databaseProxy.newPointValueDao().getPointValueAfter(vo.getId(), time); }
@Override public void scheduleTimeout(long fireTime) { synchronized (intervalLoggingLock) { DataValue value; if (vo.getIntervalLoggingType() == DataPointVO.IntervalLoggingTypes.INSTANT) value = PointValueTime.getValue(pointValue); else if (vo.getIntervalLoggingType() == DataPointVO.IntervalLoggingTypes.MAXIMUM || vo.getIntervalLoggingType() == DataPointVO.IntervalLoggingTypes.MINIMUM) { value = PointValueTime.getValue(intervalValue); intervalValue = pointValue; } else if (vo.getIntervalLoggingType() == DataPointVO.IntervalLoggingTypes.AVERAGE) { // We won't allow logging values until we have a full average window // If we don't have enough averaging values then we will bail and wait for more if (vo.isOverrideIntervalLoggingSamples() && (averagingValues.size() != vo.getIntervalLoggingSampleWindowSize())) return; IValueTime endValue = intervalValue; if (!averagingValues.isEmpty()) endValue = averagingValues.get(averagingValues.size() - 1); AnalogStatistics stats = new AnalogStatistics( intervalStartTime, fireTime, intervalValue, averagingValues, endValue); if (stats.getAverage() == null) value = null; else value = new NumericValue(stats.getAverage()); // Compute the center point of our average data, starting by finding where our period // started long sampleWindowStartTime; if (vo.isOverrideIntervalLoggingSamples()) sampleWindowStartTime = averagingValues.get(0).getTime(); else sampleWindowStartTime = intervalStartTime; intervalStartTime = fireTime; fireTime = sampleWindowStartTime + (fireTime - sampleWindowStartTime) / 2L; // Fix to simulate center tapped filter (un-shift the average) intervalValue = pointValue; if (!vo.isOverrideIntervalLoggingSamples()) averagingValues.clear(); } else throw new ShouldNeverHappenException( "Unknown interval logging type: " + vo.getIntervalLoggingType()); if (value != null) valueCache.logPointValueAsync(new PointValueTime(value, fireTime), null); } }
// // // Lifecycle // @Override public void initialize() { // Get the latest value for the point from the database. pointValue = valueCache.getLatestPointValue(); // Set the tolerance origin if this is a numeric if (pointValue != null && pointValue.getValue() instanceof NumericValue) toleranceOrigin = pointValue.getDoubleValue(); // Add point event listeners for (PointEventDetectorVO ped : vo.getEventDetectors()) { if (detectors == null) detectors = new ArrayList<PointEventDetectorRT>(); PointEventDetectorRT pedRT = ped.createRuntime(); detectors.add(pedRT); pedRT.initialize(); Common.runtimeManager.addDataPointListener(vo.getId(), pedRT); } initializeIntervalLogging(); }
// // / 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 startDataPoint(DataPointVO vo) { synchronized (dataPoints) { Assert.isTrue(vo.isEnabled()); // Only add the data point if its data source is enabled. DataSourceRT ds = getRunningDataSource(vo.getDataSourceId()); if (ds != null) { // Change the VO into a data point implementation. DataPointRT dataPoint = new DataPointRT(vo, vo.getPointLocator().createRuntime()); // Add/update it in the data image. dataPoints.put(dataPoint.getId(), dataPoint); // Initialize it. dataPoint.initialize(); DataPointListener l = getDataPointListeners(vo.getId()); if (l != null) l.pointInitialized(); // Add/update it in the data source. ds.addDataPoint(dataPoint); } } }
@Override protected void createStateImpl( RuntimeManager rtm, HttpServletRequest request, JspComponentState state) { String value; DataPointRT dataPointRT = rtm.getDataPoint(dataPointVO.getId()); if (dataPointRT == null) value = disabledValue; else { PointValueTime pvt = dataPointRT.getPointValue(); if (pvt != null && pvt.getValue() instanceof ImageValue) { // Text renderers don't help here. Create a thumbnail. Map<String, Object> model = new HashMap<String, Object>(); model.put("point", dataPointVO); model.put("pointValue", pvt); value = BaseDwr.generateContent(request, "imageValueThumbnail.jsp", model); } else { int hint = raw ? TextRenderer.HINT_RAW : TextRenderer.HINT_FULL; value = dataPointVO.getTextRenderer().getText(pvt, hint); if (pvt != null && time) state.setTime(pvt.getTime()); } } state.setValue(value); }
@Override public List<PointValueTime> getPointValuesBetween(long from, long to) { List<PointValueTime> result = Common.databaseProxy.newPointValueDao().getPointValuesBetween(vo.getId(), from, to); for (PointValueTime pvt : valueCache.getCacheContents()) { if (pvt.getTime() >= from && pvt.getTime() < to) { int index = Collections.binarySearch(result, pvt, pvtTimeComparator); if (index < 0) result.add(-index - 1, pvt); } } return result; }
public static void jsonReadVarContext(JsonObject json, List<IntStringPair> context) throws JsonException { JsonArray jsonContext = json.getJsonArray("context"); if (jsonContext != null) { context.clear(); DataPointDao dataPointDao = new DataPointDao(); for (JsonValue jv : jsonContext) { JsonObject jo = jv.toJsonObject(); String xid = jo.getString("dataPointXid"); if (xid == null) throw new TranslatableJsonException("emport.error.meta.missing", "dataPointXid"); DataPointVO dp = dataPointDao.getDataPoint(xid); if (dp == null) throw new TranslatableJsonException("emport.error.missingPoint", xid); String var = jo.getString("varName"); if (var == null) throw new TranslatableJsonException("emport.error.meta.missing", "varName"); context.add(new IntStringPair(dp.getId(), var)); } } }
@Override public DataPointVO mapRow(ResultSet rs, int rowNum) throws SQLException { DataPointVO dp = (DataPointVO) SerializationHelper.readObjectInContext(rs.getBlob(4).getBinaryStream()); dp.setId(rs.getInt(1)); dp.setXid(rs.getString(2)); dp.setDataSourceId(rs.getInt(3)); // Data source information. dp.setDataSourceName(rs.getString(5)); dp.setDataSourceXid(rs.getString(6)); dp.setDataSourceTypeName(rs.getString(7)); return dp; }
public DataPointRT(DataPointVO vo, PointLocatorRT pointLocator) { this.vo = vo; this.pointLocator = pointLocator; valueCache = new PointValueCache(vo.getId(), vo.getDefaultCacheSize()); }
@Override public String toString() { return "DataPointRT(id=" + getId() + ", name=" + vo.getName() + ")"; }
@Override public int getDataTypeId() { return vo.getPointLocator().getDataTypeId(); }
// // / // / Properties // / // public int getId() { return vo.getId(); }
// // / Purging // public void resetValues() { valueCache.reset(); if (vo.getLoggingType() != DataPointVO.LoggingTypes.NONE) pointValue = valueCache.getLatestPointValue(); }
/** * To allow simulation of points using a timer implementation * * @param vo * @param pointLocator * @param timer */ public DataPointRT(DataPointVO vo, PointLocatorRT pointLocator, AbstractTimer timer) { this.vo = vo; this.pointLocator = pointLocator; valueCache = new PointValueCache(vo.getId(), vo.getDefaultCacheSize()); this.timer = timer; }
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); }
public int getDataSourceId() { return vo.getDataSourceId(); }