/// <summary> /// Publish <see cref="IFrame"/> of time-aligned collection of <see cref="IMeasurement"/> values that arrived within the /// concentrator's defined <see cref="ConcentratorBase.LagTime"/>. /// </summary> /// <param name="frame"><see cref="IFrame"/> of measurements with the same timestamp that arrived within <see cref="ConcentratorBase.LagTime"/> that are ready for processing.</param> /// <param name="index">Index of <see cref="IFrame"/> within a second ranging from zero to <c><see cref="ConcentratorBase.FramesPerSecond"/> - 1</c>.</param> /// <remarks> /// If user implemented publication function consistently exceeds available publishing time (i.e., <c>1 / <see cref="ConcentratorBase.FramesPerSecond"/></c> seconds), /// concentration will fall behind. A small amount of this time is required by the <see cref="ConcentratorBase"/> for processing overhead, so actual total time /// available for user function process will always be slightly less than <c>1 / <see cref="ConcentratorBase.FramesPerSecond"/></c> seconds. /// </remarks> protected override void PublishFrame(TimeSeriesFramework.IFrame frame, int index) { IMeasurement measurement = null; foreach (MeasurementKey key in frame.Measurements.Keys) { measurement = frame.Measurements[key]; if (measurement.AdjustedValue < m_lowRange || measurement.AdjustedValue > m_highRange) { AddOutOfRangeMeasurement(key, measurement); } } }
/// <summary> /// Publish <see cref="IFrame"/> of time-aligned collection of <see cref="IMeasurement"/> values that arrived within the /// concentrator's defined <see cref="ConcentratorBase.LagTime"/>. /// </summary> /// <param name="frame"><see cref="IFrame"/> of measurements with the same timestamp that arrived within <see cref="ConcentratorBase.LagTime"/> that are ready for processing.</param> /// <param name="index">Index of <see cref="IFrame"/> within a second ranging from zero to <c><see cref="ConcentratorBase.FramesPerSecond"/> - 1</c>.</param> protected override void PublishFrame(TimeSeriesFramework.IFrame frame, int index) { ConcurrentDictionary<MeasurementKey, IMeasurement> measurements; IMeasurement measurement; string name; measurements = frame.Measurements; m_expressionContext.Variables.Clear(); // Set the values of variables in the expression foreach (MeasurementKey key in m_keyMapping.Keys) { name = m_keyMapping[key]; if (measurements.TryGetValue(key, out measurement)) m_expressionContext.Variables[name] = measurement.AdjustedValue; else m_expressionContext.Variables[name] = double.NaN; } // Compile the expression if it has not been compiled already if ((object)m_expression == null) m_expression = m_expressionContext.CompileDynamic(m_aliasedExpressionText); // Evaluate the expression and generate the measurement GenerateCalculatedMeasurement(m_expression.Evaluate() as IConvertible); }