XMLNodeManager.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /******************************************************************************
  2. ** Copyright (c) 2006-2018 Unified Automation GmbH All rights reserved.
  3. **
  4. ** Software License Agreement ("SLA") Version 2.7
  5. **
  6. ** Unless explicitly acquired and licensed from Licensor under another
  7. ** license, the contents of this file are subject to the Software License
  8. ** Agreement ("SLA") Version 2.7, or subsequent versions
  9. ** as allowed by the SLA, and You may not copy or use this file in either
  10. ** source code or executable form, except in compliance with the terms and
  11. ** conditions of the SLA.
  12. **
  13. ** All software distributed under the SLA is provided strictly on an
  14. ** "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  15. ** AND LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
  16. ** LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  17. ** PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the SLA for specific
  18. ** language governing rights and limitations under the SLA.
  19. **
  20. ** Project: .NET based OPC UA Client Server SDK
  21. **
  22. ** Description: OPC Unified Architecture Software Development Kit.
  23. **
  24. ** The complete license agreement can be found here:
  25. ** http://unifiedautomation.com/License/SLA/2.7/
  26. ******************************************************************************/
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Linq;
  30. using System.Text;
  31. using System.Threading;
  32. using System.IO;
  33. using System.Reflection;
  34. using UnifiedAutomation.UaBase;
  35. using UnifiedAutomation.UaServer;
  36. namespace acdp
  37. {
  38. internal class XMLNodeManager : BaseNodeManager
  39. {
  40. /// <summary>
  41. /// Gets or sets the index of the instance namespace.
  42. /// </summary>
  43. /// <value>
  44. /// The index of the instance namespace.
  45. /// </value>
  46. public ushort InstanceNamespaceIndex { get; set; }
  47. /// <summary>
  48. /// Gets or sets the index of the type namespace.
  49. /// </summary>
  50. /// <value>
  51. /// The index of the type namespace.
  52. /// </value>
  53. public ushort TypeNamespaceIndex { get; set; }
  54. /// <summary>
  55. /// Called when the node manager is started.
  56. /// </summary>
  57. public override void Startup()
  58. {
  59. try
  60. {
  61. Console.WriteLine("Starting XMLNodeManager.");
  62. base.Startup();
  63. // save the namespaces used by this node manager.
  64. InstanceNamespaceIndex = AddNamespaceUri("http://www.acdp.at/DI_test/");
  65. TypeNamespaceIndex = AddNamespaceUri("http://www.acdp.at/DI_test/");
  66. // load the model.
  67. Console.WriteLine("Loading XML Models.");
  68. ImportUaNodeset(new FileInfo("../../Model/Opc.Ua.Di.NodeSet2.xml"));
  69. ImportUaNodeset(new FileInfo("../../Model/di_test.xml"));
  70. // initialize the underlying system.
  71. //m_system.Initialize();
  72. SetVariableConfiguration(new NodeId(6010, 2), NodeHandleType.ExternalPush, null);
  73. /*
  74. // Create a Folder for Controllers
  75. CreateObjectSettings settings = new CreateObjectSettings()
  76. {
  77. ParentNodeId = ObjectIds.ObjectsFolder,
  78. ReferenceTypeId = ReferenceTypeIds.Organizes,
  79. RequestedNodeId = new NodeId("Controllers", InstanceNamespaceIndex),
  80. BrowseName = new QualifiedName("Controllers", InstanceNamespaceIndex),
  81. TypeDefinitionId = ObjectTypeIds.FolderType
  82. };
  83. CreateObject(Server.DefaultRequestContext, settings);
  84. // Create controllers from configuration
  85. foreach (BlockConfiguration block in m_system.GetBlocks())
  86. {
  87. // set type definition NodeId
  88. NodeId typeDefinitionId = ObjectTypeIds.BaseObjectType;
  89. if (block.Type == BlockType.AirConditioner)
  90. {
  91. typeDefinitionId = new NodeId(yourorganisation.BA.ObjectTypes.AirConditionerControllerType, TypeNamespaceIndex);
  92. }
  93. else if (block.Type == BlockType.Furnace)
  94. {
  95. typeDefinitionId = new NodeId(yourorganisation.BA.ObjectTypes.FurnaceControllerType, TypeNamespaceIndex);
  96. }
  97. // create object.
  98. settings = new CreateObjectSettings()
  99. {
  100. ParentNodeId = new NodeId("Controllers", InstanceNamespaceIndex),
  101. ReferenceTypeId = ReferenceTypeIds.Organizes,
  102. RequestedNodeId = new NodeId(block.Name, InstanceNamespaceIndex),
  103. BrowseName = new QualifiedName(block.Name, TypeNamespaceIndex),
  104. TypeDefinitionId = typeDefinitionId
  105. };
  106. CreateObject(Server.DefaultRequestContext, settings);
  107. /// [Snippet EURange]
  108. // Set NodeHandleType to ExternalPolled
  109. foreach (BlockProperty property in block.Properties)
  110. {
  111. // the node was already created when the controller object was instantiated.
  112. // this call links the node to the underlying system data.
  113. VariableNode variable = SetVariableConfiguration(
  114. new NodeId(block.Name, InstanceNamespaceIndex),
  115. new QualifiedName(property.Name, TypeNamespaceIndex),
  116. NodeHandleType.ExternalPolled,
  117. new SystemAddress() { Address = block.Address, Offset = property.Offset });
  118. // Add information about expected range
  119. if (variable != null)
  120. {
  121. // in-memory nodes must be locked before updates.
  122. // reads do not require locks for simple types and references.
  123. // value reads require a lock.
  124. lock (InMemoryNodeLock)
  125. {
  126. variable.AccessLevel = (property.Writeable) ? AccessLevels.CurrentReadOrWrite : AccessLevels.CurrentRead;
  127. }
  128. if (property.Range != null)
  129. {
  130. SetVariableDefaultValue(
  131. variable.NodeId,
  132. new QualifiedName(BrowseNames.EURange),
  133. new Variant(property.Range));
  134. }
  135. }
  136. }
  137. /// [Snippet EURange]
  138. }
  139. */
  140. }
  141. catch (Exception e)
  142. {
  143. Console.WriteLine("Failed to start Lesson3aNodeManager. " + e.Message);
  144. }
  145. }
  146. /// <summary>
  147. /// Called when the node manager is stopped.
  148. /// </summary>
  149. public override void Shutdown()
  150. {
  151. try
  152. {
  153. Console.WriteLine("Stopping Lesson3aNodeManager.");
  154. // TBD
  155. base.Shutdown();
  156. }
  157. catch (Exception e)
  158. {
  159. Console.WriteLine("Failed to stop Lesson3aNodeManager. " + e.Message); ;
  160. }
  161. }
  162. /// <summary>
  163. /// Reads the attributes.
  164. /// </summary>
  165. /// [Read]
  166. protected override void Read(
  167. RequestContext context,
  168. TransactionHandle transaction,
  169. IList<NodeAttributeOperationHandle> operationHandles,
  170. IList<ReadValueId> settings)
  171. {
  172. for (int ii = 0; ii < operationHandles.Count; ii++)
  173. {
  174. DataValue dv = null;
  175. //// the data passed to CreateVariable is returned as the UserData in the handle.
  176. //SystemAddress address = operationHandles[ii].NodeHandle.UserData as SystemAddress;
  177. //if (address != null)
  178. //{
  179. // // read the data from the underlying system.
  180. // object value = m_system.Read(address.Address, address.Offset);
  181. // if (value != null)
  182. // {
  183. // dv = new DataValue(new Variant(value, null), DateTime.UtcNow);
  184. // // apply any index range or encoding.
  185. // if (!String.IsNullOrEmpty(settings[ii].IndexRange) || !QualifiedName.IsNull(settings[ii].DataEncoding))
  186. // {
  187. // dv = ApplyIndexRangeAndEncoding(
  188. // operationHandles[ii].NodeHandle,
  189. // dv,
  190. // settings[ii].IndexRange,
  191. // settings[ii].DataEncoding);
  192. // }
  193. // }
  194. //}
  195. Console.WriteLine($"Read NodeId: {operationHandles[ii].NodeId}");
  196. dv = new DataValue(new Variant(1234.56), DateTime.UtcNow);
  197. // set an error if not found.
  198. if (dv == null)
  199. {
  200. dv = new DataValue(new StatusCode(StatusCodes.BadNodeIdUnknown));
  201. }
  202. // return the data to the caller.
  203. ((ReadCompleteEventHandler)transaction.Callback)(
  204. operationHandles[ii],
  205. transaction.CallbackData,
  206. dv,
  207. false);
  208. }
  209. }
  210. /// [Read]
  211. /// <summary>
  212. /// Write the attributes
  213. /// </summary>
  214. /// [Write]
  215. protected override void Write(
  216. RequestContext context,
  217. TransactionHandle transaction,
  218. IList<NodeAttributeOperationHandle> operationHandles,
  219. IList<WriteValue> settings)
  220. {
  221. for (int ii = 0; ii < operationHandles.Count; ii++)
  222. {
  223. StatusCode error = StatusCodes.Good;
  224. // the data passed to CreateVariable is returned as the UserData in the handle.
  225. //SystemAddress address = operationHandles[ii].NodeHandle.UserData as SystemAddress;
  226. //if (address != null)
  227. //{
  228. // if (!String.IsNullOrEmpty(settings[ii].IndexRange))
  229. // {
  230. // error = StatusCodes.BadIndexRangeInvalid;
  231. // }
  232. // else if (!m_system.Write(address.Address, address.Offset, settings[ii].Value.Value))
  233. // {
  234. // Console.WriteLine($"Write Value: {settings[ii].Value.Value}, NodeId: {operationHandles[ii].NodeId}");
  235. // //error = StatusCodes.BadUserAccessDenied;
  236. // }
  237. //}
  238. //else
  239. //{
  240. // error = StatusCodes.BadNodeIdUnknown;
  241. //}
  242. Console.WriteLine($"Write Value: {settings[ii].Value.Value}, NodeId: {operationHandles[ii].NodeId}");
  243. // return the data to the caller.
  244. ((WriteCompleteEventHandler)transaction.Callback)(
  245. operationHandles[ii],
  246. transaction.CallbackData,
  247. error,
  248. false);
  249. }
  250. }
  251. /// [Write]
  252. #region Constructor
  253. /// <summary>
  254. /// Initializes a new instance of the class.
  255. /// </summary>
  256. /// [Create system in constructor]
  257. public XMLNodeManager(ServerManager server) : base(server)
  258. {
  259. // m_system = new UnderlyingSystem();
  260. }
  261. /// [Create system in constructor]
  262. #endregion
  263. #region IDisposable
  264. /// <summary>
  265. /// An overrideable version of the Dispose.
  266. /// </summary>
  267. /// <param name="disposing"></param>
  268. protected override void Dispose(bool disposing)
  269. {
  270. if (disposing)
  271. {
  272. // TBD
  273. }
  274. }
  275. #endregion
  276. #region SystemAddress Class
  277. private class SystemAddress
  278. {
  279. public int Address;
  280. public int Offset;
  281. }
  282. #endregion
  283. #region Private Methods
  284. #endregion
  285. /// [Add system]
  286. #region Private Fields
  287. //private UnderlyingSystem m_system;
  288. #endregion
  289. /// [Add system]
  290. }
  291. }