今天想跟大家介紹的是OPC UA (Open Platform Communications United Architecture), OPC UA 嚴格來說並不是一種通訊方式,只能說是一種在工業上被當作資料交換標準的規範使用。

這個協議我在做時覺得台灣的資訊蠻少的,藉此我想在這裡做個筆記分享我所理解的部分,當然這一切都只是冰山一角。

由於OPC Funcdation 上面所有程式碼都是open source 如想要瞭解比較深層的code,必須當起碼農開始去看官網上release的程式碼!!

當然我這邊會教大家基礎的設置與撰寫。

第一步:

     首先我們當然要先開啟一個專案

第二步

     至nuget下載OPCFoundation 

nugetopc.PNG

第三部: 開始撰寫程式

一開始需要創建一個class,我將其命名為 ReferenceServer,此類別必須要繼承 StandardServer,因為我們必須要override 連線時所需要的兩個方法

必須override的方法為: 

  • CreateMasterNodeManager
  • LoadServerProperties

   public ReferenceServer(List<T> nodeDataStructObj)
        {  /// TmpObj 這個地方只是我程式架構中所帶入的樹狀結構資料
            TmpObj = nodeDataStructObj.ToList<OpcuaNode>();
        }

   protected override MasterNodeManager CreateMasterNodeManager(IServerInternal server, ApplicationConfiguration configuration)
        {
            Utils.Trace("Creating the Node Managers.");

            List<INodeManager> nodeManagers = new List<INodeManager>();
            NodeManager = new ReferenceNodeManager<OpcuaNode>(server, configuration, TmpObj);  /// 創建樹狀結構類別
            // create the custom node managers.
            nodeManagers.Add(NodeManager);

            // create master node manager.
            return new MasterNodeManager(server, configuration, null, nodeManagers.ToArray());
        }
        /// <summary>
        /// Loads the non-configurable properties for the application.
        /// </summary>
        /// <remarks>
        /// These properties are exposed by the server but cannot be changed by administrators.
        /// </remarks>
        protected override ServerProperties LoadServerProperties()
        {
            ServerProperties properties = new ServerProperties();

            properties.ManufacturerName = "OPC Foundation";
            properties.ProductName = "Quickstart Reference Server";
            properties.ProductUri = "http://opcfoundation.org/GPPlant/InformationModelServer/v1.0"; //此處翻紅的地方必須要與你的設定檔一樣
            properties.SoftwareVersion = Utils.GetAssemblySoftwareVersion();
            properties.BuildNumber = Utils.GetAssemblyBuildNumber();
            properties.BuildDate = Utils.GetAssemblyTimestamp();

            return properties;
        }

 

再來再創建一個class 命名為 ReferenceNodeManager 請再繼承CustomNodeManager2

也是一樣需要override 

  • CreateAddressSpace

        public ReferenceNodeManager(IServerInternal server, ApplicationConfiguration configuration, List<T> nodeClass) : base(server, configuration, GP_NameSpace.ReferenceApplications)
        {
            SystemContext.NodeIdFactory = this;
            m_configuration = configuration.ParseExtension<ReferenceServerConfiguration>();
            if (m_configuration == null)
            {
                m_configuration = new ReferenceServerConfiguration();
            }
            nodes = nodeClass;     ///建置樹狀結構需要的NODE 每個人建置的方式都不同 我就沒有把這個放上來了
        }

        /// <summary>
        /// overrride 創建基礎目錄
        /// </summary>
        /// <param name="externalReferences"></param>
        public override void CreateAddressSpace(IDictionary<NodeId, IList<IReference>> externalReferences)
        {
            lock (Lock)
            {
                IList<IReference> references = null;
                if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references))
                {
                    externalReferences[ObjectIds.ObjectsFolder] = references = new List<IReference>();
                }

                try
                {
                    CreateRoot(nodes, references);   //建立樹節點
                    // UpdateVariableValue();
                }
                catch (Exception e)
                {
                    Utils.Trace(e, "Error creating the address space.");
                }
            }
        }

 

接下來就開始建立連線:

目前我知道建立連線的方式有兩種:

第一種 : 透過xml config設定檔建立

第二種: 直接寫code建立

我這邊會先分享第一種方法,有時間我會再說明第二種方法

        public OPCUA_Server(ServerBase serverbaseobj)   

        ///我這邊是我程式架構的關係所以我參數帶入ServerBase 如果你不需要帶入serverbase,只需要在 application.Start 時帶入有serverBase基底的class就可以了
        {
            RefServer = serverbaseobj as ReferenceServer<OpcuaNode>;
            string appStartupPath = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
            ApplicationInstance application = new ApplicationInstance();
            application.ApplicationType = ApplicationType.Server;
            application.ConfigSectionName = "GPPlantServer";    /// A 
            try
            {                                                                                                                                           ///    A與B均為紅色表示這兩處名字要相同

                                                                                                                                                        ///    此處的設定檔可以由OPC Fundation 開源程式碼中得到           

                                                                                                                                                        ///    如果找不到請在下面留言我再寄給你                                                                                                                                             // load the application configuration.                                                                            
                application.LoadApplicationConfiguration(string.Format("{0}{1}", appStartupPath, @"\GPPlantServer.Config.xml"), false).Wait(); ///B 

                  // check the application certificate.
                application.CheckApplicationInstanceCertificate(false, 0).Wait();

                  // start the server.
                application.Start(serverbaseobj).Wait();
            }
            catch (Exception e)
            {
                string text = "Exception: " + e.Message;
                if (e.InnerException != null)
                {
                    text += "\r\nInner exception: ";
                    text += e.InnerException.Message;
                }
                //   MessageBox.Show(text, application.ApplicationName);
            }
        }

這樣第一種連線方式就完成了

 

如果有任何OPC UA 概念的疑問可以參考以下影片,我是覺得講解的蠻仔細的

OPC

OPCUA講解

 

創作者介紹
創作者 我叫小信信的部落格 的頭像
我叫小信信

我叫小信信的部落格

我叫小信信 發表在 痞客邦 留言(0) 人氣( 905 )