예제 #1
0
  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);
      }
    }
  }
예제 #2
0
  //
  //
  // 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);
  }
예제 #3
0
  @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);
  }
예제 #4
0
  @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;
  }
예제 #5
0
  @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);
    }
  }
예제 #6
0
  //
  //
  // 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();
  }
예제 #7
0
    @Override
    public void execute() {
      if (backdate) listener.pointBackdated(newValue);
      else {
        // Always fire this.
        listener.pointUpdated(newValue);

        // Fire if the point has changed.
        if (!PointValueTime.equalValues(oldValue, newValue))
          listener.pointChanged(oldValue, newValue);

        // Fire if the point was set.
        if (set) listener.pointSet(oldValue, newValue);
      }
    }
예제 #8
0
  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);
  }
예제 #9
0
 public static DataValue getValue(PointValueTime pvt) {
   if (pvt == null) return null;
   return pvt.getValue();
 }
예제 #10
0
 public static boolean equalValues(PointValueTime pvt1, PointValueTime pvt2) {
   if (pvt1 == null && pvt2 == null) return true;
   if (pvt1 == null || pvt2 == null) return false;
   return ObjectUtils.equals(pvt1.getValue(), pvt2.getValue());
 }