// Static Constructor static MeasurementKey() { // Order of operations is critical here since MeasurementKey and MeasurementMetadata have a circular reference Undefined = CreateUndefinedMeasurementKey(); MeasurementMetadata.CreateUndefinedMeasurementMetadata(); Undefined.m_metadata = MeasurementMetadata.Undefined; }
private MeasurementKey(Guid signalID, ulong id, string source) { m_signalID = signalID; m_id = id; m_source = source; m_hashCode = base.GetHashCode(); m_runtimeID = Interlocked.Increment(ref s_nextRuntimeID) - 1; // Returns the incremented value. Hints the -1 m_metadata = new MeasurementMetadata(this, null, 0, 1, null); }
private MeasurementKey(Guid signalID, uint id, string source) { m_signalID = signalID; m_id = id; m_source = source; m_hashCode = base.GetHashCode(); m_runtimeID = Interlocked.Increment(ref s_nextRuntimeID) - 1; // Returns the incremented value. Hints the -1 m_metadata = new MeasurementMetadata(this, null, 0, 1, null); }
/// <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> /// Map parsed measurement value to defined measurement attributes (i.e., assign meta-data to parsed measured value). /// </summary> /// <param name="mappedMeasurements">Destination collection for the mapped measurement values.</param> /// <param name="metadata">The metadata to assign</param> /// <param name="parsedMeasurement">The parsed <see cref="IMeasurement"/> value.</param> protected void MapMeasurementAttributes(List<IMeasurement> mappedMeasurements, MeasurementMetadata metadata, IMeasurement parsedMeasurement) { if ((object)metadata == null) return; // Assign ID and other relevant attributes to the parsed measurement value parsedMeasurement.Metadata = metadata; // Add the updated measurement value to the destination measurement collection mappedMeasurements.Add(parsedMeasurement); }
/// <summary> /// Get <see cref="MeasurementMetadata"/> for specified <see cref="SignalKind"/>. /// </summary> /// <param name="lookup">A lookup table by signal reference.</param> /// <param name="type"><see cref="SignalKind"/> to request signal reference for.</param> /// <param name="index">Index <see cref="SignalKind"/> to request signal reference for.</param> /// <param name="count">Number of signals defined for this <see cref="SignalKind"/>.</param> /// <returns>The MeasurementMetadata for a given <see cref="SignalKind"/>. Null if it does not exist.</returns> public MeasurementMetadata GetMetadata(Dictionary<string, MeasurementMetadata> lookup, SignalKind type, int index, int count) { // Clear the cache if the lookup dictionary has changed. // Since the instance of Lookup is effectively readonly as implemented in PhasorMeasurementMapper // a simple reference check is all that is needed. If it could be modified, this would likely be a // concurrent dictionary instead. if (m_metadataLookupObject != lookup) { Array.Clear(m_generatedMeasurementMetadataCache, 0, m_generatedMeasurementMetadataCache.Length); m_metadataLookupObject = lookup; } // Gets the cache for the supplied SignalKind int typeIndex = (int)type; MeasurementMetadata[] metadataArray = m_generatedMeasurementMetadataCache[typeIndex]; // If this SignalKind is null, create the sub array and generate all item lookups, also, rebuild // if the count is not the same. This could be because a new config frame was received. if ((object)metadataArray == null || metadataArray.Length != count) { metadataArray = new MeasurementMetadata[count]; m_generatedMeasurementMetadataCache[typeIndex] = metadataArray; for (int x = 0; x < count; x++) { string signalReference = GetSignalReference(type, x, count); MeasurementMetadata metadata; if (lookup.TryGetValue(signalReference, out metadata)) metadataArray[x] = metadata; } } return metadataArray[index]; }
/// <summary> /// Get <see cref="MeasurementMetadata"/> for specified <see cref="SignalKind"/>. /// </summary> /// <param name="lookup">A lookup table by signal reference.</param> /// <param name="type"><see cref="SignalKind"/> to request signal reference for.</param> /// <returns>The <see cref="MeasurementMetadata"/> for a given <see cref="SignalKind"/>; otherwise <c>null</c> if value does not exist.</returns> public MeasurementMetadata GetMetadata(Dictionary<string, MeasurementMetadata> lookup, SignalKind type) { // Clear the cache if the lookup dictionary has changed. // Since the instance of Lookup is effectively readonly as implemented in PhasorMeasurementMapper // a simple reference check is all that is needed. If it could be modified, this would likely be a // concurrent dictionary instead. if (m_metadataLookupObject != lookup) { Array.Clear(m_generatedMeasurementMetadataCache, 0, m_generatedMeasurementMetadataCache.Length); m_metadataLookupObject = lookup; } // Gets the cache for the supplied SignalKind int typeIndex = (int)type; MeasurementMetadata[] metadataArray = m_generatedMeasurementMetadataCache[typeIndex]; // If this SignalKind is null, create the sub array and generate all item lookups if ((object)metadataArray == null) { metadataArray = new MeasurementMetadata[1]; m_generatedMeasurementMetadataCache[typeIndex] = metadataArray; string signalReference = GetSignalReference(type); MeasurementMetadata metadata; if (lookup.TryGetValue(signalReference, out metadata)) metadataArray[0] = metadata; } return metadataArray[0]; }
/// <summary> /// Constructs a new <see cref="Measurement"/> using default settings. /// </summary> public Measurement() { m_metadata = MeasurementMetadata.Undefined; m_lifespan = ShortTime.Now; }
// Static Methods // Create measurement metadata for undefined internal static void CreateUndefinedMeasurementMetadata() { s_undefined = s_undefined ?? new MeasurementMetadata(MeasurementKey.Undefined, null, 0, 1, null); }
/// <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); }