Skip to content

Commit ae1362b

Browse files
Merge pull request #487 from GridProtectionAlliance/FixPIConnectionTimeoutAssignment
Fix PI connection timeout assignment
2 parents 2c79c2d + 4a3c407 commit ae1362b

File tree

5 files changed

+80
-64
lines changed

5 files changed

+80
-64
lines changed

Source/Libraries/Adapters/PIAdapters/PIBufferInputAdapter.cs

Lines changed: 47 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,16 @@
2121
//
2222
//******************************************************************************************************
2323

24-
using GSF;
2524
using GSF.Diagnostics;
26-
using GSF.TimeSeries;
2725
using GSF.TimeSeries.Adapters;
2826
using OSIsoft.AF.Asset;
2927
using OSIsoft.AF.PI;
3028
using OSIsoft.AF.Time;
3129
using System;
3230
using System.Collections.Generic;
3331
using System.ComponentModel;
34-
using System.Data;
3532
using System.Linq;
3633
using System.Text;
37-
using System.Threading;
38-
using System.Timers;
39-
using Timer = System.Timers.Timer;
4034

4135
namespace PIAdapters;
4236

@@ -53,8 +47,8 @@ public class PIBufferInputAdapter : InputAdapterBase
5347
private const int DefaultPageFactor = 1;
5448

5549
// Fields
56-
private PIConnection m_connection; // PI server connection
57-
private IEnumerator<AFValue> m_dataReader; // Data reader
50+
private PIConnection m_connection; // PI server connection
51+
private IEnumerator<AFValue> m_dataReader; // Data reader
5852
private AFTime m_startTime;
5953
private AFTime m_stopTime;
6054
private bool m_disposed;
@@ -66,7 +60,7 @@ public class PIBufferInputAdapter : InputAdapterBase
6660
/// <summary>
6761
/// Creates a new instance of the <see cref="PIAdapters.PIBufferInputAdapter"/>.
6862
/// </summary>
69-
public PIBufferInputAdapter() {}
63+
public PIBufferInputAdapter() { }
7064

7165
#endregion
7266

@@ -103,10 +97,6 @@ public PIBufferInputAdapter() {}
10397
[DefaultValue(PIConnection.DefaultConnectTimeout)]
10498
public int ConnectTimeout { get; set; }
10599

106-
107-
108-
109-
110100
/// <summary>
111101
/// Gets or sets value paging factor to read more data per page from PI.
112102
/// </summary>
@@ -119,7 +109,7 @@ public PIBufferInputAdapter() {}
119109
/// Gets the flag indicating if this adapter supports temporal processing.
120110
/// </summary>
121111
public override bool SupportsTemporalProcessing => false;
122-
112+
123113

124114
/// <summary>
125115
/// Returns the detailed status of the data input source.
@@ -129,17 +119,19 @@ public override string Status
129119
get
130120
{
131121
StringBuilder status = new();
122+
132123
status.Append(base.Status);
124+
status.AppendLine($" OSI-PI server name: {ServerName}");
125+
status.AppendLine($" Connected to server: {(m_connection is null ? "No" : m_connection.Connected ? "Yes" : "No")}");
126+
status.AppendLine($" Paging factor: {PageFactor:#,##0}");
127+
status.AppendLine($" Start time-tag: {m_startTime}");
128+
status.AppendLine($" Stop time-tag: {m_stopTime}");
133129

134-
status.AppendFormat(" OSI-PI server name: {0}\r\n", ServerName);
135-
status.AppendFormat(" Connected to server: {0}\r\n", m_connection is null ? "No" : m_connection.Connected ? "Yes" : "No");
136-
status.AppendFormat(" Paging factor: {0:#,##0}\r\n", PageFactor);
137-
status.AppendFormat(" Start time-tag: {0}\r\n", m_startTime);
138-
status.AppendFormat(" Stop time-tag: {0}\r\n", m_stopTime);
139130
return status.ToString();
140131
}
141132
}
142133

134+
/// <inheritdoc />
143135
protected override bool UseAsyncConnect => false;
144136

145137
#endregion
@@ -152,25 +144,25 @@ public override string Status
152144
/// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
153145
protected override void Dispose(bool disposing)
154146
{
155-
if (!m_disposed)
147+
if (m_disposed)
148+
return;
149+
150+
try
156151
{
157-
try
152+
if (!disposing)
153+
return;
154+
155+
if (m_connection is not null)
158156
{
159-
if (disposing)
160-
{
161-
if (m_connection is not null)
162-
{
163-
m_connection.Dispose();
164-
m_connection = null;
165-
}
166-
}
167-
}
168-
finally
169-
{
170-
m_disposed = true; // Prevent duplicate dispose.
171-
base.Dispose(disposing); // Call base class Dispose().
157+
m_connection.Dispose();
158+
m_connection = null;
172159
}
173160
}
161+
finally
162+
{
163+
m_disposed = true; // Prevent duplicate dispose.
164+
base.Dispose(disposing); // Call base class Dispose().
165+
}
174166
}
175167

176168
/// <summary>
@@ -195,8 +187,6 @@ public override void Initialize()
195187

196188
ConnectTimeout = settings.TryGetValue(nameof(ConnectTimeout), out setting) ? Convert.ToInt32(setting) : PIConnection.DefaultConnectTimeout;
197189

198-
199-
200190
if (settings.TryGetValue(nameof(PageFactor), out setting) && int.TryParse(setting, out int pageFactor) && pageFactor > 0)
201191
PageFactor = pageFactor;
202192
else
@@ -220,15 +210,18 @@ public override string GetShortStatus(int maxLength)
220210
/// </summary>
221211
private void OpenPIConnection()
222212
{
223-
m_connection = new PIConnection
224-
{
225-
ServerName = ServerName,
226-
UserName = UserName,
227-
Password = Password,
228-
ConnectTimeout = ConnectTimeout
229-
};
213+
m_connection = new PIConnection
214+
{
215+
ServerName = ServerName,
216+
UserName = UserName,
217+
Password = Password,
218+
ConnectTimeout = ConnectTimeout
219+
};
220+
221+
string warningMessage = m_connection.Open();
230222

231-
m_connection.Open();
223+
if (!string.IsNullOrEmpty(warningMessage))
224+
OnStatusMessage(MessageLevel.Warning, warningMessage);
232225
}
233226

234227
private IEnumerable<AFValue> ReadData(AFTime startTime, AFTime endTime, PIPointList points, int sampleRate)
@@ -241,15 +234,12 @@ private IEnumerable<AFValue> ReadData(AFTime startTime, AFTime endTime, PIPointL
241234
DataReadExceptionHandler = ex => OnProcessException(MessageLevel.Warning, ex)
242235
};
243236

244-
if (sampleRate <= 0)
245-
return scanner.Read(PageFactor);
246-
else
247-
return scanner.ReadInterpolated(new AFTimeSpan(new TimeSpan(0,0,sampleRate)), PageFactor);
248-
}
237+
return sampleRate <= 0 ? scanner.Read(PageFactor) : scanner.ReadInterpolated(new AFTimeSpan(new TimeSpan(0, 0, sampleRate)), PageFactor);
238+
}
249239

250240

251241
/// <summary>
252-
/// Commnad that reads the PI Buffer for the specified time range and tags.
242+
/// Command that reads the PI Buffer for the specified time range and tags.
253243
/// </summary>
254244
/// <param name="start"> The start Time of the requested data.</param>
255245
/// <param name="end">The end time for the data requested.</param>
@@ -262,7 +252,7 @@ public string ReadBuffer(DateTime start, DateTime end, string tags, int interpol
262252
if (end.Kind == DateTimeKind.Unspecified)
263253
end = DateTime.SpecifyKind(end, DateTimeKind.Utc);
264254

265-
string[] tagArray = tags.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
255+
string[] tagArray = tags.Split([';'], StringSplitOptions.RemoveEmptyEntries);
266256

267257
if (!Enabled || m_connection is null || tagArray.Length == 0)
268258
{
@@ -281,10 +271,9 @@ public string ReadBuffer(DateTime start, DateTime end, string tags, int interpol
281271

282272
foreach (string tag in tagArray)
283273
{
284-
285274
if (PIPoint.TryFindPIPoint(m_connection.Server, tag, out PIPoint point))
286275
{
287-
tagList.Add(tag, new List<Tuple<long, double>>());
276+
tagList.Add(tag, []);
288277
points.Add(point);
289278
}
290279
}
@@ -308,24 +297,24 @@ public string ReadBuffer(DateTime start, DateTime end, string tags, int interpol
308297
throw new NullReferenceException("PI data read returned a null value.");
309298

310299
long timestamp = currentPoint.Timestamp.UtcTime.Ticks;
311-
double Value = Convert.ToDouble(currentPoint.Value);
300+
double value = Convert.ToDouble(currentPoint.Value);
312301

313302
if (tagList.ContainsKey(currentPoint.PIPoint.Name))
314303
{
315-
tagList[currentPoint.PIPoint.Name].Add(Tuple.Create(timestamp, Value));
304+
tagList[currentPoint.PIPoint.Name].Add(Tuple.Create(timestamp, value));
316305
}
317306
}
318307

319308
return string.Join(Environment.NewLine,
320309
tagList.Select(item => $"{item.Key}:{string.Join(";", item.Value.Select(v => $"{v.Item2},{v.Item1}"))}"));
321310
}
322311

323-
312+
324313
/// <inheritdoc/>
325-
protected override void AttemptConnection() {}
314+
protected override void AttemptConnection() { }
326315

327316
/// <inheritdoc/>
328-
protected override void AttemptDisconnection() {}
317+
protected override void AttemptDisconnection() { }
329318

330319
#endregion
331320
}

Source/Libraries/Adapters/PIAdapters/PIConnection.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,17 @@ protected virtual void Dispose(bool disposing)
142142
/// <summary>
143143
/// Attempts to open <see cref="PIConnection"/>.
144144
/// </summary>
145-
public void Open()
145+
/// <remarks>
146+
/// Returns warning messages related to opening connection; otherwise, <c>null</c> if there are no warnings.
147+
/// </remarks>
148+
/// <exception cref="InvalidOperationException">
149+
/// Connection is already open, <see cref="ServerName"/> is not defined, server not found in PI servers collection,
150+
/// or failed to connect to PI server.
151+
/// </exception>
152+
public string Open()
146153
{
154+
string warningMessage = null;
155+
147156
if (m_connected || (Server is not null && Server.ConnectionInfo.IsConnected))
148157
throw new InvalidOperationException("OSI-PI server connection is already open.");
149158

@@ -162,7 +171,12 @@ public void Open()
162171
throw new InvalidOperationException("Server not found in the PI servers collection.");
163172

164173
if (ConnectTimeout > 0)
165-
Server.ConnectionInfo.ConnectionTimeOut = TimeSpan.FromMilliseconds(ConnectTimeout);
174+
{
175+
if (Server.Collective is null)
176+
Server.ConnectionInfo.ConnectionTimeOut = TimeSpan.FromMilliseconds(ConnectTimeout);
177+
else
178+
warningMessage = "Cannot change connect timeout when connecting to PI collective";
179+
}
166180

167181
Server.ConnectChanged += PIConnection_ConnectChanged;
168182
}
@@ -181,6 +195,8 @@ public void Open()
181195
}
182196

183197
m_connected = true;
198+
199+
return warningMessage;
184200
}
185201

186202
/// <summary>

Source/Libraries/Adapters/PIAdapters/PIOutputAdapter.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1689,7 +1689,11 @@ protected override void AttemptConnection()
16891689
};
16901690

16911691
m_connection.Disconnected += Connection_Disconnected;
1692-
m_connection.Open();
1692+
1693+
string warningMessage = m_connection.Open();
1694+
1695+
if (!string.IsNullOrEmpty(warningMessage))
1696+
OnStatusMessage(MessageLevel.Warning, warningMessage);
16931697

16941698
m_mappedPIPoints.Clear();
16951699

Source/Libraries/Adapters/PIAdapters/PIPBInputAdapter.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,10 @@ protected override void AttemptConnection()
402402
ConnectTimeout = ConnectTimeout
403403
};
404404

405-
m_connection.Open();
405+
string warningMessage = m_connection.Open();
406+
407+
if (!string.IsNullOrEmpty(warningMessage))
408+
OnStatusMessage(MessageLevel.Warning, warningMessage);
406409

407410
// Start the data reader on its own thread so connection attempt can complete in a timely fashion...
408411
ThreadPool.QueueUserWorkItem(StartDataReader);

Source/Libraries/Adapters/PIAdapters/PIRTInputAdapter.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,11 @@ protected override void AttemptConnection()
286286
};
287287

288288
m_connection.Disconnected += m_connection_Disconnected;
289-
m_connection.Open();
289+
290+
string warningMessage = m_connection.Open();
291+
292+
if (!string.IsNullOrEmpty(warningMessage))
293+
OnStatusMessage(MessageLevel.Warning, warningMessage);
290294

291295
m_dataPipe = new PIDataPipe(AFDataPipeType.Snapshot);
292296
m_dataPipe.Subscribe(m_dataUpdateObserver);
@@ -465,7 +469,7 @@ private void m_dataUpdateObserver_DataUpdated(object sender, EventArgs<AFValue>
465469
Timestamp = value.Timestamp.UtcTime
466470
};
467471

468-
OnNewMeasurements(new[] { measurement });
472+
OnNewMeasurements([measurement]);
469473

470474
m_lastReceivedTimestamp = measurement.Timestamp;
471475
m_lastReceivedValue = measurement.Value;

0 commit comments

Comments
 (0)