/// <summary> /// Creates a new <see cref="CommonPhasorServices"/>. /// </summary> public CommonPhasorServices() { // Create wait handle to use to wait for configuration frame m_configurationWaitHandle = new ManualResetEvent(false); // Create a new phasor protocol frame parser used to dynamically request device configuration frames // and return them to remote clients so that the frame can be used in system setup and configuration m_frameParser = new MultiProtocolFrameParser(); // Attach to events on new frame parser reference m_frameParser.ConnectionAttempt += m_frameParser_ConnectionAttempt; m_frameParser.ConnectionEstablished += m_frameParser_ConnectionEstablished; m_frameParser.ConnectionException += m_frameParser_ConnectionException; m_frameParser.ConnectionTerminated += m_frameParser_ConnectionTerminated; m_frameParser.ExceededParsingExceptionThreshold += m_frameParser_ExceededParsingExceptionThreshold; m_frameParser.ParsingException += m_frameParser_ParsingException; m_frameParser.ReceivedConfigurationFrame += m_frameParser_ReceivedConfigurationFrame; // We only want to try to connect to device and retrieve configuration as quickly as possible m_frameParser.MaximumConnectionAttempts = 1; m_frameParser.SourceName = Name; m_frameParser.AutoRepeatCapturedPlayback = false; m_frameParser.AutoStartDataParsingSequence = false; m_frameParser.SkipDisableRealTimeData = true; }
public static void Main(string[] args) { m_definedMeasurements = new ConcurrentDictionary<string, IMeasurement>(); m_definedDevices = new ConcurrentDictionary<ushort, ConfigurationCell>(); if (WriteLogs) m_exportFile = new StreamWriter(FilePath.GetAbsolutePath("InputTimestamps.csv")); if (TestConcentrator) { // Create a new concentrator concentrator = new Concentrator(WriteLogs, FilePath.GetAbsolutePath("OutputTimestamps.csv")); concentrator.TimeResolution = 333000; concentrator.FramesPerSecond = 30; concentrator.LagTime = 3.0D; concentrator.LeadTime = 9.0D; concentrator.PerformTimestampReasonabilityCheck = false; concentrator.ProcessByReceivedTimestamp = true; concentrator.Start(); } // Create a new protocol parser parser = new MultiProtocolFrameParser(); parser.AllowedParsingExceptions = 500; parser.ParsingExceptionWindow = 5; // Attach to desired events parser.ConnectionAttempt += parser_ConnectionAttempt; parser.ConnectionEstablished += parser_ConnectionEstablished; parser.ConnectionException += parser_ConnectionException; parser.ParsingException += parser_ParsingException; parser.ReceivedConfigurationFrame += parser_ReceivedConfigurationFrame; parser.ReceivedDataFrame += parser_ReceivedDataFrame; parser.ReceivedFrameBufferImage += parser_ReceivedFrameBufferImage; parser.ConnectionTerminated += parser_ConnectionTerminated; // Define the connection string //parser.ConnectionString = @"phasorProtocol=IeeeC37_118V1; transportProtocol=UDP; localport=5000; server=233.123.123.123:5000; interface=0.0.0.0"; //parser.ConnectionString = @"phasorProtocol=Ieee1344; transportProtocol=File; file=D:\Projects\Applications\openPDC\Synchrophasor\Current Version\Build\Output\Debug\Applications\openPDC\Sample1344.PmuCapture"; //parser.ConnectionString = @"phasorProtocol=Macrodyne; accessID=1; transportProtocol=File; skipDisableRealTimeData = true; file=C:\Users\Ritchie\Desktop\Development\Macrodyne\ING.out; iniFileName=C:\Users\Ritchie\Desktop\Development\Macrodyne\BCH18Aug2011.ini; deviceLabel=ING1; protocolVersion=G"; //parser.ConnectionString = @"phasorProtocol=Iec61850_90_5; accessID=1; transportProtocol=UDP; skipDisableRealTimeData = true; localPort=102; interface=0.0.0.0; commandChannel={transportProtocol=TCP; server=172.21.1.201:4712; interface=0.0.0.0}"; //parser.ConnectionString = @"phasorProtocol=FNET; transportProtocol=TCP; server=172.21.4.100:4001; interface=0.0.0.0; isListener=false"; //parser.ConnectionString = @"phasorProtocol=Macrodyne; transportProtocol=Serial; port=COM6; baudrate=38400; parity=None; stopbits=One; databits=8; dtrenable=False; rtsenable=False;"; //parser.ConnectionString = @"phasorProtocol=SelFastMessage; transportProtocol=Serial; port=COM5; baudrate=57600; parity=None; stopbits=One; databits=8; dtrenable=False; rtsenable=False;"; //parser.ConnectionString = @"phasorProtocol=IEEEC37_118v1; transportProtocol=File; file=C:\Users\Ritchie\Desktop\MTI_Test_3phase.PmuCapture; checkSumValidationFrameTypes=DataFrame,HeaderFrame,CommandFrame"; parser.ConnectionString = @"phasorProtocol=IEEEC37_118V1; transportProtocol=tcp; accessID=105; server=172.31.105.135:4712; interface=0.0.0.0; isListener=false"; Dictionary<string, string> settings = parser.ConnectionString.ParseKeyValuePairs(); string setting; // TODO: These should be optional picked up from connection string inside of MPFP // Apply other settings as needed if (settings.TryGetValue("accessID", out setting)) parser.DeviceID = ushort.Parse(setting); if (settings.TryGetValue("simulateTimestamp", out setting)) parser.InjectSimulatedTimestamp = setting.ParseBoolean(); if (settings.TryGetValue("allowedParsingExceptions", out setting)) parser.AllowedParsingExceptions = int.Parse(setting); if (settings.TryGetValue("parsingExceptionWindow", out setting)) parser.ParsingExceptionWindow = Ticks.FromSeconds(double.Parse(setting)); if (settings.TryGetValue("autoStartDataParsingSequence", out setting)) parser.AutoStartDataParsingSequence = setting.ParseBoolean(); if (settings.TryGetValue("skipDisableRealTimeData", out setting)) parser.SkipDisableRealTimeData = setting.ParseBoolean(); // When connecting to a file based resource you may want to loop the data parser.AutoRepeatCapturedPlayback = true; // Start frame parser parser.AutoStartDataParsingSequence = true; Console.WriteLine("ConnectionString: {0}", parser.ConnectionString); parser.Start(); // To keep the console open while receiving live data with AutoRepeatCapturedPlayback = false, uncomment the following line of code: Console.WriteLine("Press <enter> to terminate application..."); Console.ReadLine(); parser.Stop(); // Stop concentrator if (TestConcentrator) concentrator.Stop(); if (WriteLogs) m_exportFile.Close(); }
/// <summary> /// Releases the unmanaged resources used by the <see cref="CommonPhasorServices"/> object and optionally releases the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { if (!m_disposed) { try { if (disposing) { // Detach from frame parser events and dispose if ((object)m_frameParser != null) { m_frameParser.ConnectionAttempt -= m_frameParser_ConnectionAttempt; m_frameParser.ConnectionEstablished -= m_frameParser_ConnectionEstablished; m_frameParser.ConnectionException -= m_frameParser_ConnectionException; m_frameParser.ConnectionTerminated -= m_frameParser_ConnectionTerminated; m_frameParser.ExceededParsingExceptionThreshold -= m_frameParser_ExceededParsingExceptionThreshold; m_frameParser.ParsingException -= m_frameParser_ParsingException; m_frameParser.ReceivedConfigurationFrame -= m_frameParser_ReceivedConfigurationFrame; m_frameParser.Dispose(); } m_frameParser = null; // Dispose configuration of wait handle if (m_configurationWaitHandle != null) m_configurationWaitHandle.Close(); m_configurationWaitHandle = null; m_configurationFrame = null; } } finally { m_disposed = true; // Prevent duplicate dispose. base.Dispose(disposing); // Call base class Dispose(). } } }
/// <summary> /// Initializes <see cref="PhasorMeasurementMapper"/>. /// </summary> public override void Initialize() { base.Initialize(); Dictionary<string, string> settings = Settings; string setting; // Load optional mapper specific connection parameters if (settings.TryGetValue("isConcentrator", out setting)) m_isConcentrator = setting.ParseBoolean(); else m_isConcentrator = false; if (settings.TryGetValue("accessID", out setting)) m_accessID = ushort.Parse(setting); else m_accessID = 1; if (settings.TryGetValue("forceLabelMapping", out setting)) m_forceLabelMapping = setting.ParseBoolean(); else m_forceLabelMapping = false; // Commented out for security purposes related to Parent collection -- // Replace with secure notification mechanism //if (settings.TryGetValue("primaryDataSource", out setting)) //{ // uint primaryDataSourceID = 0; // // Lookup adapter runtime ID of specified primary data source // if (!string.IsNullOrWhiteSpace(setting)) // { // try // { // DataRow[] filteredRows = DataSource.Tables["InputAdapters"].Select(string.Format("AdapterName = '{0}'", setting)); // if (filteredRows.Length > 0) // primaryDataSourceID = uint.Parse(filteredRows[0]["ID"].ToString()); // else // OnProcessException(new InvalidOperationException(string.Format("Failed to find input adapter ID for primary data source \"{0}\", data source was not established.", setting))); // } // catch (Exception ex) // { // OnProcessException(new InvalidOperationException(string.Format("Failed to find input adapter ID for primary data source \"{0}\" due to exception: {1} Data source was not established.", setting, ex.Message), ex)); // } // } // if (primaryDataSourceID > 0) // { // // Get matching data subscriber // m_primaryDataSource = Parent.FirstOrDefault(adapter => adapter.ID == primaryDataSourceID && adapter is DataSubscriber) as DataSubscriber; // if ((object)m_primaryDataSource == null) // { // OnProcessException(new InvalidOperationException(string.Format("Input adapter \"{0}\" specified to be the primary data source was not a DataSubscriber adapter, data source was not established.", setting))); // } // else // { // // Attach to connection events of primary source adapter since these will be used to control when back connection is established... // m_primaryDataSource.ConnectionEstablished += m_primaryDataSource_ConnectionEstablished; // m_primaryDataSource.ConnectionTerminated += m_primaryDataSource_ConnectionTerminated; // } // } //} if (settings.TryGetValue("sharedMapping", out setting)) SharedMapping = setting.Trim(); else SharedMapping = null; if (settings.TryGetValue("timeZone", out setting) && !string.IsNullOrWhiteSpace(setting) && !setting.Trim().Equals("UTC", StringComparison.OrdinalIgnoreCase) && !setting.Trim().Equals("Coordinated Universal Time", StringComparison.OrdinalIgnoreCase)) { try { m_timezone = TimeZoneInfo.FindSystemTimeZoneById(setting); } catch (Exception ex) { OnProcessException(MessageLevel.Info, new InvalidOperationException($"Defaulting to UTC. Failed to find system time zone for ID \"{setting}\": {ex.Message}", ex)); m_timezone = TimeZoneInfo.Utc; } } else { m_timezone = TimeZoneInfo.Utc; } if (settings.TryGetValue("timeAdjustmentTicks", out setting)) m_timeAdjustmentTicks = long.Parse(setting); else m_timeAdjustmentTicks = 0; if (settings.TryGetValue("dataLossInterval", out setting)) m_dataStreamMonitor.Interval = (int)(double.Parse(setting) * 1000.0D); else m_dataStreamMonitor.Interval = 5000; if (settings.TryGetValue("delayedConnectionInterval", out setting)) { double interval = double.Parse(setting) * 1000.0D; // Minimum delay is one millisecond if (interval < 1.0D) interval = 1.0D; ConnectionAttemptInterval = interval; } else { ConnectionAttemptInterval = 1500.0D; } if (settings.TryGetValue("allowUseOfCachedConfiguration", out setting)) m_allowUseOfCachedConfiguration = setting.ParseBoolean(); else m_allowUseOfCachedConfiguration = true; if (settings.TryGetValue("countOnlyMappedMeasurements", out setting)) m_countOnlyMappedMeasurements = setting.ParseBoolean(); else m_countOnlyMappedMeasurements = false; // Create a new phasor protocol frame parser for non-virtual connections MultiProtocolFrameParser frameParser = new MultiProtocolFrameParser(); // Most of the parameters in the connection string will be for the data source in the frame parser // so we provide all of them, other parameters will simply be ignored frameParser.ConnectionString = ConnectionString; // Since input adapter will automatically reconnect on connection exceptions, we need only to specify // that the frame parser try to connect once per connection attempt frameParser.MaximumConnectionAttempts = 1; // For captured data simulations we will inject a simulated timestamp and auto-repeat file stream... if (frameParser.TransportProtocol == TransportProtocol.File) { if (settings.TryGetValue("definedFrameRate", out setting)) frameParser.DefinedFrameRate = int.Parse(setting); else frameParser.DefinedFrameRate = 30; if (settings.TryGetValue("autoRepeatFile", out setting)) frameParser.AutoRepeatCapturedPlayback = setting.ParseBoolean(); else frameParser.AutoRepeatCapturedPlayback = true; if (settings.TryGetValue("useHighResolutionInputTimer", out setting)) frameParser.UseHighResolutionInputTimer = setting.ParseBoolean(); else frameParser.UseHighResolutionInputTimer = false; } // Apply other settings as needed if (settings.TryGetValue("simulateTimestamp", out setting)) frameParser.InjectSimulatedTimestamp = setting.ParseBoolean(); else frameParser.InjectSimulatedTimestamp = (frameParser.TransportProtocol == TransportProtocol.File); if (settings.TryGetValue("allowedParsingExceptions", out setting)) frameParser.AllowedParsingExceptions = int.Parse(setting); if (settings.TryGetValue("parsingExceptionWindow", out setting)) frameParser.ParsingExceptionWindow = Ticks.FromSeconds(double.Parse(setting)); if (settings.TryGetValue("autoStartDataParsingSequence", out setting)) frameParser.AutoStartDataParsingSequence = setting.ParseBoolean(); if (settings.TryGetValue("skipDisableRealTimeData", out setting)) frameParser.SkipDisableRealTimeData = setting.ParseBoolean(); if (!(settings.TryGetValue("lagTime", out setting) && double.TryParse(setting, out m_lagTime))) m_lagTime = 10.0D; if (!(settings.TryGetValue("leadTime", out setting) && double.TryParse(setting, out m_leadTime))) m_leadTime = 3.0D; if (!(settings.TryGetValue("timeResolution", out setting) && long.TryParse(setting, out m_timeResolution))) m_timeResolution = 10000L; if (settings.TryGetValue("enableConnectionErrors", out setting)) EnableConnectionErrors = setting.ParseBoolean(); // Provide access ID to frame parser as this may be necessary to make a phasor connection frameParser.DeviceID = m_accessID; frameParser.SourceName = Name; // Assign reference to frame parser for this connection and attach to needed events FrameParser = frameParser; // Load input devices associated with this connection LoadInputDevices(); // Load active device measurements associated with this connection LoadDeviceMeasurements(); // Load specific configuration file if one was specified if (settings.TryGetValue("configurationFile", out setting)) LoadConfiguration(setting); // Register with the statistics engine StatisticsEngine.Register(this, "InputStream", "IS"); StatisticsEngine.Calculated += (sender, args) => ResetLatencyCounters(); StatisticsEngine.Calculated += (sender, args) => ResetMeasurementsPerSecondCounters(); }