如何使用 FIWARE OPC UA AGENT

问题描述

目标

使用 Fiware OPC UA 代理更改 OPC UA 服务器上的可写值。

我的测试实现

  1. 将 NodeId“7:PLC1_7:G_Communication_7:fi_heartbeat_i”添加到 config.json 文件中的“command”和“contextSubscription”部分。 NodeId的值数据类型是Int16,但是因为这个值是要写的,所以我假设必须使用“command”作为类型。遗憾的是,手册 fiware opcua agent 中找不到更详细的信息。
  2. 使用 Opcua 代理、Orion 上下文代理和 mongodb 启动新的测试环境。

预期行为

当请求发送到上下文代理时,服务器上的值会更新。

当前行为

  • 参数值被正确读取,但数据类型不正确(字符串而不是整数)。
  • 将请求发送到 Orion 上下文代理时,不会更新参数值。

其他信息

  1. config.json
     {
      "logLevel" : "DEBUG","contextbroker" : {
        "host" : "orion","port" : 1026
      },"server" : {
        "port" : 4001,"baseRoot" : "/"
      },"deviceRegistry" : {
        "type" : "memory"
      },"mongodb" : {
        "host" : "iotmongo","port" : "27017","db" : "iotagent","retries" : 5,"retryTime" : 5
      },"providerUrl" : "http://iotopcua:4001","pollingExpiration" : "200000","pollingDaemonFrequency" : "20000","deviceRegistrationDuration" : "P1M","defaultType" : null,"browseServerOptions" : null,"service" : "test","subservice" : "/test","types" : {
        "g_communication" : {
          "service" : "test","active" : [{
            "name" : "7:PLC1_7:G_Communication_7:fo_smartControllerActive_b","type" : "Boolean"
          } ],"lazy" : [ ],"commands" : [{
            "name" : "7:PLC1_7:G_Communication_7:fi_heartbeat_i","type" : "Command"  
            }]
        }
      },"contexts" : [ {
            "id" : "plant","type" : "g_communication","polling" : null,"mappings" : [{
              "ocb_id" : "7:PLC1_7:G_Communication_7:fo_smartControllerActive_b","opcua_id" : "ns=7;s=G_Communication.fo_smartControllerActive_b","object_id" : null,"inputArguments" : []
            } ]
      }],"contextSubscriptions" : [{ 
            "id" : "plant","mappings" : [{
              "ocb_id" : "7:PLC1_7:G_Communication_7:fi_heartbeat_i","opcua_id" : "ns=7;s=G_Communication.fi_heartbeat_i","object_id" : "ns=7;s=G_Communication","inputArguments" : [{
                 "type": "Number"
              }]
            }]
        }]
    }
  1. 列出实体
curl 'http://localhost:1026/v2/entities/plant/' -H 'fiware-service: test' -H 'fiwate-servicepath: /test' | python -m json.tool
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                Dload  Upload   Total   Spent    Left  Speed
100   684  100   684    0     0  13751      0 --:--:-- --:--:-- --:--:-- 13959
{
   "7:PLC1_7:G_Communication_7:fi_heartbeat_i": {
       "Metadata": {
           "ServerTimestamp": {
               "type": "ISO8601","value": "null"
           },"SourceTimestamp": {
               "type": "ISO8601","value": "null"
           }
       },"type": "string","value": "4"
   },"7:PLC1_7:G_Communication_7:fi_heartbeat_i_info": {
       "Metadata": {},"type": "commandResult","value": " "
   },"7:PLC1_7:G_Communication_7:fi_heartbeat_i_status": {
       "Metadata": {},"type": "commandStatus","value": "UNKNowN"
   },"7:PLC1_7:G_Communication_7:fo_smartControllerActive_b": {
       "Metadata": {
           "ServerTimestamp": {
               "type": "ISO8601","value": "2021-05-04T07:38:01.150Z"
           },"value": "2021-05-04T07:37:59.934Z"
           }
       },"type": "Boolean","value": false
   },"id": "plant","type": "g_communication"
}
  1. 注册
curl 'http://localhost:1026/v2/registrations'  -H 'fiware-service: test' -H 'fiwate-servicepath: /test' | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   320  100   320    0     0  46049      0 --:--:-- --:--:-- --:--:-- 53333
[
    {
        "dataProvided": {
            "attrs": [
                "7:PLC1_7:G_Communication_7:fi_heartbeat_i"
            ],"entities": [
                {
                    "id": "plant","type": "g_communication"
                }
            ]
        },"expires": "2021-06-03T07:37:38.00Z","id": "6090f9c254b918756abf1a7d","provider": {
            "http": {
                "url": "http://iotopcua:4001"
            },"legacyForwarding": true,"supportedForwardingMode": "all"
        },"status": "active"
    }
]
  1. 测试与 iotopcua 的通信
 curl "http://iotopcua:4001/version"
{"libVersion":"2.12.0-next","port":4001,"baseRoot":"/"}
  1. 请求更新
curl -X PUT \
  'http://localhost:1026/v2/entities/plant/attrs/7:PLC1_7:G_Communication_7:fi_heartbeat_i?type=g_communication' \
  -H 'content-type: application/json' \
  -H 'fiware-service: test' \
  -H 'fiware-servicepath: /test' \
  -d '{
  "value": 2
  }'
  1. 记录 OCB
from=0.0.0.0 | srv=test | subsrv=/test | comp=Orion | op=logMsg.h[1844]:lmTransactionStart | msg=Starting transaction from 0.0.0.0:54232/v2/entities/plant/attrs/7:PLC1_7:G_Communication_7:fi_heartbeat_i
from=0.0.0.0 | srv=test | subsrv=/test | comp=Orion | op=rest.cpp[874]:servicePathSplit | msg=Service Path 0: '/test'
from=0.0.0.0 | srv=test | subsrv=/test | comp=Orion | op=connectionoperations.cpp[244]:collectionCount | msg=Database Operation Successful (count: { _id.id: "plant",_id.type: "g_communication",_id.servicePath: "/test" })
from=0.0.0.0 | srv=test | subsrv=/test | comp=Orion | op=connectionoperations.cpp[94]:collectionQuery | msg=Database Operation Successful (query: { _id.id: "plant",_id.servicePath: "/test" })
from=0.0.0.0 | srv=test | subsrv=/test | comp=Orion | op=connectionoperations.cpp[182]:collectionRangedQuery | msg=Database Operation Successful (query: { query: { $or: [ { contextRegistration.entities.id: "plant",contextRegistration.entities.type: "g_communication" },{ contextRegistration.entities.id: ".*",contextRegistration.entities.isPattern: "true",contextRegistration.entities.type: { $in: [ "g_communication" ] } },contextRegistration.entities.type: { $exists: false } } ],expiration: { $gt: 1620114947 },contextRegistration.attrs.name: { $in: [ "7:PLC1_7:G_Communication_7:fi_heartbeat_i" ] },servicePath: "/test" },orderby: { _id: 1 } })
from=0.0.0.0 | srv=test | subsrv=/test | comp=Orion | op=logMsg.h[1844]:lmTransactionStart | msg=Starting transaction to http://iotopcua:4001//updateContext
from=0.0.0.0 | srv=test | subsrv=/test | comp=Orion | op=httpRequestSend.cpp[550]:httpRequestSendWithCurl | msg=Sending message 4 to HTTP server: sending message of 458 bytes to HTTP server
from=10.1.17.1 | srv=test | subsrv=/test | comp=Orion | op=logMsg.h[1844]:lmTransactionStart | msg=Starting transaction from 10.1.17.1:58162/v1/updateContext
from=10.1.17.1 | srv=test | subsrv=/test | comp=Orion | op=rest.cpp[874]:servicePathSplit | msg=Service Path 0: '/test'
from=10.1.17.1 | srv=test | subsrv=/test | comp=Orion | op=connectionoperations.cpp[94]:collectionQuery | msg=Database Operation Successful (query: { _id.id: "plant",_id.servicePath: "/test" })
from=10.1.17.1 | srv=test | subsrv=/test | comp=Orion | op=connectionoperations.cpp[454]:collectionUpdate | msg=Database Operation Successful (update: <{ _id.id: "plant",_id.servicePath: "/test" },{ $set: { attrs.7:PLC1_7:G_Communication_7:fi_heartbeat_i_status: { value: "PENDING",type: "commandStatus",mdNames: [],creDate: 1620113858,modDate: 1620114947 },modDate: 1620114947,lastCorrelator: "2324ca1e-acae-11eb-a4f7-226cad26e2cc" },$unset: { location: 1,expDate: 1 } }>)
from=10.1.17.1 | srv=test | subsrv=/test | comp=Orion | op=logMsg.h[1874]:lmTransactionEnd | msg=Transaction ended
from=0.0.0.0 | srv=test | subsrv=/test | comp=Orion | op=httpRequestSend.cpp[570]:httpRequestSendWithCurl | msg=Notification Successfully Sent to http://iotopcua:4001//updateContext
from=0.0.0.0 | srv=test | subsrv=/test | comp=Orion | op=httpRequestSend.cpp[579]:httpRequestSendWithCurl | msg=Notification response OK,http code: 200
from=0.0.0.0 | srv=test | subsrv=/test | comp=Orion | op=logMsg.h[1874]:lmTransactionEnd | msg=Transaction ended
  1. 登录 OPcua 客户端
time=2021-05-04T07:55:47.191Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.GenericMiddlewares | msg=Request for path [//updateContext] from [iotopcua:4001]
time=2021-05-04T07:55:47.191Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.GenericMiddlewares | msg=Body:

{
    "contextElements": [
        {
            "type": "g_communication","isPattern": "false","attributes": [
                {
                    "name": "7:PLC1_7:G_Communication_7:fi_heartbeat_i","type": "Number","value": 2
                }
            ]
        }
    ],"updateAction": "UPDATE"
}


time=2021-05-04T07:55:47.193Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.ContextServer | msg=Handling update from [iotopcua:4001]
time=2021-05-04T07:55:47.193Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.ContextServer | msg=[object Object]
time=2021-05-04T07:55:47.194Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.InMemoryGroupRegister | msg=Looking for device params ["service","subservice","type"]
time=2021-05-04T07:55:47.194Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.DeviceService | msg=deviceData after merge with conf: {"id":"plant","name":"plant","type":"g_communication","active":[{"name":"7:PLC1_7:G_Communication_7:fo_smartControllerActive_b","type":"Boolean","object_id":"7:PLC1_7:G_Communication_7:fo_smartControllerActive_b"}],"service":"test","subservice":"/test","polling":null,"endpoint":"opc.tcp://109.68.106.155:48050","registrationId":"6090f9c254b918756abf1a7d","creationDate":1620113858802}
time=2021-05-04T07:55:47.194Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.DeviceService | msg=deviceData before merge with conf: {"id":"plant","lazy":[],"commands":[{"name":"7:PLC1_7:G_Communication_7:fi_heartbeat_i","type":"Command","object_id":"7:PLC1_7:G_Communication_7:fi_heartbeat_i"}],"creationDate":1620113858802,"internalAttributes":null,"staticAttributes":[],"subscriptions":[]}
time=2021-05-04T07:55:47.195Z | lvl=INFO | corr=n/a | trans=n/a | op=Index.CommandContextHandler | comp=iotAgent-OPcua | srv=test | subsrv=/test | msg=method to call =[{"objectId":"ns=7;s=G_Communication","methodId":"ns=7;s=G_Communication.fi_heartbeat_i","inputArguments":[{"type":"Number"}]}]
time=2021-05-04T07:55:47.879Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.NGSIService | msg=executeWithDeviceInfo entityName plant type undefined apikey undefined attributes [{"name":"7:PLC1_7:G_Communication_7:fi_heartbeat_i_status","type":"commandStatus","value":"PENDING"}] deviceinformation {"id":"plant","subscriptions":[]}
time=2021-05-04T07:55:47.879Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.NGSIService | msg=error {"name":"DEVICE_GROUP_NOT_FOUND","message":"Couldn\t find device group","code":404} in get group device
time=2021-05-04T07:55:47.880Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.NGSIService | msg=typeinformation {"id":"plant","subscriptions":[]}
time=2021-05-04T07:55:47.880Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.NGSIService | msg=Updating device value in the Context broker at [http://orion:1026/v1/updateContext]
time=2021-05-04T07:55:47.880Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.NGSIService | msg=Using the following request:

{
    "url": "http://orion:1026/v1/updateContext","method": "POST","headers": {
        "fiware-service": "test","fiware-servicepath": "/test"
    },"json": {
        "contextElements": [
            {
                "type": "g_communication","attributes": [
                    {
                        "name": "7:PLC1_7:G_Communication_7:fi_heartbeat_i_status","value": "PENDING"
                    }
                ]
            }
        ],"updateAction": "UPDATE"
    }
}


time=2021-05-04T07:55:47.886Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.NGSIService | msg=Received the following request from the CB:

{
    "contextResponses": [
        {
            "contextElement": {
                "type": "g_communication","value": ""
                    }
                ]
            },"statusCode": {
                "code": "200","reasonPhrase": "OK"
            }
        }
    ]
}


time=2021-05-04T07:55:47.886Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.NGSIService | msg=Value updated successfully
time=2021-05-04T07:55:47.886Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.ContextServer | msg=Update action from [iotopcua:4001] handled successfully.
time=2021-05-04T07:55:47.886Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.ContextServer | msg=Generated update response: {"contextResponses":[{"contextElement":{"attributes":[{"name":"7:PLC1_7:G_Communication_7:fi_heartbeat_i","type":"Number","value":""}],"id":"plant","isPattern":false,"type":"g_communication"},"statusCode":{"code":200,"reasonPhrase":"OK"}}]}
time=2021-05-04T07:55:47.887Z | lvl=DEBUG | corr=n/a | trans=n/a | op=IoTAgentNGSI.DomainControl | msg=response-time: 697

解决方法

据我所知,我认为错误存在于 config.json 中的 contextSubscription 片段中,它应该如下所示:

"contextSubscriptions": [{
  "id": "plant","type": "g_communication","service": "test","subservice": "/test","mappings": [{
    "ocb_id": "7:PLC1_7:G_Communication_7:fi_heartbeat_i","opcua_id": "ns=7;s=G_Communication.fi_heartbeat_i","object_id": "ns=7;s=G_Communication","inputArguments": [{
      "dataType": 4,"type": "Intensity"
    }]
  }]
}]

可以试试吗?