OPC UA:如何在OPC UA中打开用于写入原始数据的服务器文件?

问题描述 投票:1回答:2

我正在创建一个C#应用程序,它使用OPC UA将文件发送到Siemens数字控件。

我正在使用CopyFileToServer方法。文件已创建但我已经看到要传递文件中的原始数据,您必须使用filetype中包含的Open方法,传递原始数据并调用Close方法来关闭文件。我尝试了几次使用Open方法而没有成功。有人能帮我吗?

我在Visual Studio 2017的Windows 10 64位计算机上尝试过它。

public void SendFile(Opc.Ua.Client.Session session)
    {
        try
        {
            if (session != null)
            {

                NodeId node0 = new NodeId("ns=2;s=/Methods");
                NodeId node1 = new NodeId("ns=2;s=/Methods/GiveUserAccess");
                object[] argument0 = new object[2];

                argument0[0] = "USER";
                argument0[1] = "SinuWriteAll";

                session.Call(node0, node1, argument0);

                NodeId node = new NodeId("ns=2;s=/Methods");
                NodeId method = new NodeId("ns=2;s=/Methods/CopyFileToServer");
                object[] argument = new object[3];
                byte[] data = new byte[1];

                argument[0] = "Sinumerik/FileSystem/Part Program/sendFile.mpf";
                argument[1] = data;
                argument[2] = true;

                var a = session.Call(node, method, argument);

                NodeId nodeFile = new NodeId("file to open"); // The problem is this (i don't find the method for the file server nodeid)
                NodeId methodOpen = new NodeId("ns=0;i=11580");
                object[] argument1 = new object[1];
                argument1[0] = OpenFileMode.Write;

                var hndl = session.Call(nodeFile, methodOpen, argument1); // Exception 
            }
        }
        catch (Exception ex)
        {

        }
    }

上面的代码返回以下异常:

“无效的论据无效”。

c# opc-ua
2个回答
0
投票

找到了解决方案。

    NodeId open = new NodeId("ns=2;s=Sinumerik/FileSystem/Part Program/SENDFILE.MPF.Open");
    var parent = GetMethodParent(session, open);
    object[] argument1 = new object[1];
    argument1[0] = Convert.ToByte(OpenFileMode.Write);
    var hndl = session.Call(parent, open, argument1);

通过这种方式,我有了与write函数一起使用的句柄。在NodeId中,“打开”表示要打开的文件。

函数“GetMethodParent”:

private NodeId GetMethodParent(Session session, NodeId methodNodeId)
    {
        session.Browse(
          null,
          null,
          methodNodeId,
          0u,
          BrowseDirection.Inverse, //browse in inverse direction
          ReferenceTypeIds.HierarchicalReferences,
          true,
          (uint)NodeClass.Object, //only return nodes of type Object
          out _,
          out var references); //get all parent references

        var parentReference = references[0]; //a MethodNode can only have one parent reference
        return ExpandedNodeId.ToNodeId(parentReference.NodeId, session.NamespaceUris); //return the NodeId converted from an ExpandedNodeId
    }

0
投票

重要的是,在创建新的NodeId之后使用Browse方法。 Browse方法允许使用刚刚创建的新NodeID重新加载服务器树。

     private ReferenceDescriptionCollection Browse(Session session, BrowseDescription nodeToBrowse, bool throwOnError)
    {
        try
        {
            var descriptionCollection = new ReferenceDescriptionCollection();
            var nodesToBrowse = new BrowseDescriptionCollection { nodeToBrowse };
            BrowseResultCollection results;
            DiagnosticInfoCollection diagnosticInfos;
            session.Browse(null, null, 0U, nodesToBrowse, out results, out diagnosticInfos);
            ClientBase.ValidateResponse(results, nodesToBrowse);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse);
            while (!StatusCode.IsBad(results[0].StatusCode))
            {
                for (var index = 0; index < results[0].References.Count; ++index)
                    descriptionCollection.Add(results[0].References[index]);
                if (results[0].References.Count == 0 || results[0].ContinuationPoint == null)
                    return descriptionCollection;
                var continuationPoints = new ByteStringCollection();
                continuationPoints.Add(results[0].ContinuationPoint);
                session.BrowseNext(null, false, continuationPoints, out results, out diagnosticInfos);
                ClientBase.ValidateResponse(results, continuationPoints);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints);
            }
            throw new ServiceResultException(results[0].StatusCode);
        }
        catch (Exception ex)
        {
            if (throwOnError)
                throw new ServiceResultException(ex, 2147549184U);
            return null;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.