PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/Releases/v1.4sp2/Synchrophasor/Current Version/Source/Libraries/TVA.PhasorProtocols/CalculatedMeasurementBase.cs

#
C# | 322 lines | 175 code | 38 blank | 109 comment | 16 complexity | d78af0c8f138a690781dac4d1d14e47c MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, EPL-1.0
  1. //******************************************************************************************************
  2. // CalculatedMeasurementBase.cs - 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. // 10/19/2009 - J. Ritchie Carroll
  20. // Generated original version of source code.
  21. // 04/21/2010 - J. Ritchie Carroll
  22. // Added signal type summary to the calculated measurement status.
  23. //
  24. //******************************************************************************************************
  25. using System;
  26. using System.Collections.Generic;
  27. using System.Data;
  28. using System.Linq;
  29. using System.Text;
  30. using TimeSeriesFramework;
  31. using TimeSeriesFramework.Adapters;
  32. namespace TVA.PhasorProtocols
  33. {
  34. #region [ Enumerations ]
  35. /// <summary>
  36. /// Signal type enumeration.
  37. /// </summary>
  38. /// <remarks>
  39. /// <para>
  40. /// The signal type represents the explicit type of a signal that a value represents.
  41. /// </para>
  42. /// <para>
  43. /// Contrast the <see cref="SignalType"/> enumeration with the <see cref="SignalKind"/>
  44. /// enumeration which defines an abstract type for a signal (e.g., simply phase or angle).
  45. /// </para>
  46. /// </remarks>
  47. [Serializable()]
  48. public enum SignalType
  49. {
  50. /// <summary>
  51. /// Current phase magnitude.
  52. /// </summary>
  53. IPHM = 1,
  54. /// <summary>
  55. /// Current phase angle.
  56. /// </summary>
  57. IPHA = 2,
  58. /// <summary>
  59. /// Voltage phase magnitude.
  60. /// </summary>
  61. VPHM = 3,
  62. /// <summary>
  63. /// Voltage phase angle.
  64. /// </summary>
  65. VPHA = 4,
  66. /// <summary>
  67. /// Frequency.
  68. /// </summary>
  69. FREQ = 5,
  70. /// <summary>
  71. /// Frequency delta (dF/dt).
  72. /// </summary>
  73. DFDT = 6,
  74. /// <summary>
  75. /// Analog value.
  76. /// </summary>
  77. ALOG = 7,
  78. /// <summary>
  79. /// Status flags.
  80. /// </summary>
  81. FLAG = 8,
  82. /// <summary>
  83. /// Digital value.
  84. /// </summary>
  85. DIGI = 9,
  86. /// <summary>
  87. /// Calculated value.
  88. /// </summary>
  89. CALC = 10,
  90. /// <summary>
  91. /// Statistical value.
  92. /// </summary>
  93. STAT = 11,
  94. /// <summary>
  95. /// Undefined signal.
  96. /// </summary>
  97. NONE = -1
  98. }
  99. #endregion
  100. /// <summary>
  101. /// Represents the base class for calculated measurements that use phasor data.
  102. /// </summary>
  103. /// <remarks>
  104. /// This base class extends <see cref="ActionAdapterBase"/> by automatically looking up the
  105. /// <see cref="SignalType"/> for each of the input and output measurements.
  106. /// </remarks>
  107. public abstract class CalculatedMeasurementBase : ActionAdapterBase
  108. {
  109. #region [ Members ]
  110. // Fields
  111. private SignalType[] m_inputMeasurementKeyTypes;
  112. private SignalType[] m_outputMeasurementTypes;
  113. private string m_configurationSection;
  114. private bool m_supportsTemporalProcessing;
  115. #endregion
  116. #region [ Properties ]
  117. /// <summary>
  118. /// Gets or sets primary keys of input measurements the calculated measurement expects.
  119. /// </summary>
  120. public override MeasurementKey[] InputMeasurementKeys
  121. {
  122. get
  123. {
  124. return base.InputMeasurementKeys;
  125. }
  126. set
  127. {
  128. base.InputMeasurementKeys = value;
  129. m_inputMeasurementKeyTypes = new SignalType[value.Length];
  130. for (int i = 0; i < m_inputMeasurementKeyTypes.Length; i++)
  131. {
  132. m_inputMeasurementKeyTypes[i] = LookupSignalType(value[i]);
  133. }
  134. }
  135. }
  136. /// <summary>
  137. /// Gets or sets output measurements that the calculated measurement will produce, if any.
  138. /// </summary>
  139. public override IMeasurement[] OutputMeasurements
  140. {
  141. get
  142. {
  143. return base.OutputMeasurements;
  144. }
  145. set
  146. {
  147. base.OutputMeasurements = value;
  148. m_outputMeasurementTypes = new SignalType[value.Length];
  149. for (int i = 0; i < m_outputMeasurementTypes.Length; i++)
  150. {
  151. m_outputMeasurementTypes[i] = LookupSignalType(value[i].Key);
  152. }
  153. }
  154. }
  155. /// <summary>
  156. /// Gets or sets input measurement <see cref="SignalType"/>'s for each of the <see cref="ActionAdapterBase.InputMeasurementKeys"/>, if any.
  157. /// </summary>
  158. public virtual SignalType[] InputMeasurementKeyTypes
  159. {
  160. get
  161. {
  162. return m_inputMeasurementKeyTypes;
  163. }
  164. }
  165. /// <summary>
  166. /// Gets or sets output measurement <see cref="SignalType"/>'s for each of the <see cref="ActionAdapterBase.OutputMeasurements"/>, if any.
  167. /// </summary>
  168. public virtual SignalType[] OutputMeasurementTypes
  169. {
  170. get
  171. {
  172. return m_outputMeasurementTypes;
  173. }
  174. }
  175. /// <summary>
  176. /// Gets or sets the configuration section to use for this <see cref="CalculatedMeasurementBase"/>.
  177. /// </summary>
  178. public virtual string ConfigurationSection
  179. {
  180. get
  181. {
  182. return m_configurationSection;
  183. }
  184. set
  185. {
  186. m_configurationSection = value;
  187. }
  188. }
  189. /// <summary>
  190. /// Gets the flag indicating if this adapter supports temporal processing.
  191. /// </summary>
  192. public override bool SupportsTemporalProcessing
  193. {
  194. get
  195. {
  196. return m_supportsTemporalProcessing;
  197. }
  198. }
  199. /// <summary>
  200. /// Returns the detailed status of the calculated measurement.
  201. /// </summary>
  202. /// <remarks>
  203. /// Derived classes should extend status with implementation specific information.
  204. /// </remarks>
  205. public override string Status
  206. {
  207. get
  208. {
  209. StringBuilder status = new StringBuilder();
  210. int count;
  211. status.AppendFormat(" Configuration section: {0}", ConfigurationSection);
  212. status.AppendLine();
  213. status.Append(base.Status);
  214. if (OutputMeasurements != null && OutputMeasurements.Length > 0)
  215. {
  216. status.AppendLine();
  217. status.AppendLine("Output measurements signal type summary:");
  218. status.AppendLine();
  219. foreach (SignalType signalType in Enum.GetValues(typeof(SignalType)))
  220. {
  221. count = OutputMeasurements.Where((key, index) => OutputMeasurementTypes[index] == signalType).Count();
  222. if (count > 0)
  223. {
  224. status.AppendFormat("{0} {1} signal{2}", count.ToString().PadLeft(15), signalType.GetFormattedSignalTypeName(), count > 1 ? "s" : "");
  225. status.AppendLine();
  226. }
  227. }
  228. }
  229. if (InputMeasurementKeys != null && InputMeasurementKeys.Length > 0)
  230. {
  231. status.AppendLine();
  232. status.AppendLine("Input measurement keys signal type summary:");
  233. status.AppendLine();
  234. foreach (SignalType signalType in Enum.GetValues(typeof(SignalType)))
  235. {
  236. count = InputMeasurementKeys.Where((key, index) => InputMeasurementKeyTypes[index] == signalType).Count();
  237. if (count > 0)
  238. {
  239. status.AppendFormat("{0} {1} signal{2}", count.ToString().PadLeft(15), signalType.GetFormattedSignalTypeName(), count > 1 ? "s" : "");
  240. status.AppendLine();
  241. }
  242. }
  243. }
  244. return status.ToString();
  245. }
  246. }
  247. #endregion
  248. #region [ Methods ]
  249. /// <summary>
  250. /// Intializes <see cref="CalculatedMeasurementBase"/>.
  251. /// </summary>
  252. public override void Initialize()
  253. {
  254. base.Initialize();
  255. Dictionary<string, string> settings = Settings;
  256. string setting;
  257. // Load optional parameters
  258. if (!settings.TryGetValue("configurationSection", out m_configurationSection))
  259. m_configurationSection = Name;
  260. if (string.IsNullOrEmpty(m_configurationSection))
  261. m_configurationSection = Name;
  262. if (settings.TryGetValue("supportsTemporalProcessing", out setting))
  263. m_supportsTemporalProcessing = setting.ParseBoolean();
  264. else
  265. m_supportsTemporalProcessing = false;
  266. }
  267. // Lookup signal type for given measurement key
  268. private SignalType LookupSignalType(MeasurementKey key)
  269. {
  270. try
  271. {
  272. DataRow[] filteredRows = DataSource.Tables["ActiveMeasurements"].Select(string.Format("ID = '{0}'", key.ToString()));
  273. if (filteredRows.Length > 0)
  274. return (SignalType)Enum.Parse(typeof(SignalType), filteredRows[0]["SignalType"].ToString(), true);
  275. }
  276. catch (Exception ex)
  277. {
  278. OnProcessException(new InvalidOperationException(string.Format("Failed to lookup signal type for measurement {0}: {1}", key.ToString(), ex.Message), ex));
  279. }
  280. return SignalType.NONE;
  281. }
  282. #endregion
  283. }
  284. }