History

Converted TFS repository to Git.

StephenCWills committed 11 years ago

Commit dd143d71 parent ab7f4b62684 files · +766031 −765809Browse files

Showing the changes to Source/Libraries/TimeSeriesPlatformLibrary/Samples/AverageFrequencyCalculator.cpp (1 of 2684 files). Show all

Unified · Split

Source/Libraries/TimeSeriesPlatformLibrary/Samples/AverageFrequencyCalculator.cpp+261−261
@@ -1,262 +1,262 @@
1−//******************************************************************************************************
2−// AverageFrequencyCalculator.cpp - Gbtc
3−//
4−// Copyright � 2010, Grid Protection Alliance. All Rights Reserved.
5−//
6−// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
7−// the NOTICE file distributed with this work for additional information regarding copyright ownership.
8−// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
9−// not use this file except in compliance with the License. You may obtain a copy of the License at:
10−//
11−// http://www.opensource.org/licenses/eclipse-1.0.php
12−//
13−// Unless agreed to in writing, the subject software distributed under the License is distributed on an
14−// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
15−// License for the specific language governing permissions and limitations.
16−//
17−// Code Modification History:
18−// ----------------------------------------------------------------------------------------------------
19−// 04/25/2012 - Stephen C. Wills
20−// Generated original version of source code.
21−//
22−//******************************************************************************************************
23−
24−#include <iostream>
25−#include <string>
26−#include <vector>
27−#include <map>
28−
29−#include "../Common/Convert.h"
30−#include "../Common/Measurement.h"
31−#include "../Transport/DataSubscriber.h"
32−
33−namespace gsfts = GSF::TimeSeries;
34−namespace tst = gsfts::Transport;
35−
36−tst::DataSubscriber Subscriber;
37−tst::SubscriptionInfo Info;
38−
39−// Create helper objects for subscription.
40−tst::SubscriberConnector CreateSubscriberConnector(std::string hostname, uint16_t port);
41−tst::SubscriptionInfo CreateSubscriptionInfo();
42−
43−// Handlers for subscriber callbacks.
44−void Resubscribe(tst::DataSubscriber* source);
45−void ProcessMeasurements(std::vector<gsfts::Measurement> newMeasurements);
46−void DisplayStatusMessage(std::string message);
47−void DisplayErrorMessage(std::string message);
48−
49−// Runs the subscriber.
50−void RunSubscriber(std::string hostname, gsfts::uint16_t port);
51−
52−// Sample application to demonstrate average frequency calculation using the subscriber API.
53−int main(int argc, char* argv[])
54−{
55− std::string hostname;
56− gsfts::uint16_t port;
57−
58− // Ensure that the necessary
59− // command line arguments are given.
60− if (argc < 3)
61− {
62− std::cout << "Usage:" << std::endl;
63− std::cout << " AverageFrequencyCalculator HOSTNAME PORT" << std::endl;
64− return 0;
65− }
66−
67− // Get hostname and port.
68− hostname = argv[1];
69− std::stringstream(argv[2]) >> port;
70−
71− // Run the subscriber.
72− RunSubscriber(hostname, port);
73−
74− // Wait until the user presses enter before quitting.
75− std::string line;
76− std::getline(std::cin, line);
77−
78− // Disconnect the subscriber to stop background threads.
79− Subscriber.Disconnect();
80−
81− return 0;
82−}
83−
84−// The proper procedure when creating and running a subscriber is:
85−// - Create subscriber
86−// - Register callbacks
87−// - Connect to publisher
88−// - Subscribe
89−void RunSubscriber(std::string hostname, gsfts::uint16_t port)
90−{
91− // The connector is declared here because it
92− // is only needed for the initial connection
93− tst::SubscriberConnector connector;
94−
95− // Set up helper objects
96− connector = CreateSubscriberConnector(hostname, port);
97− Info = CreateSubscriptionInfo();
98−
99− // Register callbacks
100− Subscriber.RegisterStatusMessageCallback(&DisplayStatusMessage);
101− Subscriber.RegisterErrorMessageCallback(&DisplayErrorMessage);
102−
103− // Connect and subscribe to publisher
104− if (connector.Connect(Subscriber))
105− Subscriber.Subscribe(Info);
106− else
107− std::cerr << "All connection attempts failed" << std::endl;
108−}
109−
110−tst::SubscriptionInfo CreateSubscriptionInfo()
111−{
112− // SubscriptionInfo is a helper object which allows the user
113− // to set up their subscription and reuse subscription settings.
114− tst::SubscriptionInfo info;
115−
116− info.FilterExpression = "FILTER ActiveMeasurements WHERE SignalType = 'FREQ'";
117− info.NewMeasurementsCallback = &ProcessMeasurements;
118−
119− // Uncomment to enable optional UDP data channel
120− //info.UdpDataChannel = true;
121− //info.DataChannelLocalPort = 9600;
122−
123− info.IncludeTime = true;
124− info.UseLocalClockAsRealTime = false;
125− info.UseMillisecondResolution = true;
126−
127− // This controls the downsampling time, in seconds
128− info.Throttled = true;
129− info.LagTime = 1.0;
130−
131− return info;
132−}
133−
134−tst::SubscriberConnector CreateSubscriberConnector(std::string hostname, gsfts::uint16_t port)
135−{
136− // SubscriberConnector is another helper object which allows the
137− // user to modify settings for auto-reconnects and retry cycles.
138− tst::SubscriberConnector connector;
139−
140− connector.RegisterErrorMessageCallback(&DisplayErrorMessage);
141− connector.RegisterReconnectCallback(&Resubscribe);
142−
143− connector.SetHostname(hostname);
144− connector.SetPort(port);
145− connector.SetMaxRetries(-1);
146− connector.SetRetryInterval(2000);
147− connector.SetAutoReconnect(true);
148−
149− return connector;
150−}
151−
152−// Callback which is called when the subscriber has
153−// received a new packet of measurements from the publisher.
154−void ProcessMeasurements(std::vector<gsfts::Measurement> newMeasurements)
155−{
156− const double LoFrequency = 57.0;
157− const double HiFrequency = 62.0;
158− const double HzResolution = 1000.0; // three decimal places
159−
160− const std::string TimestampFormat = "%Y-%m-%d %H:%M:%S.%f";
161− const std::size_t MaxTimestampSize = 80;
162−
163− static std::map<gsfts::Guid, int> m_lastValues;
164−
165− std::map<gsfts::Guid, int>::iterator lastValueIter;
166− gsfts::Measurement currentMeasurement;
167− gsfts::Guid signalID;
168−
169− double frequency;
170− double frequencyTotal;
171− double maximumFrequency = LoFrequency;
172− double minimumFrequency = HiFrequency;
173− int adjustedFrequency;
174− int lastValue;
175− int total;
176−
177− char timestamp[MaxTimestampSize];
178− std::size_t i;
179−
180− frequencyTotal = 0.0;
181− total = 0;
182−
183− std::cout << Subscriber.GetTotalMeasurementsReceived() << " measurements received so far..." << std::endl;
184−
185− if (newMeasurements.size() > 0)
186− {
187− if (gsfts::TicksToString(timestamp, MaxTimestampSize, TimestampFormat, newMeasurements[0].Timestamp))
188− std::cout << "Timestamp: " << std::string(timestamp) << std::endl;
189−
190− std::cout << "Point\tValue" << std::endl;
191−
192− for (i = 0; i < newMeasurements.size(); ++i)
193− std::cout << newMeasurements[i].ID << '\t' << newMeasurements[i].Value << std::endl;
194−
195− std::cout << std::endl;
196−
197− for (i = 0; i < newMeasurements.size(); ++i)
198− {
199− currentMeasurement = newMeasurements[i];
200− frequency = currentMeasurement.Value;
201− signalID = currentMeasurement.SignalID;
202− adjustedFrequency = (int)(frequency * HzResolution);
203−
204− // Do some simple flat line avoidance...
205− lastValueIter = m_lastValues.find(signalID);
206−
207− if (lastValueIter != m_lastValues.end())
208− {
209− lastValue = lastValueIter->second;
210−
211− if (lastValue == adjustedFrequency)
212− frequency = 0.0;
213− else
214− m_lastValues[signalID] = adjustedFrequency;
215− }
216− else
217− {
218− m_lastValues[signalID] = adjustedFrequency;
219− }
220−
221− // Validate frequency
222− if (frequency > LoFrequency && frequency < HiFrequency)
223− {
224− frequencyTotal += frequency;
225−
226− if (frequency > maximumFrequency)
227− maximumFrequency = frequency;
228−
229− if (frequency < minimumFrequency)
230− minimumFrequency = frequency;
231−
232− total++;
233− }
234− }
235−
236− if (total > 0)
237− {
238− std::cout << "Avg frequency: " << (frequencyTotal / total) << std::endl;
239− std::cout << "Max frequency: " << maximumFrequency << std::endl;
240− std::cout << "Min frequency: " << minimumFrequency << std::endl << std::endl;
241− }
242− }
243−}
244−
245−// Callback that is called when the subscriber auto-reconnects.
246−void Resubscribe(tst::DataSubscriber* source)
247−{
248− if (source->IsConnected())
249− source->Subscribe(Info);
250−}
251−
252−// Callback which is called to display status messages from the subscriber.
253−void DisplayStatusMessage(std::string message)
254−{
255− std::cout << message << std::endl << std::endl;
256−}
257−
258−// Callback which is called to display error messages from the connector and subscriber.
259−void DisplayErrorMessage(std::string message)
260−{
261− std::cerr << message << std::endl << std::endl;
1+//******************************************************************************************************
2+// AverageFrequencyCalculator.cpp - Gbtc
3+//
4+// Copyright � 2010, Grid Protection Alliance. All Rights Reserved.
5+//
6+// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
7+// the NOTICE file distributed with this work for additional information regarding copyright ownership.
8+// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
9+// not use this file except in compliance with the License. You may obtain a copy of the License at:
10+//
11+// http://www.opensource.org/licenses/eclipse-1.0.php
12+//
13+// Unless agreed to in writing, the subject software distributed under the License is distributed on an
14+// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
15+// License for the specific language governing permissions and limitations.
16+//
17+// Code Modification History:
18+// ----------------------------------------------------------------------------------------------------
19+// 04/25/2012 - Stephen C. Wills
20+// Generated original version of source code.
21+//
22+//******************************************************************************************************
23+
24+#include <iostream>
25+#include <string>
26+#include <vector>
27+#include <map>
28+
29+#include "../Common/Convert.h"
30+#include "../Common/Measurement.h"
31+#include "../Transport/DataSubscriber.h"
32+
33+namespace gsfts = GSF::TimeSeries;
34+namespace tst = gsfts::Transport;
35+
36+tst::DataSubscriber Subscriber;
37+tst::SubscriptionInfo Info;
38+
39+// Create helper objects for subscription.
40+tst::SubscriberConnector CreateSubscriberConnector(std::string hostname, uint16_t port);
41+tst::SubscriptionInfo CreateSubscriptionInfo();
42+
43+// Handlers for subscriber callbacks.
44+void Resubscribe(tst::DataSubscriber* source);
45+void ProcessMeasurements(std::vector<gsfts::Measurement> newMeasurements);
46+void DisplayStatusMessage(std::string message);
47+void DisplayErrorMessage(std::string message);
48+
49+// Runs the subscriber.
50+void RunSubscriber(std::string hostname, gsfts::uint16_t port);
51+
52+// Sample application to demonstrate average frequency calculation using the subscriber API.
53+int main(int argc, char* argv[])
54+{
55+ std::string hostname;
56+ gsfts::uint16_t port;
57+
58+ // Ensure that the necessary
59+ // command line arguments are given.
60+ if (argc < 3)
61+ {
62+ std::cout << "Usage:" << std::endl;
63+ std::cout << " AverageFrequencyCalculator HOSTNAME PORT" << std::endl;
64+ return 0;
65+ }
66+
67+ // Get hostname and port.
68+ hostname = argv[1];
69+ std::stringstream(argv[2]) >> port;
70+
71+ // Run the subscriber.
72+ RunSubscriber(hostname, port);
73+
74+ // Wait until the user presses enter before quitting.
75+ std::string line;
76+ std::getline(std::cin, line);
77+
78+ // Disconnect the subscriber to stop background threads.
79+ Subscriber.Disconnect();
80+
81+ return 0;
82+}
83+
84+// The proper procedure when creating and running a subscriber is:
85+// - Create subscriber
86+// - Register callbacks
87+// - Connect to publisher
88+// - Subscribe
89+void RunSubscriber(std::string hostname, gsfts::uint16_t port)
90+{
91+ // The connector is declared here because it
92+ // is only needed for the initial connection
93+ tst::SubscriberConnector connector;
94+
95+ // Set up helper objects
96+ connector = CreateSubscriberConnector(hostname, port);
97+ Info = CreateSubscriptionInfo();
98+
99+ // Register callbacks
100+ Subscriber.RegisterStatusMessageCallback(&DisplayStatusMessage);
101+ Subscriber.RegisterErrorMessageCallback(&DisplayErrorMessage);
102+
103+ // Connect and subscribe to publisher
104+ if (connector.Connect(Subscriber))
105+ Subscriber.Subscribe(Info);
106+ else
107+ std::cerr << "All connection attempts failed" << std::endl;
108+}
109+
110+tst::SubscriptionInfo CreateSubscriptionInfo()
111+{
112+ // SubscriptionInfo is a helper object which allows the user
113+ // to set up their subscription and reuse subscription settings.
114+ tst::SubscriptionInfo info;
115+
116+ info.FilterExpression = "FILTER ActiveMeasurements WHERE SignalType = 'FREQ'";
117+ info.NewMeasurementsCallback = &ProcessMeasurements;
118+
119+ // Uncomment to enable optional UDP data channel
120+ //info.UdpDataChannel = true;
121+ //info.DataChannelLocalPort = 9600;
122+
123+ info.IncludeTime = true;
124+ info.UseLocalClockAsRealTime = false;
125+ info.UseMillisecondResolution = true;
126+
127+ // This controls the downsampling time, in seconds
128+ info.Throttled = true;
129+ info.LagTime = 1.0;
130+
131+ return info;
132+}
133+
134+tst::SubscriberConnector CreateSubscriberConnector(std::string hostname, gsfts::uint16_t port)
135+{
136+ // SubscriberConnector is another helper object which allows the
137+ // user to modify settings for auto-reconnects and retry cycles.
138+ tst::SubscriberConnector connector;
139+
140+ connector.RegisterErrorMessageCallback(&DisplayErrorMessage);
141+ connector.RegisterReconnectCallback(&Resubscribe);
142+
143+ connector.SetHostname(hostname);
144+ connector.SetPort(port);
145+ connector.SetMaxRetries(-1);
146+ connector.SetRetryInterval(2000);
147+ connector.SetAutoReconnect(true);
148+
149+ return connector;
150+}
151+
152+// Callback which is called when the subscriber has
153+// received a new packet of measurements from the publisher.
154+void ProcessMeasurements(std::vector<gsfts::Measurement> newMeasurements)
155+{
156+ const double LoFrequency = 57.0;
157+ const double HiFrequency = 62.0;
158+ const double HzResolution = 1000.0; // three decimal places
159+
160+ const std::string TimestampFormat = "%Y-%m-%d %H:%M:%S.%f";
161+ const std::size_t MaxTimestampSize = 80;
162+
163+ static std::map<gsfts::Guid, int> m_lastValues;
164+
165+ std::map<gsfts::Guid, int>::iterator lastValueIter;
166+ gsfts::Measurement currentMeasurement;
167+ gsfts::Guid signalID;
168+
169+ double frequency;
170+ double frequencyTotal;
171+ double maximumFrequency = LoFrequency;
172+ double minimumFrequency = HiFrequency;
173+ int adjustedFrequency;
174+ int lastValue;
175+ int total;
176+
177+ char timestamp[MaxTimestampSize];
178+ std::size_t i;
179+
180+ frequencyTotal = 0.0;
181+ total = 0;
182+
183+ std::cout << Subscriber.GetTotalMeasurementsReceived() << " measurements received so far..." << std::endl;
184+
185+ if (newMeasurements.size() > 0)
186+ {
187+ if (gsfts::TicksToString(timestamp, MaxTimestampSize, TimestampFormat, newMeasurements[0].Timestamp))
188+ std::cout << "Timestamp: " << std::string(timestamp) << std::endl;
189+
190+ std::cout << "Point\tValue" << std::endl;
191+
192+ for (i = 0; i < newMeasurements.size(); ++i)
193+ std::cout << newMeasurements[i].ID << '\t' << newMeasurements[i].Value << std::endl;
194+
195+ std::cout << std::endl;
196+
197+ for (i = 0; i < newMeasurements.size(); ++i)
198+ {
199+ currentMeasurement = newMeasurements[i];
200+ frequency = currentMeasurement.Value;
201+ signalID = currentMeasurement.SignalID;
202+ adjustedFrequency = (int)(frequency * HzResolution);
203+
204+ // Do some simple flat line avoidance...
205+ lastValueIter = m_lastValues.find(signalID);
206+
207+ if (lastValueIter != m_lastValues.end())
208+ {
209+ lastValue = lastValueIter->second;
210+
211+ if (lastValue == adjustedFrequency)
212+ frequency = 0.0;
213+ else
214+ m_lastValues[signalID] = adjustedFrequency;
215+ }
216+ else
217+ {
218+ m_lastValues[signalID] = adjustedFrequency;
219+ }
220+
221+ // Validate frequency
222+ if (frequency > LoFrequency && frequency < HiFrequency)
223+ {
224+ frequencyTotal += frequency;
225+
226+ if (frequency > maximumFrequency)
227+ maximumFrequency = frequency;
228+
229+ if (frequency < minimumFrequency)
230+ minimumFrequency = frequency;
231+
232+ total++;
233+ }
234+ }
235+
236+ if (total > 0)
237+ {
238+ std::cout << "Avg frequency: " << (frequencyTotal / total) << std::endl;
239+ std::cout << "Max frequency: " << maximumFrequency << std::endl;
240+ std::cout << "Min frequency: " << minimumFrequency << std::endl << std::endl;
241+ }
242+ }
243+}
244+
245+// Callback that is called when the subscriber auto-reconnects.
246+void Resubscribe(tst::DataSubscriber* source)
247+{
248+ if (source->IsConnected())
249+ source->Subscribe(Info);
250+}
251+
252+// Callback which is called to display status messages from the subscriber.
253+void DisplayStatusMessage(std::string message)
254+{
255+ std::cout << message << std::endl << std::endl;
256+}
257+
258+// Callback which is called to display error messages from the connector and subscriber.
259+void DisplayErrorMessage(std::string message)
260+{
261+ std::cerr << message << std::endl << std::endl;
262262 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t