/// <summary> /// Creates a new <see cref="DataGapRecoverer"/>. /// </summary> public DataGapRecoverer() { m_dataGapRecoveryCompleted = new ManualResetEventSlim(true); m_recoveryStartDelay = DefaultRecoveryStartDelay; m_minimumRecoverySpan = DefaultMinimumRecoverySpan; m_maximumRecoverySpan = DefaultMaximumRecoverySpan; string loggingPath = FilePath.GetDirectoryName(FilePath.GetAbsolutePath(DataSubscriber.DefaultLoggingPath)); if (Directory.Exists(loggingPath)) { m_loggingPath = loggingPath; } m_subscriptionInfo = new UnsynchronizedSubscriptionInfo(false); m_subscriptionInfo.FilterExpression = DefaultFilterExpression; m_subscriptionInfo.ProcessingInterval = DefaultRecoveryProcessingInterval; m_subscriptionInfo.UseMillisecondResolution = DefaultUseMillisecondResolution; m_dataStreamMonitor = new Timer(); m_dataStreamMonitor.Elapsed += DataStreamMonitor_Elapsed; m_dataStreamMonitor.Interval = DefaultDataMonitoringInterval * 1000.0D; m_dataStreamMonitor.AutoReset = true; m_dataStreamMonitor.Enabled = false; }
/// <summary> /// Creates a new <see cref="DataGapRecoverer"/>. /// </summary> public DataGapRecoverer() { Log = Logger.CreatePublisher(GetType(), MessageClass.Framework); Log.InitialStackMessages = Log.InitialStackMessages.Union("ComponentName", GetType().Name); m_dataGapRecoveryCompleted = new ManualResetEventSlim(true); m_recoveryStartDelay = DefaultRecoveryStartDelay; m_minimumRecoverySpan = DefaultMinimumRecoverySpan; m_maximumRecoverySpan = DefaultMaximumRecoverySpan; string loggingPath = FilePath.GetDirectoryName(FilePath.GetAbsolutePath(DataSubscriber.DefaultLoggingPath)); if (Directory.Exists(loggingPath)) { m_loggingPath = loggingPath; } m_subscriptionInfo = new UnsynchronizedSubscriptionInfo(false); m_subscriptionInfo.FilterExpression = DefaultFilterExpression; m_subscriptionInfo.ProcessingInterval = DefaultRecoveryProcessingInterval; m_subscriptionInfo.UseMillisecondResolution = DefaultUseMillisecondResolution; m_dataStreamMonitor = Common.TimerScheduler.CreateTimer((int)(DefaultDataMonitoringInterval * 1000.0D)); m_dataStreamMonitor.Elapsed += DataStreamMonitor_Elapsed; m_dataStreamMonitor.AutoReset = true; m_dataStreamMonitor.Enabled = false; }
/// <summary> /// Creates a new <see cref="DataSubscriptionHubClient"/> instance. /// </summary> public DataSubscriptionHubClient() { m_statisticSubscriptionInfo = new UnsynchronizedSubscriptionInfo(false); m_dataSubscriptionInfo = new UnsynchronizedSubscriptionInfo(false); m_measurements = new List<MeasurementValue>(); m_statistics = new List<MeasurementValue>(); m_statusLights = new List<StatusLight>(); m_deviceDetails = new List<DeviceDetail>(); m_measurementDetails = new List<MeasurementDetail>(); m_phasorDetails = new List<PhasorDetail>(); m_schemaVersion = new List<SchemaVersion>(); m_measurementLock = new object(); }
/// <summary> /// Creates a new <see cref="DataSubscriptionHubClient"/> instance. /// </summary> public DataSubscriptionHubClient() { m_statisticSubscriptionInfo = new UnsynchronizedSubscriptionInfo(false); m_dataSubscriptionInfo = new UnsynchronizedSubscriptionInfo(false); m_measurements = new List<MeasurementValue>(); m_statistics = new List<MeasurementValue>(); m_statusLights = new List<StatusLight>(); m_deviceDetails = new List<DeviceDetail>(); m_measurementDetails = new List<MeasurementDetail>(); m_phasorDetails = new List<PhasorDetail>(); m_schemaVersion = new List<SchemaVersion>(); m_measurementLock = new object(); using(AdoDataConnection conn = new AdoDataConnection("securityProvider")) { int index = conn.ExecuteScalar<int>("Select ID FROM ValueListGroup WHERE Name = 'ModbusSubscriptions'"); m_connectionString = conn.ExecuteScalar<string>("Select Text FROM ValueList WHERE GroupID = {0} AND IsDefault = 1", index); } }
/// <summary> /// Creates a new <see cref="DataGapRecoverer"/>. /// </summary> public DataGapRecoverer() { m_dataGapRecoveryCompleted = new ManualResetEventSlim(false); m_recoveryStartDelay = DefaultRecoveryStartDelay; m_minimumRecoverySpan = DefaultMinimumRecoverySpan; m_maximumRecoverySpan = DefaultMaximumRecoverySpan; m_subscriptionInfo = new UnsynchronizedSubscriptionInfo(false); m_subscriptionInfo.FilterExpression = DefaultFilterExpression; m_subscriptionInfo.ProcessingInterval = DefaultRecoveryProcessingInterval; m_subscriptionInfo.UseMillisecondResolution = DefaultUseMillisecondResolution; m_dataStreamMonitor = new Timer(); m_dataStreamMonitor.Elapsed += DataStreamMonitor_Elapsed; m_dataStreamMonitor.Interval = DefaultDataMonitoringInterval * 1000.0D; m_dataStreamMonitor.AutoReset = true; m_dataStreamMonitor.Enabled = false; }
/// <summary> /// Opens the stream and starts playback. /// </summary> /// <param name="songName">The name of the song to be played.</param> public void Play(string songName) { if (m_dataSubscriber != null && m_metadata != null) { UnsynchronizedSubscriptionInfo info; StringBuilder filterExpression = new StringBuilder(); DataTable deviceTable = m_metadata.Tables["DeviceDetail"]; DataTable measurementTable = m_metadata.Tables["MeasurementDetail"]; Dictionary<string, string> uriSettings; string dataChannel = null; int uriIndex = ConnectionUri.IndexOf(URI_SEPARATOR); m_channelIndexes = new ConcurrentDictionary<Guid, int>(); m_sampleRate = DEFAULT_SAMPLE_RATE; m_numChannels = DEFAULT_NUM_CHANNELS; // Get sample rate from metadata. if (deviceTable != null) { string sampleRate = deviceTable.Rows.Cast<DataRow>() .Single(row => row["Acronym"].ToNonNullString() == songName)["FramesPerSecond"].ToNonNullString(); if (!string.IsNullOrEmpty(sampleRate)) m_sampleRate = int.Parse(sampleRate); } // Get measurements from metadata. if (measurementTable != null) { IEnumerable<DataRow> measurementRows = measurementTable.Rows.Cast<DataRow>() .Where(row => row["DeviceAcronym"].ToNonNullString() == songName) .Where(row => row["SignalAcronym"].ToNonNullString() == "ALOG" || row["SignalAcronym"].ToNonNullString() == "VPHM") .Where(row => row["Enabled"].ToNonNullString().ParseBoolean()) .OrderBy(row => row["ID"].ToNonNullString()); m_numChannels = 0; foreach (DataRow row in measurementRows) { Guid measurementID = Guid.Parse(row["SignalID"].ToNonNullString()); if (m_numChannels > 0) filterExpression.Append(';'); filterExpression.Append(measurementID); m_channelIndexes[measurementID] = m_numChannels; m_numChannels++; } } // Create UDP data channel if specified. if (uriIndex >= 0) { uriSettings = ConnectionUri.Substring(uriIndex + URI_SEPARATOR.Length).ParseKeyValuePairs('&'); if (uriSettings.ContainsKey("udp")) dataChannel = string.Format("dataChannel={{port={0}; interface={1}}}", uriSettings["udp"], IPv6Enabled ? "::0" : "0.0.0.0"); } m_buffer = new ConcurrentQueue<IMeasurement>(); m_dumpTimer = CreateDumpTimer(); m_statTimer = CreateStatTimer(); m_waveProvider = new BufferedWaveProvider(new WaveFormat(m_sampleRate < MINIMUM_SAMPLE_RATE ? MINIMUM_SAMPLE_RATE : m_sampleRate, m_numChannels)); m_wavePlayer = CreateWavePlayer(m_waveProvider); m_waveProvider.DiscardOnBufferOverflow = true; info = new UnsynchronizedSubscriptionInfo(false) { FilterExpression = filterExpression.ToString(), ExtraConnectionStringParameters = dataChannel }; m_statTimer.Start(); m_wavePlayer.Play(); m_dataSubscriber.UnsynchronizedSubscribe(info); m_timeoutTimer.Start(); OnStateChanged(PlaybackState.Buffering); } }
/// <summary> /// Creates a new <see cref="DataGapRecoverer"/>. /// </summary> public DataGapRecoverer() { m_dataGapRecoveryCompleted = new ManualResetEventSlim(false); m_recoveryStartDelay = DefaultRecoveryStartDelay; m_minimumRecoverySpan = DefaultMinimumRecoverySpan; m_maximumRecoverySpan = DefaultMaximumRecoverySpan; string loggingPath = FilePath.GetDirectoryName(FilePath.GetAbsolutePath(DataSubscriber.DefaultLoggingPath)); if (Directory.Exists(loggingPath)) m_loggingPath = loggingPath; m_subscriptionInfo = new UnsynchronizedSubscriptionInfo(false); m_subscriptionInfo.FilterExpression = DefaultFilterExpression; m_subscriptionInfo.ProcessingInterval = DefaultRecoveryProcessingInterval; m_subscriptionInfo.UseMillisecondResolution = DefaultUseMillisecondResolution; m_dataStreamMonitor = new Timer(); m_dataStreamMonitor.Elapsed += DataStreamMonitor_Elapsed; m_dataStreamMonitor.Interval = DefaultDataMonitoringInterval * 1000.0D; m_dataStreamMonitor.AutoReset = true; m_dataStreamMonitor.Enabled = false; }
/// <summary> /// Subscribes (or re-subscribes) to a data publisher for an unsynchronized set of data points. /// </summary> /// <param name="info">Configuration object that defines the subscription.</param> /// <returns><c>true</c> if subscribe transmission was successful; otherwise <c>false</c>.</returns> public bool UnsynchronizedSubscribe(UnsynchronizedSubscriptionInfo info) { // Dispose of any previously established local concentrator DisposeLocalConcentrator(); StringBuilder connectionString = new StringBuilder(); AssemblyInfo assemblyInfo = AssemblyInfo.ExecutingAssembly; connectionString.AppendFormat("trackLatestMeasurements={0};", info.Throttled); connectionString.AppendFormat("publishInterval={0};", info.PublishInterval); connectionString.AppendFormat("includeTime={0};", info.IncludeTime); connectionString.AppendFormat("lagTime={0};", info.LagTime); connectionString.AppendFormat("leadTime={0};", info.LeadTime); connectionString.AppendFormat("useLocalClockAsRealTime={0};", info.UseLocalClockAsRealTime); connectionString.AppendFormat("processingInterval={0};", info.ProcessingInterval); connectionString.AppendFormat("useMillisecondResolution={0};", info.UseMillisecondResolution); connectionString.AppendFormat("requestNaNValueFilter={0};", info.RequestNaNValueFilter); connectionString.AppendFormat("assemblyInfo={{source={0};version={1}.{2}.{3};buildDate={4}}};", assemblyInfo.Name, assemblyInfo.Version.Major, assemblyInfo.Version.Minor, assemblyInfo.Version.Build, assemblyInfo.BuildDate.ToString("yyyy-MM-dd HH:mm:ss")); if (!string.IsNullOrWhiteSpace(info.FilterExpression)) connectionString.AppendFormat("inputMeasurementKeys={{{0}}};", info.FilterExpression); if (info.UdpDataChannel) connectionString.AppendFormat("dataChannel={{localport={0}}};", info.DataChannelLocalPort); if (!string.IsNullOrWhiteSpace(info.StartTime)) connectionString.AppendFormat("startTimeConstraint={0};", info.StartTime); if (!string.IsNullOrWhiteSpace(info.StopTime)) connectionString.AppendFormat("stopTimeConstraint={0};", info.StopTime); if (!string.IsNullOrWhiteSpace(info.ConstraintParameters)) connectionString.AppendFormat("timeConstraintParameters={0};", info.ConstraintParameters); if (!string.IsNullOrWhiteSpace(info.ExtraConnectionStringParameters)) connectionString.AppendFormat("{0};", info.ExtraConnectionStringParameters); // Make sure not to monitor for data loss any faster than down-sample time on throttled connections - additionally // you will want to make sure data stream monitor is twice lag-time to allow time for initial points to arrive. if (info.Throttled && (object)m_dataStreamMonitor != null && m_dataStreamMonitor.Interval / 1000.0D < info.LagTime) m_dataStreamMonitor.Interval = 2.0D * info.LagTime * 1000.0D; // Set millisecond resolution member variable for compact measurement parsing m_useMillisecondResolution = info.UseMillisecondResolution; return Subscribe(false, info.UseCompactMeasurementFormat, connectionString.ToString()); }
// Subscribes or resubscribes to real-time or historical stream using current filter expression private void InitiateSubscription(bool historical) { if (m_subscribed || m_historicalSubscription) { m_subscriber.Unsubscribe(); ClearSubscription(); } m_historicalSubscription = historical; UnsynchronizedSubscriptionInfo subscriptionInfo; subscriptionInfo = new UnsynchronizedSubscriptionInfo(false); subscriptionInfo.FilterExpression = m_filterExpression; if (historical) { subscriptionInfo.StartTime = m_startTime; subscriptionInfo.StopTime = m_stopTime; subscriptionInfo.ProcessingInterval = m_processInterval; UpdateStatus("*** Starting historical replay at {0} playback speed ***", m_processInterval == 0 ? "fast as possible" : m_processInterval + "ms"); } // Attempt to extract possible data channel setting from connection string. // For example, adding "; dataChannel={port=9191}" to the connection string // would request that the data publisher send data to the subscriber over // UDP on port 9191. Technically this is part of the subscription info but // we allow this definition in the connection string for this application. string dataChannel = null; if (!string.IsNullOrEmpty(m_connectionString)) { Dictionary<string, string> settings = m_connectionString.ParseKeyValuePairs(); settings.TryGetValue("dataChannel", out dataChannel); } if ((object)dataChannel != null) subscriptionInfo.ExtraConnectionStringParameters = "dataChannel={" + dataChannel + "}"; m_subscriber.UnsynchronizedSubscribe(subscriptionInfo); }
/// <summary> /// Creates a new instance of the <see cref="AlarmMonitor"/> class. /// </summary> /// <param name="singleton">Indicates whether this instance should update the global reference to become the singleton.</param> public AlarmMonitor(bool singleton = false) { object refreshInterval = IsolatedStorageManager.ReadFromIsolatedStorage("AlarmStatusRefreshInterval") ?? DefaultRefreshInterval; if (!int.TryParse(refreshInterval.ToString(), out m_refreshInterval)) m_refreshInterval = DefaultRefreshInterval; m_currentAlarmsLock = new object(); m_currentAlarms = new HashSet<Alarm>(); m_refreshTimer = new Timer(m_refreshInterval * 1000); m_refreshTimer.Elapsed += RefreshTimer_Elapsed; m_alarmStatusQuery = new AlarmStatusQuery(); m_alarmStatusQuery.RaisedAlarmStates += m_alarmStatusQuery_RaisedAlarmStates; m_alarmStatusQuery.ProcessException += m_alarmStatusQuery_ProcessException; // Load all alarms defined in the database UpdateDefinedAlarms(); // Setup subscription to subscribe to all alarm measurements m_subscriptionInfo = new UnsynchronizedSubscriptionInfo(false) { FilterExpression = "FILTER ActiveMeasurements WHERE SignalType='ALRM'" }; m_dataSubscriber = new DataSubscriber(); m_dataSubscriber.ConnectionEstablished += m_dataSubscriber_ConnectionEstablished; m_dataSubscriber.ReceivedServerResponse += m_dataSubscriber_ReceivedServerResponse; m_dataSubscriber.NewMeasurements += m_dataSubscriber_NewMeasurements; m_dataSubscriber.ProcessException += m_dataSubscriber_ProcessException; m_dataSubscriber.ConnectionString = GetDataPublisherConnectionString(); m_dataSubscriber.OperationalModes |= OperationalModes.UseCommonSerializationFormat | OperationalModes.CompressSignalIndexCache | OperationalModes.CompressPayloadData; m_dataSubscriber.DataLossInterval = -1; m_dataSubscriber.Initialize(); if (singleton) Default = this; }
/// <summary> /// Creates a new <see cref="DataGapRecoverer"/>. /// </summary> public DataGapRecoverer() { Log = Logger.CreatePublisher(GetType(), MessageClass.Framework); Log.InitialStackMessages = Log.InitialStackMessages.Union("ComponentName", GetType().Name); m_dataGapRecoveryCompleted = new ManualResetEventSlim(true); m_recoveryStartDelay = DefaultRecoveryStartDelay; m_minimumRecoverySpan = DefaultMinimumRecoverySpan; m_maximumRecoverySpan = DefaultMaximumRecoverySpan; string loggingPath = FilePath.GetDirectoryName(FilePath.GetAbsolutePath(DataSubscriber.DefaultLoggingPath)); if (Directory.Exists(loggingPath)) m_loggingPath = loggingPath; m_subscriptionInfo = new UnsynchronizedSubscriptionInfo(false); m_subscriptionInfo.FilterExpression = DefaultFilterExpression; m_subscriptionInfo.ProcessingInterval = DefaultRecoveryProcessingInterval; m_subscriptionInfo.UseMillisecondResolution = DefaultUseMillisecondResolution; m_dataStreamMonitor = Common.TimerScheduler.CreateTimer((int)(DefaultDataMonitoringInterval * 1000.0D)); m_dataStreamMonitor.Elapsed += DataStreamMonitor_Elapsed; m_dataStreamMonitor.AutoReset = true; m_dataStreamMonitor.Enabled = false; }