WORK/OPC

OPC UA Client ToolKit에서 PLC에 DATA WRITE 하기 Session Write

memoriserf 2025. 3. 31. 10:43

 

기본적으로 OPC UA Client ToolKit Sample Project에서 제공하는 방법은

 

OPC Manager 객체의 ReadValue , ReadValues , WriteValue , WriteValues 를 이용하는 방법이다.

 

ReadValues나 WriteValues는 NodeID와 Data를 List로 만들어서 보내는 방식이다.

패키지와 라이센스 유통 회사에 기술문의를 해보니 Integration Objects에서는 위의 방법을 권장하고 속도향상에 대한 퍼포먼스 설정 및 다른 방법은 알려주지 않았다.

 

 

 

아무튼, Read는 Subscription을 사용하면 되고 Write는 세션자체에도 펑션이 존재한다.

Subscription은 기회가 되면 다음에...

 

WriteValues를 사용하기 위한 기본틀을 struct로 잡아놓았기에 그것을 그대로 이용했다.

 

참고자료 : https://csharp.hotexamples.com/examples/Opc.Ua.Client/Session/Write/php-session-write-method-examples.html

 

목록을 보면 다른 opc UA client의 function example을 확인 가능하다

 

참고자료를 보면 WriteValue를 정의하기 위해 Type을 위한 펑션도 있고... 뭐 아무튼 여러가지의 펑션이 더 필요하다.

필요없는건 자르고 데이터는 직접 정의하는 방법으로 사용한것은 아래와 같다.

 

 

for (int i = 0; i < structData.NodeID.Count; i++)

                        {

                            //TypeInfo m_sourceType = GetExpectedType(m_session, structData.NodeID[i]);

                            object value;

                            if (structData.Data[i] == "True" || structData.Data[i] == "False")

                            {

                                //value = TypeInfo.Cast(Convert.ToBoolean(structData.Data[i]), m_sourceType.BuiltInType);

                                value = TypeInfo.Cast(Convert.ToBoolean(structData.Data[i]), BuiltInType.Boolean);

                            }

                            else if (structData.NodeID[i].Substring(structData.NodeID[i].Length - 5, 5) == "JOBNO")

                            {

                                value = TypeInfo.Cast(Convert.ToString(structData.Data[i]), BuiltInType.String);

                            }

                            else

                            {

                                value = TypeInfo.Cast(structData.Data[i], BuiltInType.Int16);

                            }

                            WriteValueCollection nodesToWrite = new WriteValueCollection();

                            WriteValue nodeToWrite = new WriteValue();

                            nodeToWrite.NodeId = structData.NodeID[i];

                            nodeToWrite.AttributeId = Attributes.Value;

                            // using the WrappedValue instead of the Value property because we know the TypeInfo.

                            // this makes the assignment more efficient by avoiding reflection to determine type.

                            nodeToWrite.Value.WrappedValue = new Variant(value);

                            nodesToWrite.Add(nodeToWrite);

                            // override the diagnostic masks (other parameters are set to defaults).

                            //RequestHeader requestHeader = new RequestHeader();

                            //requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All;

                            // read the attributes.

                            StatusCodeCollection results = null;

                            DiagnosticInfoCollection diagnosticInfos = null;

                            /* ResponseHeader responseHeader =*/

                            m_session.Write(

                            null,

                            nodesToWrite,

                            out results,

                            out diagnosticInfos);

                            //ClientBase.ValidateResponse(results, nodesToWrite);

                            //ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite);

                            // check status.

                            //if (StatusCode.IsBad(results[0]))

                            //{

                            //    // embed the diagnostic information in a exception.

                            //    throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable);

                            //}

                        }

 

 

struct의 NodeID에는 n=2;s= 로 시작하는 NodeID를 리스트로 넣고

          Data에는 실제 값을 리스트로 넣는다.

 

값의 유형은 직접 판별해서 TypeInfo로 캐스팅해서 넣어준다.

 

대량의 Tag를 한번에 Write할 경우 OPCManager의 WriteValues보다 조금이나마 나은 결과를 보여준다.

 

테스트를 많이 하진 않았지만 일단 Session Write를 사용할 듯 하다

 

 

 

 

 

혹시 몰라서 Type을 가져오는 GetExpectedType function도 일단 적어둠

 

     private TypeInfo GetExpectedType(Session session, NodeId nodeId)

        {

            // build list of attributes to read.

            ReadValueIdCollection nodesToRead = new ReadValueIdCollection();

 

            foreach (uint attributeId in new uint[] { Attributes.DataType, Attributes.ValueRank })

            {

                ReadValueId nodeToRead = new ReadValueId();

                nodeToRead.NodeId = nodeId;

                nodeToRead.AttributeId = attributeId;

                nodesToRead.Add(nodeToRead);

            }

            // read the attributes.

            DataValueCollection results = null;

            DiagnosticInfoCollection diagnosticInfos = null;

 

            session.Read(

                null,

                0,

                TimestampsToReturn.Neither,

                nodesToRead,

                out results,

                out diagnosticInfos);

 

            ClientBase.ValidateResponse(results, nodesToRead);

            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

 

            // this call checks for error and checks the data type of the value.

            // if an error or mismatch occurs the default value is returned.

            NodeId dataTypeId = results[0].GetValue<NodeId>(null);

            int valueRank = results[1].GetValue<int>(ValueRanks.Scalar);

 

            // use the local type cache to look up the base type for the data type.

            BuiltInType builtInType = DataTypes.GetBuiltInType(dataTypeId, session.NodeCache.TypeTree);

 

            // the type info object is used in cast and compare functions.

            return new TypeInfo(builtInType, valueRank);

        }

 

 

 

 

 

 

 

'WORK > OPC' 카테고리의 다른 글

OPC UA Client Toolkit 사용시 기본설정  (0) 2025.04.09
OPC Server Session Write -2-  (0) 2025.03.31
OPC SERVER SIMULATION MODE 적용하는 방법  (0) 2025.03.31