/// <summary>
 /// Creates a <see cref="MeasurementMetadata"/>
 /// </summary>
 /// <param name="key">Gets or sets the primary key of this <see cref="IMeasurement"/>.</param>
 /// <param name="tagName">Gets or sets the text based tag name of this <see cref="IMeasurement"/>.</param>
 /// <param name="adder">Defines an offset to add to the <see cref="IMeasurement"/> value.</param>
 /// <param name="multiplier">Defines a multiplicative offset to apply to the <see cref="IMeasurement"/> value.</param>
 /// <param name="measurementValueFilter">Gets or sets function used to apply a down-sampling filter over a sequence of <see cref="IMeasurement"/> values.</param>
 public MeasurementMetadata(MeasurementKey key, string tagName, double adder, double multiplier, MeasurementValueFilterFunction measurementValueFilter)
 {
     Key = key;
     TagName = tagName;
     Adder = adder;
     Multiplier = multiplier;
     MeasurementValueFilter = measurementValueFilter;
 }
Example #2
0
 /// <summary>
 /// Creates a <see cref="MeasurementMetadata"/>
 /// </summary>
 /// <param name="key">Gets or sets the primary key of this <see cref="IMeasurement"/>.</param>
 /// <param name="tagName">Gets or sets the text based tag name of this <see cref="IMeasurement"/>.</param>
 /// <param name="adder">Defines an offset to add to the <see cref="IMeasurement"/> value.</param>
 /// <param name="multiplier">Defines a multiplicative offset to apply to the <see cref="IMeasurement"/> value.</param>
 /// <param name="measurementValueFilter">Gets or sets function used to apply a down-sampling filter over a sequence of <see cref="IMeasurement"/> values.</param>
 public MeasurementMetadata(MeasurementKey key, string tagName, double adder, double multiplier, MeasurementValueFilterFunction measurementValueFilter)
 {
     Key                    = key;
     TagName                = tagName;
     Adder                  = adder;
     Multiplier             = multiplier;
     MeasurementValueFilter = measurementValueFilter;
 }
Example #3
0
        /// <summary>
        /// Updates the values of the <see cref="Metadata"/>.
        /// </summary>
        /// <param name="tagName">Gets or sets the text based tag name.</param>
        /// <param name="adder">Defines an offset to add to the <see cref="IMeasurement"/> value.</param>
        /// <param name="multiplier">Defines a multiplicative offset to apply to the <see cref="IMeasurement"/> value.</param>
        /// <param name="valueFilter">Defines the <see cref="MeasurementValueFilterFunction"/> to use when downsampling this type of <see cref="IMeasurement"/> value.</param>
        public void SetMeasurementMetadata(string tagName, double adder, double multiplier, MeasurementValueFilterFunction valueFilter)
        {
            if (this == Undefined)
            {
                throw new NotSupportedException("Cannot set data source information for an undefined measurement.");
            }

            if (m_metadata.TagName != tagName || m_metadata.Adder != adder || m_metadata.Multiplier != multiplier || m_metadata.MeasurementValueFilter != valueFilter)
            {
                m_metadata = new MeasurementMetadata(this, tagName, adder, multiplier, valueFilter);
            }
        }
 /// <summary>
 /// Creates a new instance of <see cref="MeasurementMetadata"/> using the provided <paramref name="measurementValueFilter"/>. All other fields remain the same.
 /// </summary>
 /// <param name="measurementValueFilter">the measurementValueFilter to set.</param>
 /// <returns>New instance of <see cref="MeasurementMetadata"/> using the provided <paramref name="measurementValueFilter"/>.</returns>
 public MeasurementMetadata ChangeMeasurementValueFilter(MeasurementValueFilterFunction measurementValueFilter) => ReferenceEquals(MeasurementValueFilter, measurementValueFilter) ? this : new MeasurementMetadata(Key, TagName, Adder, Multiplier, measurementValueFilter);
        /// <summary>
        /// Updates the values of the <see cref="Metadata"/>.
        /// </summary>
        /// <param name="tagName">Gets or sets the text based tag name.</param>
        /// <param name="adder">Defines an offset to add to the <see cref="IMeasurement"/> value.</param>
        /// <param name="multiplier">Defines a multiplicative offset to apply to the <see cref="IMeasurement"/> value.</param>
        /// <param name="valueFilter">Defines the <see cref="MeasurementValueFilterFunction"/> to use when downsampling this type of <see cref="IMeasurement"/> value.</param>
        public void SetMeasurementMetadata(string tagName, double adder, double multiplier, MeasurementValueFilterFunction valueFilter)
        {
            if (this == Undefined)
                throw new NotSupportedException("Cannot set data source information for an undefined measurement.");

            if (m_metadata.TagName != tagName || m_metadata.Adder != adder || m_metadata.Multiplier != multiplier || m_metadata.MeasurementValueFilter != valueFilter)
                m_metadata = new MeasurementMetadata(this, tagName, adder, multiplier, valueFilter);
        }
Example #6
0
        /// <summary>
        /// Derives measurement value, downsampling if needed.
        /// </summary>
        /// <param name="measurement">New <see cref="IMeasurement"/> value.</param>
        /// <returns>New derived <see cref="IMeasurement"/> value, or null if value should not be assigned to <see cref="IFrame"/>.</returns>
        public IMeasurement DeriveMeasurementValue(IMeasurement measurement)
        {
            IMeasurement        derivedMeasurement;
            List <IMeasurement> values;

            switch (m_downsamplingMethod)
            {
            case DownsamplingMethod.LastReceived:
                // Keep track of total number of derived measurements
                m_derivedMeasurements++;

                // This is the simplest case, just apply latest value
                return(measurement);

            case DownsamplingMethod.Closest:
                // Get tracked measurement values
                if (m_measurements.TryGetValue(measurement.Key, out values))
                {
                    if ((object)values != null && values.Count > 0)
                    {
                        // Get first tracked value (should only be one for "Closest")
                        derivedMeasurement = values[0];

                        if ((object)derivedMeasurement != null)
                        {
                            // Determine if new measurement's timestamp is closer to frame
                            if (measurement.Timestamp < derivedMeasurement.Timestamp && measurement.Timestamp >= m_timestamp)
                            {
                                // This measurement came in out-of-order and is closer to frame timestamp, so
                                // we sort this measurement instead of the original
                                values[0] = measurement;

                                // Keep track of total number of derived measurements
                                m_derivedMeasurements++;

                                return(measurement);
                            }

                            // Prior measurement is closer to frame than new one
                            return(null);
                        }
                    }
                }

                // No prior measurement exists, track this initial one
                values = new List <IMeasurement> {
                    measurement
                };
                m_measurements[measurement.Key] = values;

                // Keep track of total number of derived measurements
                m_derivedMeasurements++;

                return(measurement);

            case DownsamplingMethod.Filtered:
                // Get tracked measurement values
                if (m_measurements.TryGetValue(measurement.Key, out values))
                {
                    if ((object)values != null && values.Count > 0)
                    {
                        // Get first tracked value - we clone the measurement since we are updating its value
                        derivedMeasurement = Measurement.Clone(values[0]);

                        if ((object)derivedMeasurement != null)
                        {
                            // Get function defined for measurement value filtering
                            MeasurementValueFilterFunction measurementValueFilter = derivedMeasurement.MeasurementValueFilter;

                            // Default to average value filter if none is specified
                            if (measurementValueFilter == null)
                            {
                                measurementValueFilter = Measurement.AverageValueFilter;
                            }

                            // Add new measurement to tracking collection
                            if ((object)measurement != null)
                            {
                                values.Add(measurement);
                            }

                            // Perform filter calculation as specified by device measurement
                            if (values.Count > 1)
                            {
                                derivedMeasurement.Value = measurementValueFilter(values);

                                // Keep track of total number of derived measurements
                                m_derivedMeasurements++;

                                return(derivedMeasurement);
                            }

                            // No change from existing measurement
                            return(null);
                        }
                    }
                }

                // No prior measurement exists, track this initial one
                values = new List <IMeasurement> {
                    measurement
                };
                m_measurements[measurement.Key] = values;

                // Keep track of total number of derived measurements
                m_derivedMeasurements++;

                return(measurement);

            case DownsamplingMethod.BestQuality:
                // Get tracked measurement values
                if (m_measurements.TryGetValue(measurement.Key, out values))
                {
                    if ((object)values != null && values.Count > 0)
                    {
                        // Get first tracked value (should only be one for "BestQuality")
                        derivedMeasurement = values[0];

                        if ((object)derivedMeasurement != null)
                        {
                            // Determine if new measurement's quality is better than existing one or if new measurement's timestamp is closer to frame
                            if
                            (
                                (
                                    (!derivedMeasurement.ValueQualityIsGood() || !derivedMeasurement.TimestampQualityIsGood())
                                    &&
                                    (measurement.ValueQualityIsGood() || measurement.TimestampQualityIsGood())
                                )
                                ||
                                (
                                    measurement.Timestamp < derivedMeasurement.Timestamp && measurement.Timestamp >= m_timestamp
                                )
                            )
                            {
                                // This measurement has a better quality or came in out-of-order and is closer to frame timestamp, so
                                // we sort this measurement instead of the original
                                values[0] = measurement;

                                // Keep track of total number of derived measurements
                                m_derivedMeasurements++;

                                return(measurement);
                            }

                            // Prior measurement is closer to frame than new one
                            return(null);
                        }
                    }
                }

                // No prior measurement exists, track this initial one
                values = new List <IMeasurement> {
                    measurement
                };
                m_measurements[measurement.Key] = values;

                // Keep track of total number of derived measurements
                m_derivedMeasurements++;

                return(measurement);
            }

            return(null);
        }
Example #7
0
 /// <summary>
 /// Creates a new instance of <see cref="MeasurementMetadata"/> using the provided <paramref name="measurementValueFilter"/>. All other fields remain the same.
 /// </summary>
 /// <param name="measurementValueFilter">the measurementValueFilter to set.</param>
 /// <returns>New instance of <see cref="MeasurementMetadata"/> using the provided <paramref name="measurementValueFilter"/>.</returns>
 public MeasurementMetadata ChangeMeasurementValueFilter(MeasurementValueFilterFunction measurementValueFilter) => ReferenceEquals(MeasurementValueFilter, measurementValueFilter) ? this : new MeasurementMetadata(Key, TagName, Adder, Multiplier, measurementValueFilter);