{"id":4072,"date":"2020-09-10T14:00:25","date_gmt":"2020-09-10T05:00:25","guid":{"rendered":"https:\/\/now0930.pe.kr\/wordpress\/?p=4072"},"modified":"2020-09-10T19:22:15","modified_gmt":"2020-09-10T10:22:15","slug":"open62541-serverclient-%ea%b3%b5%ec%a0%95-%eb%8f%99%ec%9e%91-%ec%8b%9c%ea%b0%84-%ec%b8%a1%ec%a0%95","status":"publish","type":"post","link":"https:\/\/now0930.pe.kr\/wordpress\/open62541-serverclient-%ea%b3%b5%ec%a0%95-%eb%8f%99%ec%9e%91-%ec%8b%9c%ea%b0%84-%ec%b8%a1%ec%a0%95\/","title":{"rendered":"open62541 server+client \uacf5\uc815 \ub3d9\uc791 \uc2dc\uac04 \uce21\uc815"},"content":{"rendered":"\n<p>\ucc98\uc74c \uc124\uc815\ud55c \ubaa9\ud45c\ub97c \ub4dc\ub514\uc5b4 \uc218\ud589\ud588\ub2e4. \uc11c\ubc84\ub97c \ub300\ub7b5 \uad6c\ud604\ud588\uc73c\ub2c8  \ub2e4\uc74c\uc73c\ub85c \ud074\ub77c\uc774\uc5b8\ud2b8\ub97c \ub9cc\ub4e4\uc5c8\ub2e4. \ub0b4\uac00 \ucabc\ub7a9\uc774\ub77c tutorial \ubb38\uc11c \uadf8\ub300\ub85c \uc0ac\uc6a9\ud588\ub2e4. cilent\ub294 UA_Client_Service_browse\ub85c server\uac00 \uc5b4\ub5a4 \ub370\uc774\ud130\ub97c \uac00\uc9c0\uace0 \uc788\ub294\uc9c0 \ubcfc \uc218 \uc788\ub2e4. \uadf8\ub7ec\ub098 \uc5ed\uc2dc \ud55c \ub2e8\uacc4\ubc16\uc5d0 \ubcfc \uc218 \uc5c6\ub2e4. \ud558\ubd80 \uad6c\uc870\ub97c \ubcf4\ub824\uba74 nodeId\ub97c \uae30\uc5b5\ud558\uc5ec \ub2e4\uc2dc browse\ub97c \ud574\uc57c \ud55c\ub2e4. \ub354 \uc88b\uc740 \ubc29\ubc95\uc774 \uc788\uaca0\uc9c0\ub9cc, \uc774\uac83\ub3c4 \ub418\ub2c8\uae4c \ubb38\uc81c \uc548\ub41c\ub2e4.<\/p>\n\n\n\n<p>\uc11c\ubc84\uac00 method\ub97c \uac00\uc9c0\uace0 \uc788\uc5b4 client\uc5d0\uc11c \uc624\ub294 \ucf5c\uc744 \ubc1b\uc544 \uc815\ub9ac\ud574\uc11c \ubcf4\ub0b4 \uc904 \uc218\ub3c4 \uc788\uc9c0\ub9cc, \uc2dc\uac04\uc744 \ub9ce\uc774 \uc4f8 \ub4ef\ud558\uc5ec \uc27d\uace0 \uac04\ub2e8\ud558\uac8c \uac14\ub2e4.<\/p>\n\n\n\n<p>\uc11c\ubc84\uac00 \uac01 \uacf5\uc815 \ub3d9\uc791 \uc0c1\ud669\uc744 OPC UA nodeId\uc5d0 \uae30\ub85d\ud55c\ub2e4. 5\ucd08\ub9c8\ub2e4 \uc5c5\ub370\uc774\ud2b8 \ud588\ub294\ub370, \uc2e4\uc7ac PLC\ub85c \uad6c\ud604\ud55c\ub2e4\uba74 \ub9e4 \ucd08\ub9c8\ub2e4 update\ud558\ub294 \ubc29\uc2dd\uc73c\ub85c \ud574\uc57c \ud560 \ub4ef\ud558\ub2e4. \uadf8\ub9ac \ub9ce\uc740 \ubd80\ud558\uac00 \uac78\ub9ac\uc9c0\ub294 \uc54a\uc744 \ub4ef \ud558\ub2e4.<\/p>\n\n\n\n<p>\ud074\ub77c\uc774\uc5b8\ud2b8\ub294 \ub9e4 3\ucd08\ub9c8\ub2e4 \uc11c\ubc84\ub85c request\ud558\uc5ec \uc815\ubcf4\ub97c \ubc1b\uc544\uc624\ub294 \ubc29\uc2dd\uc73c\ub85c \uc791\uc131\ud588\ub2e4. timestamp\ub294 server\ucabd \uc2dc\uac01\uc744 \uc4f0\uc9c0 \uc54a\uace0, \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \uc784\uc758\ub85c \ub9cc\ub4e0 \uc2dc\uac01\uc744 \uae30\ub85d\ud588\ub2e4.<\/p>\n\n\n\n<p>\ub370\uc774\ud130\ub97c \ub370\uc774\ud130 \ubca0\uc774\uc2a4\ub85c \ubc14\ub85c \uc5c5\ub370\uc774\ud2b8 \ud55c\ub2e4\ub358\uac00, \ud30c\uc77c\ub85c \uae30\ub85d\ud560 \uc218\ub3c4 \uc788\ub2e4. \uadf8\ub7ec\ub098 \uc2dc\uac04\uc744 \ub9ce\uc774 \uc4f0\ubbc0\ub85c \ud45c\uc900 \ucd9c\ub825\uc73c\ub85c \ub098\uc628 \uba54\uc138\uc9c0\ub97c file\ub85c redirect\ud558\uba74 \uc27d\uac8c \ud560 \uc218 \uc788\ub2e4. \uc911\ubcf5 \ub370\uc774\ud130\ub294 sort\ub85c \uc27d\uac8c \uc9c0\uc6b8 \uc218 \uc788\ub2e4. bash \ub9cc\uc138!<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"900\" style=\"aspect-ratio: 1600 \/ 900;\" width=\"1600\" controls src=\"https:\/\/now0930.pe.kr\/wordpress\/wp-content\/uploads\/2020\/09\/OPCUA_server_client-2020-09-10_13.39.29.mp4\"><\/video><\/figure>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include \"open62541.h\"\n\n#include &lt;signal.h>\n#include &lt;stdlib.h>\n#include &lt;time.h>\n\nstatic volatile UA_Boolean running = true;\nstatic void stopHandler(int sig) {\n\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"received ctrl-c\");\n\trunning = false;\n}\n\nstatic void\nbeforeReadVal(UA_Server *server,\n\t\tconst UA_NodeId *sessionId, void *sessionContext,\n\t\tconst UA_NodeId *nodeid, void *nodeContext,\n\t\tconst UA_NumericRange *range, const UA_DataValue *data) {\n\t\/\/updateCurrentTime(server);\n\tint tmpVal = rand()%1000;\n\tUA_Variant value;\n\tUA_Variant_setScalar(&amp;value, &amp;tmpVal, &amp;UA_TYPES[UA_TYPES_INT32]);\n\tUA_NodeId currentNodeId = UA_NODEID_STRING(1, \"SEQ\");\n\t\/\/UA_Server_writeValue(server, currentNodeId, value);\n}\n\n\/* predefined identifier for later use *\/\nUA_NodeId pumpTypeId = {1, UA_NODEIDTYPE_NUMERIC, {1001}};\nUA_NodeId cylTypeId = {1, UA_NODEIDTYPE_NUMERIC, {2001}};\nUA_NodeId robotTypeId = {1, UA_NODEIDTYPE_NUMERIC, {3001}};\n\n\nstatic void\ndefineObjectTypes(UA_Server *server) {\n\t\/* Define the object type for \"Device\" *\/\n\tUA_NodeId deviceTypeId; \/* get the nodeid assigned by the server *\/\n\tUA_ObjectTypeAttributes dtAttr = UA_ObjectTypeAttributes_default;\n\tdtAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"DeviceType\");\n\tUA_Server_addObjectTypeNode(server, UA_NODEID_NULL,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),\n\t\t\tUA_QUALIFIEDNAME(1, \"DeviceType\"), dtAttr,\n\t\t\tNULL, &amp;deviceTypeId);\n\n\tUA_VariableAttributes mnAttr = UA_VariableAttributes_default;\n\tmnAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"ManufacturerName\");\n\tUA_NodeId manufacturerNameId;\n\tUA_Server_addVariableNode(server, UA_NODEID_NULL, deviceTypeId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),\n\t\t\tUA_QUALIFIEDNAME(1, \"ManufacturerName\"),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), mnAttr, NULL, &amp;manufacturerNameId);\n\t\/* Make the manufacturer name mandatory *\/\n\tUA_Server_addReference(server, manufacturerNameId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASMODELLINGRULE),\n\t\t\tUA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_MANDATORY), true);\n\n\n\tUA_VariableAttributes modelAttr = UA_VariableAttributes_default;\n\tmodelAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"ModelName\");\n\tUA_Server_addVariableNode(server, UA_NODEID_NULL, deviceTypeId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),\n\t\t\tUA_QUALIFIEDNAME(1, \"ModelName\"),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), modelAttr, NULL, NULL);\n\n\t\/* Define the object type for \"Pump\" *\/\n\tUA_ObjectTypeAttributes ptAttr = UA_ObjectTypeAttributes_default;\n\tptAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"PumpType\");\n\tUA_Server_addObjectTypeNode(server, pumpTypeId,\n\t\t\tdeviceTypeId, UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),\n\t\t\tUA_QUALIFIEDNAME(1, \"PumpType\"), ptAttr,\n\t\t\tNULL, NULL);\n\n\tUA_VariableAttributes statusAttr = UA_VariableAttributes_default;\n\tstatusAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"Status\");\n\tstatusAttr.valueRank = UA_VALUERANK_SCALAR;\n\tUA_NodeId statusId;\n\tUA_Server_addVariableNode(server, UA_NODEID_NULL, pumpTypeId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),\n\t\t\tUA_QUALIFIEDNAME(1, \"Status\"),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), statusAttr, NULL, &amp;statusId);\n\t\/* Make the status variable mandatory *\/\n\tUA_Server_addReference(server, statusId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASMODELLINGRULE),\n\t\t\tUA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_MANDATORY), true);\n\n\tUA_VariableAttributes rpmAttr = UA_VariableAttributes_default;\n\trpmAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"MotorRPM\");\n\trpmAttr.valueRank = UA_VALUERANK_SCALAR;\n\tUA_Server_addVariableNode(server, UA_NODEID_NULL, pumpTypeId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),\n\t\t\tUA_QUALIFIEDNAME(1, \"MotorRPMs\"),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), rpmAttr, NULL, NULL);\n}\n\nstatic void\ndefineCylTypes(UA_Server *server) {\n\t\/* Define the object type for \"Device\" *\/\n\tUA_NodeId deviceTypeId; \/* get the nodeid assigned by the server *\/\n\tUA_ObjectTypeAttributes dtAttr = UA_ObjectTypeAttributes_default;\n\tdtAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"Cylinder Type\");\n\tUA_Server_addObjectTypeNode(server, UA_NODEID_NULL,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),\n\t\t\tUA_QUALIFIEDNAME(1, \"Cylinder Type\"), dtAttr,\n\t\t\tNULL, &amp;deviceTypeId);\n\n\tUA_VariableAttributes mnAttr = UA_VariableAttributes_default;\n\tmnAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"Manufacturer Name\");\n\tUA_NodeId manufacturerNameId;\n\tUA_Server_addVariableNode(server, UA_NODEID_NULL, deviceTypeId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),\n\t\t\tUA_QUALIFIEDNAME(1, \"Cylinder\"),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), mnAttr, NULL, &amp;manufacturerNameId);\n\n\tUA_VariableAttributes modelAttr = UA_VariableAttributes_default;\n\tUA_NodeId modelNameId;\n\tmodelAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"Cyl Model Name\");\n\tUA_Server_addVariableNode(server, UA_NODEID_NULL, deviceTypeId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),\n\t\t\tUA_QUALIFIEDNAME(1, \"Cyl Model Name\"),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), modelAttr, NULL, &amp;modelNameId);\n\n\tUA_Server_addReference(server,modelNameId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASMODELLINGRULE),\n\t\t\tUA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_MANDATORY), true);\n\n\t\/* Define the object type for \"Pump\" *\/\n\tUA_ObjectTypeAttributes ptAttr = UA_ObjectTypeAttributes_default;\n\tptAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"Running State\");\n\tUA_Server_addObjectTypeNode(server, cylTypeId,\n\t\t\tdeviceTypeId, UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),\n\t\t\tUA_QUALIFIEDNAME(1, \"Running State\"), ptAttr,\n\t\t\tNULL, NULL);\n\n\n\tUA_VariableAttributes statusAttr = UA_VariableAttributes_default;\n\tstatusAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"Status\");\n\tstatusAttr.valueRank = UA_VALUERANK_SCALAR;\n\tUA_NodeId statusId;\n\tUA_Server_addVariableNode(server, UA_NODEID_NULL, cylTypeId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),\n\t\t\tUA_QUALIFIEDNAME(1, \"Status\"),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), statusAttr, NULL, &amp;statusId);\n\t\/* Make the manufacturer name mandatory *\/\n\t\/\/ UA_Server_addReference()\ub97c \uc5b4\ub5bb\uac8c \ud558\ub0d0\uc5d0 \ub530\ub77c  statusId\n\t\/\/ instance \ub9cc\ub4e4\uacbd\uc6b0 \ud45c\uc2dc\n\tUA_Server_addReference(server, statusId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASMODELLINGRULE),\n\t\t\tUA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_MANDATORY), true);\n}\n\n\n\nstatic void\ndefineRobotTypes(UA_Server *server) {\n\t\/* Define the object type for \"Device\" *\/\n\tUA_NodeId deviceTypeId; \/* get the nodeid assigned by the server *\/\n\tUA_ObjectTypeAttributes dtAttr = UA_ObjectTypeAttributes_default;\n\tdtAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"Robot Type\");\n\tUA_Server_addObjectTypeNode(server, UA_NODEID_NULL,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),\n\t\t\tUA_QUALIFIEDNAME(1, \"Robot Type\"), dtAttr,\n\t\t\tNULL, &amp;deviceTypeId);\n\n\tUA_VariableAttributes mnAttr = UA_VariableAttributes_default;\n\tmnAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"Manufacturer Name\");\n\tUA_NodeId manufacturerNameId;\n\tUA_Server_addVariableNode(server, UA_NODEID_NULL, deviceTypeId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),\n\t\t\tUA_QUALIFIEDNAME(1, \"Robot\"),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), mnAttr, NULL, &amp;manufacturerNameId);\n\n\tUA_VariableAttributes modelAttr = UA_VariableAttributes_default;\n\tUA_NodeId modelNameId;\n\tmodelAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"Robot Model Name\");\n\tUA_Server_addVariableNode(server, UA_NODEID_NULL, deviceTypeId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),\n\t\t\tUA_QUALIFIEDNAME(1, \"Robot Model Name\"),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), modelAttr, NULL, &amp;modelNameId);\n\n\tUA_Server_addReference(server,modelNameId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASMODELLINGRULE),\n\t\t\tUA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_MANDATORY), true);\n\n\t\/* Define the object type for \"Pump\" *\/\n\tUA_ObjectTypeAttributes ptAttr = UA_ObjectTypeAttributes_default;\n\tptAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"Interlock\");\n\tUA_Server_addObjectTypeNode(server, robotTypeId,\n\t\t\tdeviceTypeId, UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),\n\t\t\tUA_QUALIFIEDNAME(1, \"Interlock\"), ptAttr,\n\t\t\tNULL, NULL);\n\n\n\tUA_VariableAttributes statusAttr = UA_VariableAttributes_default;\n\tstatusAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", \"Status\");\n\tstatusAttr.valueRank = UA_VALUERANK_SCALAR;\n\tUA_NodeId statusId;\n\tUA_Server_addVariableNode(server, UA_NODEID_NULL, robotTypeId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),\n\t\t\tUA_QUALIFIEDNAME(1, \"Status\"),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), statusAttr, NULL, &amp;statusId);\n\t\/* Make the manufacturer name mandatory *\/\n\t\/\/ UA_Server_addReference()\ub97c \uc5b4\ub5bb\uac8c \ud558\ub0d0\uc5d0 \ub530\ub77c  statusId\n\t\/\/ instance \ub9cc\ub4e4\uacbd\uc6b0 \ud45c\uc2dc\n\tUA_Server_addReference(server, statusId,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASMODELLINGRULE),\n\t\t\tUA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_MANDATORY), true);\n}\n\n\n\nstatic void\naddPumpObjectInstance(UA_Server *server, char *name) {\n\tUA_ObjectAttributes oAttr = UA_ObjectAttributes_default;\n\toAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", name);\n\tUA_Server_addObjectNode(server, UA_NODEID_NULL,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),\n\t\t\tUA_QUALIFIEDNAME(1, name),\n\t\t\tpumpTypeId, \/* this refers to the object type\n\t\t\t\t\t\t   identifier *\/\n\t\t\toAttr, NULL, NULL);\n}\n\nstatic void\naddCylObjectInstance(UA_Server *server, char *name) {\n\tUA_ObjectAttributes oAttr = UA_ObjectAttributes_default;\n\toAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", name);\n\t\/*\n\t   UA_Server_addObjectNode(UA_Server *server, const UA_NodeId requestedNewNodeId,\n\t   const UA_NodeId parentNodeId,\n\t   const UA_NodeId referenceTypeId,\n\t   const UA_QualifiedName browseName,\n\t   const UA_NodeId typeDefinition,\n\t   const UA_ObjectAttributes attr,\n\t   void *nodeContext, UA_NodeId *outNewNodeId) {\n\t *\/\n\n\tUA_Server_addObjectNode(server, UA_NODEID_NULL,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),\n\t\t\tUA_QUALIFIEDNAME(1, name),\n\t\t\tcylTypeId, \/* this refers to the object type\n\t\t\t\t\t\t  identifier *\/\n\t\t\toAttr, NULL, NULL);\n}\n\n\n\nstatic void\naddRbtObjectInstance(UA_Server *server, char *name) {\n\tUA_ObjectAttributes oAttr = UA_ObjectAttributes_default;\n\toAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\", name);\n\t\/*\n\t   UA_Server_addObjectNode(UA_Server *server, const UA_NodeId requestedNewNodeId,\n\t   const UA_NodeId parentNodeId,\n\t   const UA_NodeId referenceTypeId,\n\t   const UA_QualifiedName browseName,\n\t   const UA_NodeId typeDefinition,\n\t   const UA_ObjectAttributes attr,\n\t   void *nodeContext, UA_NodeId *outNewNodeId) {\n\t *\/\n\n\tUA_Server_addObjectNode(server, UA_NODEID_NULL,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),\n\t\t\tUA_QUALIFIEDNAME(1, name),\n\t\t\trobotTypeId, \/* this refers to the object type\n\t\t\t\t\t\t\tidentifier *\/\n\t\t\toAttr, NULL, NULL);\n}\n\n\nstatic UA_StatusCode\npumpTypeConstructor(UA_Server *server,\n\t\tconst UA_NodeId *sessionId, void *sessionContext,\n\t\tconst UA_NodeId *typeId, void *typeContext,\n\t\tconst UA_NodeId *nodeId, void **nodeContext) {\n\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"New pump created\");\n\n\t\/* Find the NodeId of the status child variable *\/\n\tUA_RelativePathElement rpe;\n\tUA_RelativePathElement_init(&amp;rpe);\n\trpe.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT);\n\trpe.isInverse = false;\n\trpe.includeSubtypes = false;\n\trpe.targetName = UA_QUALIFIEDNAME(1, \"Status\");\n\n\tUA_BrowsePath bp;\n\tUA_BrowsePath_init(&amp;bp);\n\tbp.startingNode = *nodeId;\n\tbp.relativePath.elementsSize = 1;\n\tbp.relativePath.elements = &rpe;\n\n\tUA_BrowsePathResult bpr =\n\t\tUA_Server_translateBrowsePathToNodeIds(server, &amp;bp);\n\tif(bpr.statusCode != UA_STATUSCODE_GOOD ||\n\t\t\tbpr.targetsSize &lt; 1)\n\t\treturn bpr.statusCode;\n\n\t\/* Set the status value *\/\n\tUA_Boolean status = true;\n\tUA_Variant value;\n\tUA_Variant_setScalar(&amp;value, &amp;status, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\tUA_Server_writeValue(server, bpr.targets[0].targetId.nodeId, value);\n\tUA_BrowsePathResult_clear(&amp;bpr);\n\n\t\/* At this point we could replace the node context .. *\/\n\n\treturn UA_STATUSCODE_GOOD;\n}\n\nstatic void\naddPumpTypeConstructor(UA_Server *server) {\n\tUA_NodeTypeLifecycle lifecycle;\n\tlifecycle.constructor = pumpTypeConstructor;\n\tlifecycle.destructor = NULL;\n\tUA_Server_setNodeTypeLifecycle(server, pumpTypeId, lifecycle);\n}\n\n\n\n\n\/\/method \ucd94\uac00\nstatic UA_StatusCode\nhelloWorldMethodCallback(UA_Server *server,\n\t\tconst UA_NodeId *sessionId, void *sessionHandle,\n\t\tconst UA_NodeId *methodId, void *methodContext,\n\t\tconst UA_NodeId *objectId, void *objectContext,\n\t\tsize_t inputSize, const UA_Variant *input,\n\t\tsize_t outputSize, UA_Variant *output) {\n\tUA_String *inputStr = (UA_String*)input->data;\n\tUA_String tmp = UA_STRING_ALLOC(\"Hello \");\n\tif(inputStr->length > 0) {\n\t\ttmp.data = (UA_Byte *)UA_realloc(tmp.data, tmp.length + inputStr->length);\n\t\tmemcpy(&amp;tmp.data[tmp.length], inputStr->data, inputStr->length);\n\t\ttmp.length += inputStr->length;\n\t}\n\tUA_Variant_setScalarCopy(output, &amp;tmp, &amp;UA_TYPES[UA_TYPES_STRING]);\n\tUA_String_clear(&amp;tmp);\n\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, \"Hello World was called\");\n\treturn UA_STATUSCODE_GOOD;\n}\n\nstatic void\naddHellWorldMethod(UA_Server *server) {\n\tUA_Argument inputArgument;\n\tUA_Argument_init(&amp;inputArgument);\n\tinputArgument.description = UA_LOCALIZEDTEXT(\"en-US\", \"A String\");\n\tinputArgument.name = UA_STRING(\"MyInput\");\n\tinputArgument.dataType = UA_TYPES[UA_TYPES_STRING].typeId;\n\tinputArgument.valueRank = UA_VALUERANK_SCALAR;\n\n\tUA_Argument outputArgument;\n\tUA_Argument_init(&amp;outputArgument);\n\toutputArgument.description = UA_LOCALIZEDTEXT(\"en-US\", \"A String\");\n\toutputArgument.name = UA_STRING(\"MyOutput\");\n\toutputArgument.dataType = UA_TYPES[UA_TYPES_STRING].typeId;\n\toutputArgument.valueRank = UA_VALUERANK_SCALAR;\n\n\tUA_MethodAttributes helloAttr = UA_MethodAttributes_default;\n\thelloAttr.description = UA_LOCALIZEDTEXT(\"en-US\",\"Say `Hello World`\");\n\thelloAttr.displayName = UA_LOCALIZEDTEXT(\"en-US\",\"Hello World\");\n\thelloAttr.executable = true;\n\thelloAttr.userExecutable = true;\n\tUA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1,62541),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),\n\t\t\tUA_QUALIFIEDNAME(1, \"hello world\"),\n\t\t\thelloAttr, &amp;helloWorldMethodCallback,\n\t\t\t1, &amp;inputArgument, 1, &amp;outputArgument, NULL, NULL);\n}\n\n\n\/\/\uc774\ub984\uc73c\ub85c nodeId\ub97c \ucc3e\ub294 \ud568\uc218.\nUA_StatusCode\nfindNodeIdWithName(UA_Server *server, UA_NodeId *startNodeId, char *name, UA_NodeId **retNodeId){\n\n\t\/* Find the NodeId of the status child variable *\/\n\tUA_RelativePathElement rpe;\n\tUA_RelativePathElement_init(&amp;rpe);\n\trpe.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT);\n\trpe.isInverse = false;\n\trpe.includeSubtypes = false;\n\trpe.targetName = UA_QUALIFIEDNAME(1,name); \n\n\tUA_BrowsePath bp;\n\tUA_BrowsePath_init(&amp;bp);\n\n\n\tbp.startingNode = *startNodeId;\n\tbp.relativePath.elementsSize = 1;\n\tbp.relativePath.elements = &rpe;\n\n\tUA_BrowsePathResult bpr =\n\t\tUA_Server_translateBrowsePathToNodeIds(server, &amp;bp);\n\tif(bpr.statusCode != UA_STATUSCODE_GOOD ||\n\t\t\tbpr.targetsSize &lt; 1)\n\t\treturn bpr.statusCode;\n\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"found target is %d\", bpr.targets->targetId.nodeId.identifier.numeric);\n\t**retNodeId = bpr.targets->targetId.nodeId;\n\n}\n\n\n\nint main(void) {\n\tsignal(SIGINT, stopHandler);\n\tsignal(SIGTERM, stopHandler);\n\n\tUA_Server *server = UA_Server_new();\n\tUA_ServerConfig_setDefault(UA_Server_getConfig(server));\n\tUA_ServerConfig* config = UA_Server_getConfig(server);\n\tconfig->verifyRequestTimestamp = UA_RULEHANDLING_ACCEPT;\n\n\t\/\/addVariable(server);\n\t\/\/writeVariable(server);\n\t\/\/writeWrongVariable(server);\n\n\n\t\/\/vendor, serial, variable \uc21c\uc73c\ub85c \ucd94\uac00.\n\n\t\/\/\uacf5\ud1b5\uc73c\ub85c \uc0ac\uc6a9\ud560 \ubd80\ubd84 \uc124\uc815.\n\tUA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);\n\tUA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT);\n\t\/\/variable \ucd94\uac00.\n\tUA_VariableAttributes varAttr = UA_VariableAttributes_default;\n\tUA_Int32 varName = 10;\n\tUA_Variant_setScalar(&amp;varAttr.value, &amp;varName, &amp;UA_TYPES[UA_TYPES_INT32]);\n\tUA_NodeId varNodeId = UA_NODEID_STRING(1, \"SEQ\");\n\tUA_QualifiedName myVarName = UA_QUALIFIEDNAME(1, \"SEQ\");\n\tUA_Server_addVariableNode(server, varNodeId, parentNodeId,\n\t\t\tparentReferenceNodeId, myVarName,\n\t\t\tUA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), varAttr, NULL, NULL);\n\n\t\/\/add callback\n\tUA_ValueCallback callback ;\n\tcallback.onRead = beforeReadVal;\n\tcallback.onWrite = NULL;\n\tUA_NodeId currentNodeId = UA_NODEID_STRING(1, \"SEQ\");\n\tUA_Server_setVariableNode_valueCallback(server, currentNodeId, callback);\n\n\t\/\/\uc124\ube44 \uc815\uc758\n\n\tdefineCylTypes(server);\n\taddCylObjectInstance(server, \"pin\");\n\taddCylObjectInstance(server, \"latch\");\n\taddCylObjectInstance(server, \"clamp\");\n\tdefineRobotTypes(server);\n\taddRbtObjectInstance(server, \"Loading Robot\");\n\n\t\/*\n\t   defineObjectTypes(server);\n\t   addPumpTypeConstructor(server);\n\t   addPumpObjectInstance(server, \"pump4\");\n\t *\/\n\n\n\t\/\/method\n\taddHellWorldMethod(server);\n\n\n\t\/\/ladder\ub97c \uc2dc\ubbac\ub798\uc774\uc158\ud558\ub294 \ubd80\ubd84.\n\t\/\/thread\ub85c latch fwd -> clamp fwd -> pin fwd -> robot in -> pin bwd: \uacf5\uc815 \uc791\uc5c5\uc2dc\uac04\n\t\/\/         robot in off -> clamp bwd -> latch bwd \uc21c\uc73c\ub85c \uc2e4\ud589\n\n#undef TESe\n#ifdef TEST\n\n\t\/\/\ud14c\uc2a4\ud2b8\n\t\/\/\uac01 \uc124\ube44\uac12\uc744 \uc124\uc815\ud558\ub294 \ubd80\ubd84\n\tUA_Variant tmp_value;\n\tbool bitoff = 0;\n\tUA_Variant_setScalar(&amp;tmp_value, &amp;bitoff, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\tUA_NodeId tmpNodeId = UA_NODEID_STRING(1, \"Status\");\n\tUA_Server_writeValue(server, tmpNodeId, tmp_value);\n\n\t\/* Find the NodeId of the status child variable *\/\n\tUA_RelativePathElement rpe;\n\tUA_RelativePathElement_init(&amp;rpe);\n\trpe.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT);\n\trpe.isInverse = false;\n\trpe.includeSubtypes = true;\n\t\/\/rpe.targetName = UA_QUALIFIEDNAME(1, \"Status\");\n\trpe.targetName = UA_QUALIFIEDNAME(1, \"latch\");\n\t\/\/rpe.targetName = UA_QUALIFIEDNAME(1, \"variable\");\n\n\n\tUA_BrowsePath bp;\n\tUA_BrowsePath_init(&amp;bp);\n\tUA_NodeId *nodeId  = UA_NodeId_new();\n\t*nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);\n\t\/\/UA_NodeId tmp = {0, UA_NODEIDTYPE_NUMERIC, {50238}};\n\t\/\/printf(\"\\nNode id is %d\\n\", tmp);\n\t\/\/UA_NodeId *nodeId = &tmp;\n\tbp.startingNode = *nodeId;\n\tbp.relativePath.elementsSize = 1;\n\tbp.relativePath.elements = &rpe;\n\n\tUA_BrowsePathResult bpr =\n\t\tUA_Server_translateBrowsePathToNodeIds(server, &amp;bp);\n\tif(bpr.statusCode != UA_STATUSCODE_GOOD ||\n\t\t\tbpr.targetsSize &lt; 1)\n\t\treturn bpr.statusCode;\n\n\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"found target is %d\", bpr.targets->targetId.nodeId.identifier.numeric);\n\t\/\/print\ub85c structure\ub97c \ucd9c\ub825\ud560 \uc218 \uc5c6\uc74c.\n\t\/\/printf(\"\\nnode id is %d\\n\", (UA_NodeId)bpr.targets->targetId.nodeId);\n\t\/\/* Set the status value *\/\n\tUA_Boolean status = true;\n\tUA_Variant value;\n\tUA_Variant_setScalar(&amp;value, &amp;status, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\tUA_Server_writeValue(server, bpr.targets->targetId.nodeId, value);\n\t\/\/UA_Server_writeValue(server, tmp, value);\n\n\t\/\/\ub2e4\uc2dc \uc544\ub798\ub85c \ub0b4\ub9bc.\n\tbp.startingNode = bpr.targets->targetId.nodeId;\n\trpe.targetName = UA_QUALIFIEDNAME(1, \"Status\");\n\tUA_BrowsePathResult bpr2 =\n\t\tUA_Server_translateBrowsePathToNodeIds(server, &amp;bp);\n\tif(bpr2.statusCode != UA_STATUSCODE_GOOD ||\n\t\t\tbpr2.targetsSize &lt; 1)\n\t\treturn bpr.statusCode;\n\n\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"found target is %d\", bpr2.targets->targetId.nodeId.identifier.numeric);\n\tUA_Server_writeValue(server, bpr2.targets->targetId.nodeId, value);\n\tUA_BrowsePathResult_clear(&amp;bpr);\n#endif\n\n\t\/\/NodeId\ub97c \uc800\uc7a5\ud560 structure \uc0dd\uc131\n\tstruct eqiupNodeId{\n\t\tUA_NodeId latchNodeId;\n\t\tUA_NodeId clampNodeId;\n\t\tUA_NodeId pinNodeId;\n\t\tUA_NodeId robotNodeId;\n\t};\n\n\tstruct eqiupNodeId myEquipNodeId;\n\n\tUA_NodeId **nodeIdtmp;\n\tUA_NodeId *nodeIdtmp2 = UA_NodeId_new();\n\tnodeIdtmp = &nodeIdtmp2;\n\tUA_NodeId *nodeId  = UA_NodeId_new();\n\t*nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);\n\n\tif(\tfindNodeIdWithName(server, nodeId, \"latch\", nodeIdtmp) == UA_STATUSCODE_GOOD){\n\t\tnodeId = *nodeIdtmp;\n\t\tif( findNodeIdWithName(server, nodeId, \"Status\", nodeIdtmp) == UA_STATUSCODE_GOOD){\n\t\t\tnodeId = *nodeIdtmp;\n\t\t\tmyEquipNodeId.latchNodeId = *nodeId;\n\t\t\t\/\/printf(\"Variable \ubcc0\uacbd\\n\");\n\t\t\t\/\/* Set the status value *\/\n\t\t\t\/\/\t\t\tUA_Boolean status = false;\n\t\t\t\/\/\t\t\tUA_Variant value;\n\t\t\t\/\/\t\t\tUA_Variant_setScalar(&amp;value, &amp;status, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\t\t\t\/\/\t\t\tUA_Server_writeValue(server, *nodeId, value);\n\t\t\t\/\/\t\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"node id %d value was written\", nodeId->identifier.numeric);\n\t\t}\n\t}\n\t*nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);\n\tif(\tfindNodeIdWithName(server, nodeId, \"clamp\", nodeIdtmp) == UA_STATUSCODE_GOOD){\n\t\tnodeId = *nodeIdtmp;\n\t\tif( findNodeIdWithName(server, nodeId, \"Status\", nodeIdtmp) == UA_STATUSCODE_GOOD){\n\t\t\tnodeId = *nodeIdtmp;\n\t\t\tmyEquipNodeId.clampNodeId = *nodeId;\n\n\t\t\t\/\/printf(\"Variable \ubcc0\uacbd\\n\");\n\t\t\t\/\/* Set the status value *\/\n\t\t\t\/\/\t\t\tUA_Boolean status = false;\n\t\t\t\/\/\t\t\tUA_Variant value;\n\t\t\t\/\/\t\t\tUA_Variant_setScalar(&amp;value, &amp;status, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\t\t\t\/\/\t\t\tUA_Server_writeValue(server, *nodeId, value);\n\t\t\t\/\/\t\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"node id %d value was written\", nodeId->identifier.numeric);\n\t\t}\n\t}\n\n\t*nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);\n\tif(\tfindNodeIdWithName(server, nodeId, \"pin\", nodeIdtmp) == UA_STATUSCODE_GOOD){\n\t\tnodeId = *nodeIdtmp;\n\t\tif( findNodeIdWithName(server, nodeId, \"Status\", nodeIdtmp) == UA_STATUSCODE_GOOD){\n\t\t\tnodeId = *nodeIdtmp;\n\t\t\tmyEquipNodeId.pinNodeId = *nodeId;\n\t\t\t\/\/printf(\"Variable \ubcc0\uacbd\\n\");\n\t\t\t\/\/* Set the status value *\/\n\t\t\t\/\/\t\t\tUA_Boolean status = false;\n\t\t\t\/\/\t\t\tUA_Variant value;\n\t\t\t\/\/\t\t\tUA_Variant_setScalar(&amp;value, &amp;status, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\t\t\t\/\/\t\t\tUA_Server_writeValue(server, *nodeId, value);\n\t\t\t\/\/\t\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"node id %d value was written\", nodeId->identifier.numeric);\n\t\t}\n\t}\n\n\t*nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);\n\tif(\tfindNodeIdWithName(server, nodeId, \"Loading Robot\", nodeIdtmp) == UA_STATUSCODE_GOOD){\n\t\tnodeId = *nodeIdtmp;\n\t\tif( findNodeIdWithName(server, nodeId, \"Status\", nodeIdtmp) == UA_STATUSCODE_GOOD){\n\t\t\tnodeId = *nodeIdtmp;\n\t\t\tmyEquipNodeId.robotNodeId = *nodeId;\n\t\t\t\/\/printf(\"Variable \ubcc0\uacbd\\n\");\n\t\t\t\/\/* Set the status value *\/\n\t\t\t\/\/\t\t\tUA_Boolean status = false;\n\t\t\t\/\/\t\t\tUA_Variant value;\n\t\t\t\/\/\t\t\tUA_Variant_setScalar(&amp;value, &amp;status, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\t\t\t\/\/\t\t\tUA_Server_writeValue(server, *nodeId, value);\n\t\t\t\/\/\t\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"node id %d value was written\", nodeId->identifier.numeric);\n\t\t}\n\t}\n\n\n\t\/\/\uad6c\uc870\uccb4 \ucd9c\ub825.\n\t\/\/printf(\"\ud604\uc7ac \ub178\ub4dc\ub294 %d \\n\", myEquipNodeId.latchNodeId.identifier.numeric);\n\t\/\/printf(\"\ud604\uc7ac \ub178\ub4dc\ub294 %d \\n\", myEquipNodeId.clampNodeId.identifier.numeric);\n\t\/\/printf(\"\ud604\uc7ac \ub178\ub4dc\ub294 %d \\n\", myEquipNodeId.pinNodeId.identifier.numeric);\n\t\/\/printf(\"\ud604\uc7ac \ub178\ub4dc\ub294 %d \\n\", myEquipNodeId.robotNodeId.identifier.numeric);\n\n\t\/\/\ud55c\ubc88\uc5d0 \uc5c5\ub370\uc774\ud2b8\n\tUA_Boolean statusTrue = true;\n\tUA_Boolean statusFalse = false;\n\tUA_Variant value;\n\tUA_Variant_setScalar(&amp;value, &amp;statusFalse, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\n\t\/\/\ucd08\uae30\uc0c1\ud0dc\n\tUA_Server_writeValue(server, myEquipNodeId.latchNodeId, value);\n\tUA_Server_writeValue(server, myEquipNodeId.clampNodeId, value);\n\tUA_Server_writeValue(server, myEquipNodeId.pinNodeId, value);\n\tUA_Server_writeValue(server, myEquipNodeId.robotNodeId, value);\n\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"\ubaa8\ub4e0 \ub178\ub4dc\uac00 \ucd08\uae30\ud654(\ubaa8\ub4e0 Value\uac00 0) \ub428.\");\n\n\n\n\t\/\/\uc11c\ubc84 \uad6c\ub3d9.\n\t\/\/\uc8fc\uae30\uc801\uc73c\ub85c \uc5c5\ub370\uc774\ud2b8\ub85c \uc218\uc815\n\t\/\/https:\/\/youtu.be\/abDnBv5u6bU\/\/\n\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"Starting server...every 5 secs\");\n\tUA_StatusCode retval = UA_Server_run_startup(server);\n\n\tif(retval != UA_STATUSCODE_GOOD){\n\t\tUA_Server_delete(server);\n\t\treturn retval;\n\t}\n\n\n\tint timestamp = time(0)+5;\n\tint equipStates = 0;\n\tint seqInt = 0;\n\tbool seqFlag=false;\t\t\/\/false: \ud604\uc7ac \uc791\uc5c5 \uc911, true: \uc791\uc5c5\uc644\ub8cc \ub2e4\uc74c \uc791\uc5c5 \uc2dc\uc791\n\n\twhile(running == true){\n\t\t\/\/ Handle Server\n\t\tUA_Server_run_iterate(server, true);\n\n\n\t\t\/\/\uc0c8\ub85c\uc6b4 seq\uc744 \ud560\ub2f9 \ubc1b\uc74c\n\t\tif(seqFlag == true)\n\t\t\tseqInt = rand()%1000;\n\n\n\t\t\/\/Update Status Variable\n\t\tif(time(0) > timestamp)\n\t\t{\n\t\t\ttimestamp = time(0) + 5;\n\n\t\t\tswitch(equipStates)\n\t\t\t{\n\t\t\t\tcase 0: \/\/\ucd08\uae30\uc0c1\ud0dc\n\t\t\t\t\tequipStates = 1;\n\t\t\t\t\t\/\/seq \uae30\ub85d.\n\t\t\t\t\tUA_Variant_setScalar(&amp;value, &amp;seqInt, &amp;UA_TYPES[UA_TYPES_INT32]);\n\t\t\t\t\tUA_NodeId currentNodeId = UA_NODEID_STRING(1, \"SEQ\");\n\t\t\t\t\tUA_Server_writeValue(server, currentNodeId, value);\n\t\t\t\t\t\/\/flag \ube44\ud65c\uc131\ud654\n\t\t\t\t\tseqFlag = false;\n\n\t\t\t\t\tUA_Variant_setScalar(&amp;value, &amp;statusFalse, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.latchNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.clampNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.pinNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.robotNodeId, value);\n\t\t\t\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"\ubaa8\ub4e0 \ub178\ub4dc\uac00 \ucd08\uae30\ud654(\ubaa8\ub4e0 Value\uac00 0) \ub428.\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 1: \/\/1\ub2e8\uacc4, latch fwd\n\t\t\t\t\tequipStates = 2;\n\t\t\t\t\t\/\/flag \ube44\ud65c\uc131\ud654\n\t\t\t\t\tseqFlag = false;\n\n\t\t\t\t\tUA_Variant_setScalar(&amp;value, &amp;statusFalse, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.clampNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.pinNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.robotNodeId, value);\n\n\t\t\t\t\tUA_Variant_setScalar(&amp;value, &amp;statusTrue, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.latchNodeId, value);\n\t\t\t\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"1\ub2e8\uacc4 \ub3d9\uc791 \uc644\ub8cc..latch \uc804\uc9c4\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: \/\/2\ub2e8\uacc4, clamp fwd\n\t\t\t\t\tequipStates = 3;\n\t\t\t\t\t\/\/flag \ube44\ud65c\uc131\ud654\n\t\t\t\t\tseqFlag = false;\n\n\t\t\t\t\tUA_Variant_setScalar(&amp;value, &amp;statusFalse, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.pinNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.robotNodeId, value);\n\n\t\t\t\t\tUA_Variant_setScalar(&amp;value, &amp;statusTrue, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.latchNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.clampNodeId, value);\n\t\t\t\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"2\ub2e8\uacc4 \ub3d9\uc791 \uc644\ub8cc..calmp \uc804\uc9c4(latch, clamp \uc804\uc9c4\uc0c1\ud0dc)\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: \/\/3\ub2e8\uacc4, pin fwd\n\t\t\t\t\tequipStates = 4;\n\t\t\t\t\t\/\/flag \ube44\ud65c\uc131\ud654\n\t\t\t\t\tseqFlag = false;\n\n\t\t\t\t\tUA_Variant_setScalar(&amp;value, &amp;statusFalse, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.robotNodeId, value);\n\n\t\t\t\t\tUA_Variant_setScalar(&amp;value, &amp;statusTrue, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.latchNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.clampNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.pinNodeId, value);\n\t\t\t\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"3\ub2e8\uacc4 \ub3d9\uc791 \uc644\ub8cc..pin \uc804\uc9c4(latch, clamp, pin \uc804\uc9c4\uc0c1\ud0dc)\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 4: \/\/4\ub2e8\uacc4, robot in\n\t\t\t\t\tequipStates = 5;\n\t\t\t\t\t\/\/flag \ube44\ud65c\uc131\ud654\n\t\t\t\t\tseqFlag = false;\n\n\t\t\t\t\tUA_Variant_setScalar(&amp;value, &amp;statusTrue, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.robotNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.latchNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.clampNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.pinNodeId, value);\n\t\t\t\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"4\ub2e8\uacc4 \ub3d9\uc791 \uc644\ub8cc..robot in (latch, clamp, pin \uc804\uc9c4\uc0c1\ud0dc, robot \uc9c4\uc785)\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 5: \/\/5\ub2e8\uacc4, robot in\n\t\t\t\t\t\/\/\ub2e4\uc2dc \ucd08\uae30\uc0c1\ud0dc\ub85c \uc774\ub3d9\n\t\t\t\t\tequipStates = 0;\n\t\t\t\t\t\/\/flag \ud65c\uc131\ud654\n\t\t\t\t\tseqFlag = true;\n\n\t\t\t\t\tUA_Variant_setScalar(&amp;value, &amp;statusTrue, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.robotNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.latchNodeId, value);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.clampNodeId, value);\n\n\t\t\t\t\tUA_Variant_setScalar(&amp;value, &amp;statusFalse, &amp;UA_TYPES[UA_TYPES_BOOLEAN]);\n\t\t\t\t\tUA_Server_writeValue(server, myEquipNodeId.pinNodeId, value);\n\n\t\t\t\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"5\ub2e8\uacc4 \ub3d9\uc791 \uc644\ub8cc..pin bwd(latch, clamp, \uc804\uc9c4\uc0c1\ud0dc, robot \uc9c4\uc785, pin \ud6c4\uc9c4)\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tequipStates = 0;\n\t\t\t\t\t\/\/flag \ube44\ud65c\uc131\ud654\n\t\t\t\t\tseqFlag = false;\n\t\t\t\t\tseqInt = 0;\n\n\t\t\t\t\tbreak;\n\n\t\t\t} \/\/switch\n\n\n\t\t}\t\/\/if\n\n\n\t} \/\/while\n\n\tretval = UA_Server_run_shutdown(server);\n\t\/\/UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"Starting server...\");\n\t\/\/UA_StatusCode retval = UA_Server_run(server, &amp;running);\n\t\/\/UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"Shutdown server...\");\n\n\tUA_Server_delete(server);\n\treturn retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;\n} \/\/ main<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include \"open62541.h\"\n#include &lt;time.h>\n#include &lt;stdlib.h>\n\n\n\/\/#ifdef UA_ENABLE_METHODCALLS\n\/\/UA_StatusCode\n\/\/UA_Client_call(UA_Client *client, const UA_NodeId objectId,\n\/\/               const UA_NodeId methodId, size_t inputSize, const UA_Variant *input,\n\/\/               size_t *outputSize, UA_Variant **output);\n\/\/#endif\n\nint main(void) {\n    UA_Client *client = UA_Client_new();\n    UA_ClientConfig_setDefault(UA_Client_getConfig(client));\n    UA_StatusCode retval = UA_Client_connect(client, \"opc.tcp:\/\/localhost:4840\");\n\tprintf(\"retval is %d\\n\",retval);\n    if(retval != UA_STATUSCODE_GOOD) {\n        UA_Client_delete(client);\n        return (int)retval;\n    }\n\n\n\t\/\/NodeId\ub85c \uc870\ud68c\ud55c \uac12\uc744 \uc800\uc7a5\ud560 structure \uc0dd\uc131\n\tstruct eqiupVal {\n\t\tUA_Int32 seq;\n\t\tUA_NodeId latchNodeId;\n\t\tUA_NodeId clampNodeId;\n\t\tUA_NodeId pinNodeId;\n\t\tUA_NodeId robotNodeId;\n\t\tUA_Boolean latchVal;\n\t\tUA_Boolean clampVal;\n\t\tUA_Boolean pinVal;\n\t\tUA_Boolean robotVal;\n\t};\n\tstruct eqiupVal myEquipVal;\n\ttime_t now;\n\tstruct tm *ts;\n\n\n\n    \/* Read attribute *\/\n    UA_Int32 value2 = 0;\n    \/\/printf(\"\\nReading the value of node (1, \\\"Test Var:Me\\\"):\\n\");\n    UA_Variant *val = UA_Variant_new();\n    retval = UA_Client_readValueAttribute(client, UA_NODEID_STRING(1, \"SEQ\"), val);\n    if(retval == UA_STATUSCODE_GOOD &amp;&amp; UA_Variant_isScalar(val) &amp;&amp;\n\t\t\tval->type == &amp;UA_TYPES[UA_TYPES_INT32]) {\n\t\tvalue2 = *(UA_Int32*)val->data;\n\t\t\/\/printf(\"the value is: %i\\n\", value2);\n\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,\"current seq is %d\",value2);\n\n\t}\n\/\/#ifdef UA_ENABLE_METHODCALLS\n\/\/UA_StatusCode\n\/\/UA_Client_call(UA_Client *client, const UA_NodeId objectId,\n\/\/               const UA_NodeId methodId, size_t inputSize, const UA_Variant *input,\n\/\/               size_t *outputSize, UA_Variant **output);\n\/\/#endif\n\n\n\t\/\/method call\n\n#ifdef UA_ENABLE_METHODCALLS\n\t\/* Call a remote method *\/\n\tUA_Variant input;\n\tUA_String argString = UA_STRING(\"Hello Server\");\n\tUA_Variant_init(&amp;input);\n\t\/\/UA_Variant_setScalarCopy(&amp;input, &amp;argString, &amp;UA_TYPES[UA_TYPES_STRING]);\n\tUA_Variant_setScalarCopy(&amp;input, &amp;argString, &amp;UA_TYPES[UA_TYPES_STRING]);\n\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"input data is %s\\n\",((UA_String*)input.data)->data);\n\n\tsize_t outputSize;\n\tUA_Variant *output;\n\tretval = UA_Client_call(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),\n\t\t\tUA_NODEID_NUMERIC(1, 62541), 1, &amp;input, &amp;outputSize, &amp;output);\n\n\tif(retval == UA_STATUSCODE_GOOD) {\n\t\tprintf(\"Method call was successful, and %lu returned values available.\\n\",\n\t\t\t\t(unsigned long)outputSize);\n\n\/\/\t\tif(UA_Variant_hasScalarType(output, &amp;UA_TYPES[UA_TYPES_STRING])) { \/\/ if you are paranoid you may also want to check the dimensions\n\/\/\t\t\tUA_String value4 = *(UA_String *)output->data;\n\/\/\t\t\tprintf(\"value4 is %s\\n\",value4);\n\/\/\t\t}\n\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"output data is %s\\n\",((UA_String*)output->data)->data);\n\t\t\/\/UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, (UA_String*)output->data);\n\n\t\t\/\/UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, \"output is %s\", value4);\n\t\tUA_Array_delete(output, outputSize, &amp;UA_TYPES[UA_TYPES_VARIANT]);\n\t} else {\n\t\tprintf(\"Method call was unsuccessful, and %x returned values available.\\n\", retval);\n\t}\n\tUA_Variant_clear(&amp;input);\n#endif\n\n    \/* Browse some objects *\/\n    printf(\"Browsing nodes in objects folder:\\n\");\n    UA_BrowseRequest bReq;\n    UA_BrowseRequest_init(&amp;bReq);\n    bReq.requestedMaxReferencesPerNode = 0;\n    bReq.nodesToBrowse = UA_BrowseDescription_new();\n    bReq.nodesToBrowseSize = 1;\n    bReq.nodesToBrowse[0].nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); \/* browse objects folder *\/\n    bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; \/* return everything *\/\n    UA_BrowseResponse bResp = UA_Client_Service_browse(client, bReq);\n    printf(\"%-9s %-16s %-16s %-16s\\n\", \"NAMESPACE\", \"NODEID\", \"BROWSE NAME\", \"DISPLAY NAME\");\n    for(size_t i = 0; i &lt; bResp.resultsSize; ++i) {\n        for(size_t j = 0; j &lt; bResp.results[i].referencesSize; ++j) {\n            UA_ReferenceDescription *ref = &amp;(bResp.results[i].references[j]);\n            if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC) {\n                printf(\"%-9d %-16d %-16.*s %-16.*s\\n\", ref->nodeId.nodeId.namespaceIndex,\n                       ref->nodeId.nodeId.identifier.numeric, (int)ref->browseName.name.length,\n                       ref->browseName.name.data, (int)ref->displayName.text.length,\n                       ref->displayName.text.data);\n            } else if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING) {\n                printf(\"%-9d %-16.*s %-16.*s %-16.*s\\n\", ref->nodeId.nodeId.namespaceIndex,\n                       (int)ref->nodeId.nodeId.identifier.string.length,\n                       ref->nodeId.nodeId.identifier.string.data,\n                       (int)ref->browseName.name.length, ref->browseName.name.data,\n                       (int)ref->displayName.text.length, ref->displayName.text.data);\n            }\n            \/* TODO: distinguish further types *\/\n\t\t\t\/\/\uc544\ub798 \ubb38\uc7a5\uc73c\ub85c client \ubaa8\ub4e0 brwose\ub97c \uc811\uadfc\ud560 \uc218 \uc788\uc74c.\n\t\t\t\/\/\ud55c \ub2e8\uacc4 \uc544\ub798\ub9cc \ubcf4\uc784.\n\t\t\t\/\/UA_BrowseResponse bResp = UA_Client_Service_browse(client, bReq);\n\n\n\t\t\t\/\/ object class \ub9cc \ucc3e\uc544 node\ub85c \uae30\ub85d.\n\t\t\tif(ref->nodeClass == UA_NODECLASS_OBJECT &amp;&amp;\n\t\t\t\t\t!strcmp(ref->browseName.name.data, \"Loading Robot\")){\n\t\t\t\tprintf(\"\\nNODE CLASS OBJECT\\n\");\n\t\t\t\t\/\/\uc784\uc2dc\ub85c node ID\ub97c \uc800\uc7a5\n\t\t\t\tmyEquipVal.robotNodeId = (UA_NodeId)ref->nodeId.nodeId;\n\t\t\t}\n\t\t\t\/\/ object class \ub9cc \ucc3e\uc544 node\ub85c \uae30\ub85d.\n\t\t\tif(ref->nodeClass == UA_NODECLASS_OBJECT &amp;&amp;\n\t\t\t\t\t!strcmp(ref->browseName.name.data, \"pin\")){\n\t\t\t\tprintf(\"\\nNODE CLASS OBJECT\\n\");\n\t\t\t\t\/\/\uc784\uc2dc\ub85c node ID\ub97c \uc800\uc7a5\n\t\t\t\tmyEquipVal.pinNodeId = (UA_NodeId)ref->nodeId.nodeId;\n\t\t\t}\n\n\t\t\tif(ref->nodeClass == UA_NODECLASS_OBJECT &amp;&amp;\n\t\t\t\t\t!strcmp(ref->browseName.name.data, \"latch\")){\n\t\t\t\tprintf(\"\\nNODE CLASS OBJECT\\n\");\n\t\t\t\t\/\/\uc784\uc2dc\ub85c node ID\ub97c \uc800\uc7a5\n\t\t\t\tmyEquipVal.latchNodeId = (UA_NodeId)ref->nodeId.nodeId;\n\t\t\t}\n\t\t\tif(ref->nodeClass == UA_NODECLASS_OBJECT &amp;&amp;\n\t\t\t\t\t!strcmp(ref->browseName.name.data, \"clamp\")){\n\t\t\t\tprintf(\"\\nNODE CLASS OBJECT\\n\");\n\t\t\t\t\/\/\uc784\uc2dc\ub85c node ID\ub97c \uc800\uc7a5\n\t\t\t\tmyEquipVal.clampNodeId = (UA_NodeId)ref->nodeId.nodeId;\n\t\t\t}\n\n        }\n    }\n    UA_BrowseRequest_clear(&amp;bReq);\n\tUA_BrowseResponse_clear(&amp;bResp);\n\n\t\/\/\uc5bb\uc740 \ub370\uc774\ud130\ub85c value\uac12\uc744 \ucc3e\uae30 \uc704\ud55c nodeId \ud655\uc778\n\t\/\/BaseDataType\uc744 \uc5bb\uc5b4\ub0b4\uc57c \ud568\n\tUA_BrowseRequest_init(&amp;bReq);\n\tbReq.requestedMaxReferencesPerNode = 0;\n\tbReq.requestedMaxReferencesPerNode = 0;\n    bReq.nodesToBrowse = UA_BrowseDescription_new();\n\tbReq.nodesToBrowseSize = 1;\n\tbReq.nodesToBrowse[0].nodeId = myEquipVal.robotNodeId; \/* browse objects folder *\/\n    bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; \/* return everything *\/\n\t\/\/bResp\ub85c \ub2e4\uc2dc query\n\tbResp = UA_Client_Service_browse(client, bReq);\n\tfor(size_t i = 0; i &lt; bResp.resultsSize; ++i) {\n\t\tfor(size_t j = 0; j &lt; bResp.results[i].referencesSize; ++j) {\n\t\t\tUA_ReferenceDescription *ref = &amp;(bResp.results[i].references[j]);\n\t\t\t\/\/robot\n\t\t\tif(ref->nodeClass == UA_NODECLASS_VARIABLE &amp;&amp;\n\t\t\t\t\t!strcmp(ref->browseName.name.data, \"Status\")){\n\t\t\t\tprintf(\"found\\n\");\n\t\t\t\tmyEquipVal.robotNodeId = (UA_NodeId)ref->nodeId.nodeId;\n\t\t\t}\n\t\t\t\n\t\t}\n\t}\n\n\tbReq.nodesToBrowse[0].nodeId = myEquipVal.latchNodeId; \/* browse objects folder *\/\n    bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; \/* return everything *\/\n\t\/\/bResp\ub85c \ub2e4\uc2dc query\n\tbResp = UA_Client_Service_browse(client, bReq);\n\tfor(size_t i = 0; i &lt; bResp.resultsSize; ++i) {\n\t\tfor(size_t j = 0; j &lt; bResp.results[i].referencesSize; ++j) {\n\t\t\tUA_ReferenceDescription *ref = &amp;(bResp.results[i].references[j]);\n\t\t\t\/\/robot\n\t\t\tif(ref->nodeClass == UA_NODECLASS_VARIABLE &amp;&amp;\n\t\t\t\t\t!strcmp(ref->browseName.name.data, \"Status\")){\n\t\t\t\tprintf(\"found\\n\");\n\t\t\t\tmyEquipVal.latchNodeId = (UA_NodeId)ref->nodeId.nodeId;\n\t\t\t}\n\t\t\t\n\t\t}\n\t}\n\tbReq.nodesToBrowse[0].nodeId = myEquipVal.pinNodeId; \/* browse objects folder *\/\n    bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; \/* return everything *\/\n\t\/\/bResp\ub85c \ub2e4\uc2dc query\n\tbResp = UA_Client_Service_browse(client, bReq);\n\tfor(size_t i = 0; i &lt; bResp.resultsSize; ++i) {\n\t\tfor(size_t j = 0; j &lt; bResp.results[i].referencesSize; ++j) {\n\t\t\tUA_ReferenceDescription *ref = &amp;(bResp.results[i].references[j]);\n\t\t\t\/\/robot\n\t\t\tif(ref->nodeClass == UA_NODECLASS_VARIABLE &amp;&amp;\n\t\t\t\t\t!strcmp(ref->browseName.name.data, \"Status\")){\n\t\t\t\tprintf(\"found\\n\");\n\t\t\t\tmyEquipVal.pinNodeId = (UA_NodeId)ref->nodeId.nodeId;\n\t\t\t}\n\t\t\t\n\t\t}\n\t}\n\n\tbReq.nodesToBrowse[0].nodeId = myEquipVal.clampNodeId; \/* browse objects folder *\/\n    bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; \/* return everything *\/\n\t\/\/bResp\ub85c \ub2e4\uc2dc query\n\tbResp = UA_Client_Service_browse(client, bReq);\n\tfor(size_t i = 0; i &lt; bResp.resultsSize; ++i) {\n\t\tfor(size_t j = 0; j &lt; bResp.results[i].referencesSize; ++j) {\n\t\t\tUA_ReferenceDescription *ref = &amp;(bResp.results[i].references[j]);\n\t\t\t\/\/robot\n\t\t\tif(ref->nodeClass == UA_NODECLASS_VARIABLE &amp;&amp;\n\t\t\t\t\t!strcmp(ref->browseName.name.data, \"Status\")){\n\t\t\t\tprintf(\"found\\n\");\n\t\t\t\tmyEquipVal.clampNodeId = (UA_NodeId)ref->nodeId.nodeId;\n\t\t\t}\n\t\t\t\n\t\t}\n\t}\n    UA_BrowseRequest_clear(&amp;bReq);\n\tUA_BrowseResponse_clear(&amp;bResp);\n\n\n\tfor(int i=0;i&lt;100;i++){\n\n    \/* Read attribute *\/\n    UA_Int32 value2 = 0;\n    \/\/printf(\"\\nReading the value of node (1, \\\"Test Var:Me\\\"):\\n\");\n    retval = UA_Client_readValueAttribute(client, UA_NODEID_STRING(1, \"SEQ\"), val);\n    if(retval == UA_STATUSCODE_GOOD &amp;&amp; UA_Variant_isScalar(val) &amp;&amp;\n\t\t\tval->type == &amp;UA_TYPES[UA_TYPES_INT32]) {\n\t\t\/\/value2 = *(UA_Int32*)val->data;\n\t\t\/\/printf(\"the value is: %i\\n\", value2);\n\t\t\/\/UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,\"current seq is %d\",value2);\n\t\tmyEquipVal.seq = *(UA_Int32*)val->data;\n\n\t}\n\n\t\t\/\/nodeId\ub85c Value\ub97c \uc5bb\uc74c. \n\t\tretval = UA_Client_readValueAttribute(client, myEquipVal.pinNodeId , val);\n\t\tif(retval == UA_STATUSCODE_GOOD &amp;&amp; UA_Variant_isScalar(val) &amp;&amp;\n\t\t\t\tval->type == &amp;UA_TYPES[UA_TYPES_BOOLEAN]) {\n\t\t\tmyEquipVal.pinVal = *(UA_Boolean*)val->data;\n\t\t\t\/\/UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,\"node id 50232(pin) is %d\", *(UA_Boolean*)val->data);\n\t\t}\n\n\t\t\/\/nodeId\ub85c Value\ub97c \uc5bb\uc74c. \n\t\tretval = UA_Client_readValueAttribute(client, myEquipVal.robotNodeId, val);\n\t\tif(retval == UA_STATUSCODE_GOOD &amp;&amp; UA_Variant_isScalar(val) &amp;&amp;\n\t\t\t\tval->type == &amp;UA_TYPES[UA_TYPES_BOOLEAN]) {\n\t\t\tmyEquipVal.robotVal = *(UA_Boolean*)val->data;\n\t\t\t\/\/UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,\"node id 50246(robot) is %d\", *(UA_Boolean*)val->data);\n\t\t}\n\n\t\t\/\/nodeId\ub85c Value\ub97c \uc5bb\uc74c. \n\t\tretval = UA_Client_readValueAttribute(client, myEquipVal.clampNodeId, val);\n\t\tif(retval == UA_STATUSCODE_GOOD &amp;&amp; UA_Variant_isScalar(val) &amp;&amp;\n\t\t\t\tval->type == &amp;UA_TYPES[UA_TYPES_BOOLEAN]) {\n\t\t\tmyEquipVal.clampVal = *(UA_Boolean*)val->data;\n\t\t\t\/\/UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,\"node id 50238(clamp) is %d\", *(UA_Boolean*)val->data);\n\t\t}\n\n\t\t\/\/nodeId\ub85c Value\ub97c \uc5bb\uc74c. \n\t\tretval = UA_Client_readValueAttribute(client, myEquipVal.latchNodeId, val);\n\t\tif(retval == UA_STATUSCODE_GOOD &amp;&amp; UA_Variant_isScalar(val) &amp;&amp;\n\t\t\t\tval->type == &amp;UA_TYPES[UA_TYPES_BOOLEAN]) {\n\t\t\tmyEquipVal.latchVal = *(UA_Boolean*)val->data;\n\t\t\t\/\/UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,\"node id 50235(latch) is %d\", *(UA_Boolean*)val->data);\n\t\t}\n\n\n\t\t\/\/\/printf(\"myEquipVal is\\n\");\n\t\t\/\/\/printf(\"pin is %d\\n\", myEquipVal.pinVal);\n\t\t\/\/\/printf(\"robot is %d\\n\", myEquipVal.robotVal);\n\t\t\/\/\/printf(\"latch is %d\\n\", myEquipVal.latchVal);\n\t\t\/\/\/printf(\"clamp is %d\\n\", myEquipVal.clampVal);\n\t\tnow = time(NULL);\n\t\tts = localtime(&amp;now);\n\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,\"%d cylcle read \uc644\ub8cc\",i);\n\t\tUA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,\"%d-%d-%d, %d:%d:%d, seq,%d,latch,%d, clamp,%d, pin,%d,robot,%d.\",\n\t\t\t\t\/\/ts 3\uac1c +3\uac1c \uc22b\uc790.\ub144\uc6d4\uc77c + \uc2dc\uac01:\ubd84:\ucd08\n\t\t\t\tts->tm_year+1900, ts->tm_mon+1, ts->tm_mday,\n\t\t\t\tts->tm_hour, ts->tm_min, ts->tm_sec,\n\t\t\t\tmyEquipVal.seq,\n\t\t\t\tmyEquipVal.latchVal,myEquipVal.clampVal,\n\t\t\t\tmyEquipVal.pinVal, myEquipVal.robotVal);\n\n\t\tsleep(3);\n\t}\n\n\n\tUA_Variant_delete(val);\n\t\/* Clean up *\/\n\t\/\/\tUA_Variant_clear(&amp;value);\n\tUA_Variant_clear(&amp;value2);\n\n\tUA_Client_delete(client); \/* Disconnects the client internally *\/\n\treturn EXIT_SUCCESS;\n}<\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ucc98\uc74c \uc124\uc815\ud55c \ubaa9\ud45c\ub97c \ub4dc\ub514\uc5b4 \uc218\ud589\ud588\ub2e4. \uc11c\ubc84\ub97c \ub300\ub7b5 \uad6c\ud604\ud588\uc73c\ub2c8 \ub2e4\uc74c\uc73c\ub85c \ud074\ub77c\uc774\uc5b8\ud2b8\ub97c \ub9cc\ub4e4\uc5c8\ub2e4. \ub0b4\uac00 \ucabc\ub7a9\uc774\ub77c tutorial \ubb38\uc11c \uadf8\ub300\ub85c \uc0ac\uc6a9\ud588\ub2e4. cilent\ub294 UA_Client_Service_browse\ub85c server\uac00 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[12],"tags":[807,808,745,798],"class_list":["post-4072","post","type-post","status-publish","format-standard","hentry","category-12","tag-opcua","tag-open62541","tag-plc","tag-raspberry"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/posts\/4072","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/comments?post=4072"}],"version-history":[{"count":4,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/posts\/4072\/revisions"}],"predecessor-version":[{"id":4079,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/posts\/4072\/revisions\/4079"}],"wp:attachment":[{"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/media?parent=4072"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/categories?post=4072"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/now0930.pe.kr\/wordpress\/wp-json\/wp\/v2\/tags?post=4072"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}