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

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