public bool AddFrame(IFrame frame) { if (HasFrame(frame.GetType())) { return(false); } m_frames.Add(frame); frame.OnAttached(); return(true); }
/// <summary> /// Assign <see cref="IMeasurement"/> to its <see cref="IFrame"/>. /// </summary> /// <param name="frame"><see cref="IFrame"/> to assign <paramref name="measurement"/> to.</param> /// <param name="measurement"><see cref="IMeasurement"/> to assign to <paramref name="frame"/>.</param> /// <returns><c>true</c> if <see cref="IMeasurement"/> was successfully assigned to its <see cref="IFrame"/>.</returns> /// <remarks> /// In simple concentration scenarios all you need to do is assign a measurement to its frame based on /// time. In the case of a phasor data concentrator you need to assign a measurement to its particular /// location in its <see cref="IDataFrame"/> - so this method overrides the default behavior in order /// to accomplish this task. /// </remarks> protected override void AssignMeasurementToFrame(IFrame frame, IMeasurement measurement) { ConcurrentDictionary<MeasurementKey, IMeasurement> measurements = frame.Measurements; // Make sure the measurement is a "SignalReferenceMeasurement" (it should be) SignalReferenceMeasurement signalMeasurement = measurement as SignalReferenceMeasurement; IDataFrame dataFrame = frame as IDataFrame; if ((object)signalMeasurement != null && (object)dataFrame != null) { PhasorValueCollection phasorValues; SignalReference signal = signalMeasurement.SignalReference; IDataCell dataCell = dataFrame.Cells[signal.CellIndex]; int signalIndex = signal.Index; double signalValue = m_useAdjustedValue ? signalMeasurement.AdjustedValue : signalMeasurement.Value; // Assign measurement to its destination field in the data cell based on signal type switch (signal.Kind) { case SignalKind.Angle: // Assign "phase angle" measurement to data cell phasorValues = dataCell.PhasorValues; if (phasorValues.Count >= signalIndex) phasorValues[signalIndex - 1].Angle = Angle.FromDegrees(signalValue); break; case SignalKind.Magnitude: // Assign "phase magnitude" measurement to data cell phasorValues = dataCell.PhasorValues; if (phasorValues.Count >= signalIndex) phasorValues[signalIndex - 1].Magnitude = signalValue; break; case SignalKind.Frequency: // Assign "frequency" measurement to data cell dataCell.FrequencyValue.Frequency = signalValue; break; case SignalKind.DfDt: // Assign "dF/dt" measurement to data cell dataCell.FrequencyValue.DfDt = signalValue; break; case SignalKind.Status: // Assign "common status flags" measurement to data cell dataCell.CommonStatusFlags = unchecked((uint)signalValue); // Assign by arrival sorting flag for bad synchronization if (!dataCell.SynchronizationIsValid && AllowSortsByArrival && !IgnoreBadTimestamps) dataCell.DataSortingType = DataSortingType.ByArrival; break; case SignalKind.Digital: // Assign "digital" measurement to data cell DigitalValueCollection digitalValues = dataCell.DigitalValues; if (digitalValues.Count >= signalIndex) digitalValues[signalIndex - 1].Value = unchecked((ushort)signalValue); break; case SignalKind.Analog: // Assign "analog" measurement to data cell AnalogValueCollection analogValues = dataCell.AnalogValues; if (analogValues.Count >= signalIndex) analogValues[signalIndex - 1].Value = signalValue; break; case SignalKind.Quality: // Assign "quality flags" measurement to data frame dataFrame.QualityFlags = unchecked((uint)signalValue); break; } // So that we can accurately track the total measurements that were sorted into this frame, // we also assign measurement to frame's measurement dictionary - this is important since // in down-sampling scenarios more than one of the same measurement can be sorted into a frame // but this only needs to be counted as "one" sort so that when preemptive publishing is // enabled you can compare expected measurements to sorted measurements... measurements[measurement.Key] = measurement; return; } // This is not expected to occur - but just in case if ((object)signalMeasurement == null && (object)measurement != null) OnProcessException(new InvalidCastException(string.Format("Attempt was made to assign an invalid measurement to phasor data concentration frame, expected a \"SignalReferenceMeasurement\" but received a \"{0}\"", measurement.GetType().Name))); if ((object)dataFrame == null) OnProcessException(new InvalidCastException(string.Format("During measurement assignment, incoming frame was not a phasor data concentration frame, expected a type derived from \"IDataFrame\" but received a \"{0}\"", frame.GetType().Name))); }