//****************************************************************************************************** // TemporalMeasurement.cs - Gbtc // // Copyright © 2010, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/eclipse-1.0.php // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 09/02/2010 - J. Ritchie Carroll // Generated original version of source code. // //****************************************************************************************************** using System; namespace GSF.TimeSeries { /// /// Represents a time constrained measured value. /// public class TemporalMeasurement : Measurement { #region [ Members ] // Fields private double m_lagTime; // Allowed past time deviation tolerance private double m_leadTime; // Allowed future time deviation tolerance #endregion #region [ Constructors ] /// /// Constructs a new given the specified parameters. /// /// Past time deviation tolerance, in seconds - this becomes the amount of time to wait before publishing begins. /// Future time deviation tolerance, in seconds - this becomes the tolerated +/- accuracy of the local clock to real-time. public TemporalMeasurement(double lagTime, double leadTime) : this(null, lagTime, leadTime) { } /// /// Constructs a new given the specified parameters. /// /// Source value. /// Past time deviation tolerance, in seconds - this becomes the amount of time to wait before publishing begins. /// Future time deviation tolerance, in seconds - this becomes the tolerated +/- accuracy of the local clock to real-time. public TemporalMeasurement(IMeasurement measurement, double lagTime, double leadTime) { if (measurement != null) { ID = measurement.ID; Key = measurement.Key; Value = measurement.Value; Adder = measurement.Adder; Multiplier = measurement.Multiplier; Timestamp = measurement.Timestamp; StateFlags = measurement.StateFlags; } if (lagTime <= 0) throw new ArgumentOutOfRangeException("lagTime", "lagTime must be greater than zero, but it can be less than one"); if (leadTime <= 0) throw new ArgumentOutOfRangeException("leadTime", "leadTime must be greater than zero, but it can be less than one"); m_lagTime = lagTime; m_leadTime = leadTime; } #endregion #region [ Properties ] /// Allowed past time deviation tolerance in seconds (can be subsecond). /// /// This value defines the time sensitivity to past measurement timestamps. /// Defined the number of seconds allowed before assuming a measurement timestamp is too old. /// /// LagTime must be greater than zero, but it can be less than one. public double LagTime { get { return m_lagTime; } set { if (value <= 0) throw new ArgumentOutOfRangeException("value", "LagTime must be greater than zero, but it can be less than one"); m_lagTime = value; } } /// Allowed future time deviation tolerance in seconds (can be subsecond). /// /// This value defines the time sensitivity to future measurement timestamps. /// Defined the number of seconds allowed before assuming a measurement timestamp is too advanced. /// /// LeadTime must be greater than zero, but it can be less than one. public double LeadTime { get { return m_leadTime; } set { if (value <= 0) throw new ArgumentOutOfRangeException("value", "LeadTime must be greater than zero, but it can be less than one"); m_leadTime = value; } } #endregion #region [ Methods ] /// Gets numeric adjusted value of this , constrained within specified ticks. /// /// Operation will return NaN if ticks are outside of time deviation tolerances. /// Note that returned value will be offset by adder and multiplier. /// /// Timestamp used to constrain (typically set to real-time, i.e. "now"). /// Value offset by adder and multipler (i.e., Value * Multiplier + Adder). public double GetAdjustedValue(Ticks timestamp) { // We only return a measurement value that is up-to-date... return Timestamp.TimeIsValid(timestamp, m_lagTime, m_leadTime) ? base.AdjustedValue : double.NaN; } /// Gets numeric value of this , constrained within specified ticks. /// /// Operation will return NaN if ticks are outside of time deviation tolerances. /// /// Timestamp, in ticks, used to constrain (typically set to real-time, i.e. "now"). /// Raw value of this measurement (i.e., value that is not offset by adder and multiplier). public double GetValue(Ticks timestamp) { // We only return a measurement value that is up-to-date... return Timestamp.TimeIsValid(timestamp, m_lagTime, m_leadTime) ? base.Value : double.NaN; } /// Sets numeric value and timestamp, as ticks, of this . /// /// Operation will only store a value that is newer than the cached value. /// /// New timestamp, in ticks, for . /// New value for , only stored if are newer than current . /// true if value was updated; otherwise false. public bool SetValue(Ticks timestamp, double value) { // We only store a value that is is newer than the current value if (timestamp > Timestamp) { base.Value = value; Timestamp = timestamp; return true; } return false; } #endregion } }