FilterDefinition.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using Opc.Ua;
  5. using Opc.Ua.Client;
  6. namespace IMCS_CCS.Utils.DeviceProtocol
  7. {
  8. public class FilterDefinition
  9. {
  10. public NodeId AreaId;
  11. public EventSeverity Severity;
  12. public IList<NodeId> EventTypes;
  13. public bool IgnoreSuppressedOrShelved;
  14. public SimpleAttributeOperandCollection SelectClauses;
  15. public MonitoredItem CreateMonitoredItem(Session session)
  16. {
  17. if (this.AreaId == (object)null)
  18. this.AreaId = ObjectIds.Server;
  19. return new MonitoredItem()
  20. {
  21. DisplayName = (string)null,
  22. StartNodeId = this.AreaId,
  23. RelativePath = (string)null,
  24. NodeClass = NodeClass.Object,
  25. AttributeId = 12,
  26. IndexRange = (string)null,
  27. Encoding = (QualifiedName)null,
  28. MonitoringMode = MonitoringMode.Reporting,
  29. SamplingInterval = 0,
  30. QueueSize = uint.MaxValue,
  31. DiscardOldest = true,
  32. Filter = (MonitoringFilter)this.ConstructFilter(session),
  33. Handle = (object)this
  34. };
  35. }
  36. public SimpleAttributeOperandCollection ConstructSelectClauses(
  37. Session session,
  38. params NodeId[] eventTypeIds)
  39. {
  40. SimpleAttributeOperandCollection eventFields = new SimpleAttributeOperandCollection();
  41. eventFields.Add(new SimpleAttributeOperand()
  42. {
  43. TypeDefinitionId = ObjectTypeIds.BaseEventType,
  44. AttributeId = 1U,
  45. BrowsePath = new QualifiedNameCollection()
  46. });
  47. if (eventTypeIds != null)
  48. {
  49. for (int index = 0; index < eventTypeIds.Length; ++index)
  50. this.CollectFields(session, eventTypeIds[index], eventFields);
  51. }
  52. else
  53. this.CollectFields(session, ObjectTypeIds.BaseEventType, eventFields);
  54. return eventFields;
  55. }
  56. public EventFilter ConstructFilter(Session session)
  57. {
  58. EventFilter eventFilter = new EventFilter();
  59. eventFilter.SelectClauses = this.SelectClauses;
  60. ContentFilter contentFilter = new ContentFilter();
  61. ContentFilterElement contentFilterElement1 = (ContentFilterElement)null;
  62. if (this.Severity > EventSeverity.Min)
  63. {
  64. SimpleAttributeOperand attributeOperand = new SimpleAttributeOperand();
  65. attributeOperand.TypeDefinitionId = ObjectTypeIds.BaseEventType;
  66. attributeOperand.BrowsePath.Add((QualifiedName)"Severity");
  67. attributeOperand.AttributeId = 13U;
  68. contentFilterElement1 = contentFilter.Push(FilterOperator.GreaterThanOrEqual, (object)attributeOperand, (object)new LiteralOperand()
  69. {
  70. Value = new Variant((ushort)this.Severity)
  71. });
  72. }
  73. if (!this.IgnoreSuppressedOrShelved)
  74. {
  75. SimpleAttributeOperand attributeOperand = new SimpleAttributeOperand();
  76. attributeOperand.TypeDefinitionId = ObjectTypeIds.BaseEventType;
  77. attributeOperand.BrowsePath.Add((QualifiedName)"SuppressedOrShelved");
  78. attributeOperand.AttributeId = 13U;
  79. ContentFilterElement contentFilterElement2 = contentFilter.Push(FilterOperator.Equals, (object)attributeOperand, (object)new LiteralOperand()
  80. {
  81. Value = new Variant(false)
  82. });
  83. if (contentFilterElement1 != null)
  84. contentFilterElement1 = contentFilter.Push(FilterOperator.And, (object)contentFilterElement1, (object)contentFilterElement2);
  85. else
  86. contentFilterElement1 = contentFilterElement2;
  87. }
  88. if (this.EventTypes != null && this.EventTypes.Count > 0)
  89. {
  90. ContentFilterElement contentFilterElement2 = (ContentFilterElement)null;
  91. for (int index = 0; index < this.EventTypes.Count; ++index)
  92. {
  93. ContentFilterElement contentFilterElement3 = contentFilter.Push(FilterOperator.OfType, (object)new LiteralOperand()
  94. {
  95. Value = new Variant(this.EventTypes[index])
  96. });
  97. if (contentFilterElement2 != null)
  98. contentFilterElement2 = contentFilter.Push(FilterOperator.Or, (object)contentFilterElement2, (object)contentFilterElement3);
  99. else
  100. contentFilterElement2 = contentFilterElement3;
  101. }
  102. if (contentFilterElement1 != null)
  103. contentFilter.Push(FilterOperator.And, (object)contentFilterElement1, (object)contentFilterElement2);
  104. }
  105. eventFilter.WhereClause = contentFilter;
  106. return eventFilter;
  107. }
  108. private void CollectFields(
  109. Session session,
  110. NodeId eventTypeId,
  111. SimpleAttributeOperandCollection eventFields)
  112. {
  113. ReferenceDescriptionCollection descriptionCollection = FormUtils.BrowseSuperTypes(session, eventTypeId, false);
  114. if (descriptionCollection == null)
  115. return;
  116. Dictionary<NodeId, QualifiedNameCollection> foundNodes = new Dictionary<NodeId, QualifiedNameCollection>();
  117. QualifiedNameCollection parentPath = new QualifiedNameCollection();
  118. for (int index = descriptionCollection.Count - 1; index >= 0; --index)
  119. this.CollectFields(session, (NodeId)descriptionCollection[index].NodeId, parentPath, eventFields, foundNodes);
  120. this.CollectFields(session, eventTypeId, parentPath, eventFields, foundNodes);
  121. }
  122. private void CollectFields(
  123. Session session,
  124. NodeId nodeId,
  125. QualifiedNameCollection parentPath,
  126. SimpleAttributeOperandCollection eventFields,
  127. Dictionary<NodeId, QualifiedNameCollection> foundNodes)
  128. {
  129. ReferenceDescriptionCollection descriptionCollection = FormUtils.Browse(session, new BrowseDescription()
  130. {
  131. NodeId = nodeId,
  132. BrowseDirection = BrowseDirection.Forward,
  133. ReferenceTypeId = ReferenceTypeIds.Aggregates,
  134. IncludeSubtypes = true,
  135. NodeClassMask = 3U,
  136. ResultMask = 63U
  137. }, false);
  138. if (descriptionCollection == null)
  139. return;
  140. for (int index = 0; index < descriptionCollection.Count; ++index)
  141. {
  142. ReferenceDescription referenceDescription = descriptionCollection[index];
  143. if (!referenceDescription.NodeId.IsAbsolute)
  144. {
  145. QualifiedNameCollection qualifiedNameCollection = new QualifiedNameCollection((IEnumerable<QualifiedName>)parentPath);
  146. qualifiedNameCollection.Add(referenceDescription.BrowseName);
  147. if (!this.ContainsPath(eventFields, qualifiedNameCollection))
  148. eventFields.Add(new SimpleAttributeOperand()
  149. {
  150. TypeDefinitionId = ObjectTypeIds.BaseEventType,
  151. BrowsePath = qualifiedNameCollection,
  152. AttributeId = referenceDescription.NodeClass == NodeClass.Variable ? 13U : 1U
  153. });
  154. NodeId nodeId1 = (NodeId)referenceDescription.NodeId;
  155. if (!foundNodes.ContainsKey(nodeId1))
  156. {
  157. foundNodes.Add(nodeId1, qualifiedNameCollection);
  158. this.CollectFields(session, (NodeId)referenceDescription.NodeId, qualifiedNameCollection, eventFields, foundNodes);
  159. }
  160. }
  161. }
  162. }
  163. private bool ContainsPath(
  164. SimpleAttributeOperandCollection selectClause,
  165. QualifiedNameCollection browsePath)
  166. {
  167. for (int index1 = 0; index1 < selectClause.Count; ++index1)
  168. {
  169. SimpleAttributeOperand attributeOperand = selectClause[index1];
  170. if (attributeOperand.BrowsePath.Count == browsePath.Count)
  171. {
  172. bool flag = true;
  173. for (int index2 = 0; index2 < attributeOperand.BrowsePath.Count; ++index2)
  174. {
  175. if (attributeOperand.BrowsePath[index2] != browsePath[index2])
  176. {
  177. flag = false;
  178. break;
  179. }
  180. }
  181. if (flag)
  182. return true;
  183. }
  184. }
  185. return false;
  186. }
  187. }
  188. public static class FormUtils
  189. {
  190. public static NodeId[] KnownEventTypes = new NodeId[8]
  191. {
  192. ObjectTypeIds.BaseEventType,
  193. ObjectTypeIds.ConditionType,
  194. ObjectTypeIds.DialogConditionType,
  195. ObjectTypeIds.AlarmConditionType,
  196. ObjectTypeIds.ExclusiveLimitAlarmType,
  197. ObjectTypeIds.NonExclusiveLimitAlarmType,
  198. ObjectTypeIds.AuditEventType,
  199. ObjectTypeIds.AuditUpdateMethodEventType
  200. };
  201. public static EndpointDescription SelectEndpoint(
  202. string discoveryUrl,
  203. bool useSecurity)
  204. {
  205. if (!discoveryUrl.StartsWith("opc.tcp") && !discoveryUrl.EndsWith("/discovery"))
  206. discoveryUrl += "/discovery";
  207. Uri discoveryUrl1 = new Uri(discoveryUrl);
  208. EndpointConfiguration configuration = EndpointConfiguration.Create();
  209. configuration.OperationTimeout = 5000;
  210. EndpointDescription endpointDescription1 = (EndpointDescription)null;
  211. using (DiscoveryClient discoveryClient = DiscoveryClient.Create(discoveryUrl1, configuration))
  212. {
  213. EndpointDescriptionCollection endpoints = discoveryClient.GetEndpoints((StringCollection)null);
  214. for (int index = 0; index < endpoints.Count; ++index)
  215. {
  216. EndpointDescription endpointDescription2 = endpoints[index];
  217. if (endpointDescription2.EndpointUrl.StartsWith(discoveryUrl1.Scheme))
  218. {
  219. if (endpointDescription1 == null)
  220. endpointDescription1 = endpointDescription2;
  221. if (useSecurity)
  222. {
  223. if (endpointDescription2.SecurityMode != MessageSecurityMode.None && (int)endpointDescription2.SecurityLevel > (int)endpointDescription1.SecurityLevel)
  224. endpointDescription1 = endpointDescription2;
  225. }
  226. else if (endpointDescription2.SecurityMode == MessageSecurityMode.None)
  227. endpointDescription1 = endpointDescription2;
  228. }
  229. if (endpointDescription1 == null && endpoints.Count > 0)
  230. endpointDescription1 = endpoints[0];
  231. }
  232. }
  233. Uri uri = Opc.Ua.Utils.ParseUri(endpointDescription1.EndpointUrl);
  234. if (uri != (Uri)null && uri.Scheme == discoveryUrl1.Scheme)
  235. endpointDescription1.EndpointUrl = new UriBuilder(uri)
  236. {
  237. Host = discoveryUrl1.DnsSafeHost,
  238. Port = discoveryUrl1.Port
  239. }.ToString();
  240. return endpointDescription1;
  241. }
  242. public static NodeId FindEventType(
  243. MonitoredItem monitoredItem,
  244. EventFieldList notification)
  245. {
  246. EventFilter filter = monitoredItem.Status.Filter as EventFilter;
  247. if (filter != null)
  248. {
  249. for (int index = 0; index < filter.SelectClauses.Count; ++index)
  250. {
  251. SimpleAttributeOperand selectClause = filter.SelectClauses[index];
  252. if (selectClause.BrowsePath.Count == 1 && selectClause.BrowsePath[0] == (QualifiedName)"EventType")
  253. return notification.EventFields[index].Value as NodeId;
  254. }
  255. }
  256. return (NodeId)null;
  257. }
  258. public static BaseEventState ConstructEvent(
  259. Session session,
  260. MonitoredItem monitoredItem,
  261. EventFieldList notification,
  262. Dictionary<NodeId, NodeId> eventTypeMappings)
  263. {
  264. NodeId eventType = FormUtils.FindEventType(monitoredItem, notification);
  265. if (eventType == (object)null)
  266. return (BaseEventState)null;
  267. NodeId nodeId = (NodeId)null;
  268. if (!eventTypeMappings.TryGetValue(eventType, out nodeId))
  269. {
  270. for (int index = 0; index < FormUtils.KnownEventTypes.Length; ++index)
  271. {
  272. if (FormUtils.KnownEventTypes[index] == (object)eventType)
  273. {
  274. nodeId = eventType;
  275. eventTypeMappings.Add(eventType, eventType);
  276. break;
  277. }
  278. }
  279. if (nodeId == (object)null)
  280. {
  281. ReferenceDescriptionCollection descriptionCollection = FormUtils.BrowseSuperTypes(session, eventType, false);
  282. if (descriptionCollection == null)
  283. return (BaseEventState)null;
  284. for (int index1 = 0; index1 < descriptionCollection.Count; ++index1)
  285. {
  286. for (int index2 = 0; index2 < FormUtils.KnownEventTypes.Length; ++index2)
  287. {
  288. if (FormUtils.KnownEventTypes[index2] == (object)descriptionCollection[index1].NodeId)
  289. {
  290. nodeId = FormUtils.KnownEventTypes[index2];
  291. eventTypeMappings.Add(eventType, nodeId);
  292. break;
  293. }
  294. }
  295. if (nodeId != (object)null)
  296. break;
  297. }
  298. }
  299. }
  300. if (nodeId == (object)null)
  301. return (BaseEventState)null;
  302. uint? identifier = nodeId.Identifier as uint?;
  303. if (!identifier.HasValue)
  304. return (BaseEventState)null;
  305. BaseEventState baseEventState;
  306. switch (identifier.Value)
  307. {
  308. case 2052:
  309. baseEventState = (BaseEventState)new AuditEventState((NodeState)null);
  310. break;
  311. case 2127:
  312. baseEventState = (BaseEventState)new AuditUpdateMethodEventState((NodeState)null);
  313. break;
  314. case 2782:
  315. baseEventState = (BaseEventState)new ConditionState((NodeState)null);
  316. break;
  317. case 2830:
  318. baseEventState = (BaseEventState)new DialogConditionState((NodeState)null);
  319. break;
  320. case 2915:
  321. baseEventState = (BaseEventState)new AlarmConditionState((NodeState)null);
  322. break;
  323. case 9341:
  324. baseEventState = (BaseEventState)new ExclusiveLimitAlarmState((NodeState)null);
  325. break;
  326. case 9906:
  327. baseEventState = (BaseEventState)new NonExclusiveLimitAlarmState((NodeState)null);
  328. break;
  329. default:
  330. baseEventState = new BaseEventState((NodeState)null);
  331. break;
  332. }
  333. EventFilter filter = monitoredItem.Status.Filter as EventFilter;
  334. baseEventState.Update(session.SystemContext, filter.SelectClauses, notification);
  335. baseEventState.Handle = (object)notification;
  336. return baseEventState;
  337. }
  338. public static ReferenceDescriptionCollection Browse(
  339. Session session,
  340. BrowseDescription nodeToBrowse,
  341. bool throwOnError)
  342. {
  343. try
  344. {
  345. ReferenceDescriptionCollection descriptionCollection = new ReferenceDescriptionCollection();
  346. BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
  347. nodesToBrowse.Add(nodeToBrowse);
  348. BrowseResultCollection results = (BrowseResultCollection)null;
  349. DiagnosticInfoCollection diagnosticInfos = (DiagnosticInfoCollection)null;
  350. session.Browse((RequestHeader)null, (ViewDescription)null, 0U, nodesToBrowse, out results, out diagnosticInfos);
  351. ClientBase.ValidateResponse((IList)results, (IList)nodesToBrowse);
  352. ClientBase.ValidateDiagnosticInfos(diagnosticInfos, (IList)nodesToBrowse);
  353. while (!StatusCode.IsBad(results[0].StatusCode))
  354. {
  355. for (int index = 0; index < results[0].References.Count; ++index)
  356. descriptionCollection.Add(results[0].References[index]);
  357. if (results[0].References.Count == 0 || results[0].ContinuationPoint == null)
  358. return descriptionCollection;
  359. ByteStringCollection continuationPoints = new ByteStringCollection();
  360. continuationPoints.Add(results[0].ContinuationPoint);
  361. session.BrowseNext((RequestHeader)null, false, continuationPoints, out results, out diagnosticInfos);
  362. ClientBase.ValidateResponse((IList)results, (IList)continuationPoints);
  363. ClientBase.ValidateDiagnosticInfos(diagnosticInfos, (IList)continuationPoints);
  364. }
  365. throw new ServiceResultException((ServiceResult)results[0].StatusCode);
  366. }
  367. catch (Exception ex)
  368. {
  369. if (throwOnError)
  370. throw new ServiceResultException(ex, 2147549184U);
  371. return (ReferenceDescriptionCollection)null;
  372. }
  373. }
  374. public static ReferenceDescriptionCollection BrowseSuperTypes(
  375. Session session,
  376. NodeId typeId,
  377. bool throwOnError)
  378. {
  379. ReferenceDescriptionCollection descriptionCollection1 = new ReferenceDescriptionCollection();
  380. try
  381. {
  382. BrowseDescription nodeToBrowse = new BrowseDescription();
  383. nodeToBrowse.NodeId = typeId;
  384. nodeToBrowse.BrowseDirection = BrowseDirection.Inverse;
  385. nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.HasSubtype;
  386. nodeToBrowse.IncludeSubtypes = false;
  387. nodeToBrowse.NodeClassMask = 0U;
  388. nodeToBrowse.ResultMask = 63U;
  389. for (ReferenceDescriptionCollection descriptionCollection2 = FormUtils.Browse(session, nodeToBrowse, throwOnError); descriptionCollection2 != null && descriptionCollection2.Count > 0; descriptionCollection2 = FormUtils.Browse(session, nodeToBrowse, throwOnError))
  390. {
  391. descriptionCollection1.Add(descriptionCollection2[0]);
  392. if (!descriptionCollection2[0].NodeId.IsAbsolute)
  393. nodeToBrowse.NodeId = (NodeId)descriptionCollection2[0].NodeId;
  394. else
  395. break;
  396. }
  397. return descriptionCollection1;
  398. }
  399. catch (Exception ex)
  400. {
  401. if (throwOnError)
  402. throw new ServiceResultException(ex, 2147549184U);
  403. return (ReferenceDescriptionCollection)null;
  404. }
  405. }
  406. }
  407. }