使用 IOT 代理 JSON 和 Orion LD 通过双向属性配置设备时出现问题

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

我有一个物联网设备,在运行时有一些可配置的参数。该参数可以由设备用户配置,也可以由设备配置(在某些情况下可以重新配置自身以优化功耗)。设备通过 HTTP 进行通信,并且没有配置端点,因此在发送测量结果时必须接收配置更新。

我正在使用 Orion LD 和 IOT 代理 JSON。为了解决这个场景,我决定使用双向属性,因为这些参数可以由设备和最终用户修改,并且不是真正的执行器。尽管如此,我在配置这个时遇到了一些问题。

我正在使用以下 docker compose 文件部署 Orion LD、IOT 代理 JSON 和上下文服务器:

version: "3.8"
services:

  ngsi-ld-context-server:
    image: nginx:latest
    hostname: ngsi-ld-context-server
    container_name: ngsi-ld-context-server
    networks:
      - fiware
    ports:
      - "9090:80"
    volumes:
      - ./ngsild-context.jsonld:/usr/share/nginx/html/ngsild-context.jsonld

  fiware-mongo-db:
    image: mongo:4.4
    hostname: fiware-mongo-db
    container_name: fiware-mongo-db
    networks:
      - fiware
    ports:
      - "27017:27017"

  orion-ld:
    platform: linux/amd64
    image: quay.io/fiware/orion-ld:1.4.0
    hostname: orion-ld
    container_name: orion-ld
    networks:
      - fiware
    depends_on:
      - fiware-mongo-db
    ports:
      - "1026:1026"
    command: -dbhost fiware-mongo-db -logLevel DEBUG -forwarding -experimental

  iot-agent-json:
    image: quay.io/fiware/iotagent-json:2.2.0
    hostname: iot-agent-json
    container_name: iot-agent-json
    networks:
      - fiware
    depends_on:
      - fiware-mongo-db
      - orion-ld
    ports:
      - "4041:4041"
      - "7896:7896"
    environment:
      - IOTA_CB_HOST=orion-ld 
      - IOTA_CB_PORT=1026
      - IOTA_NORTH_PORT=4041
      - IOTA_REGISTRY_TYPE=mongodb 
      - IOTA_LOG_LEVEL=DEBUG 
      - IOTA_TIMESTAMP=true 
      - IOTA_AUTOCAST=true 
      - IOTA_MONGO_HOST=fiware-mongo-db 
      - IOTA_MONGO_PORT=27017
      - IOTA_MONGO_DB=iotagenjson 
      - IOTA_HTTP_PORT=7896
      - IOTA_PROVIDER_URL=http://iot-agent-json:4041
      - IOTA_DEFAULT_RESOURCE=/iot/json

      - IOTA_CB_NGSI_VERSION=ld 
      - IOTA_JSON_LD_CONTEXT=http://ngsi-ld-context-server/ngsild-context.jsonld
      - IOTA_FALLBACK_TENANT=openiot

networks:
  fiware:
    driver: bridge

首先,我为设备创建一个服务:

{
    "services": [
        {
            "apikey": "4jggokgpepnvsb2uv4s40d59ov",
            "cbroker": "http://orion-ld:1026",
            "entity_type": "Device",
            "resource": "/iot/json"
        }
    ]
}

然后我尝试按照 IOT 代理 NGSILD 教程配置双向属性 (没有提供端点,因为我想轮询):

{
  "devices": [
    {
      "device_id": "device001",
      "entity_name": "urn:ngsi-ld:Device:device001",
      "entity_type": "Device",
      "attributes": [
        {
            "name": "sampleTime",
            "type": "Property",
            "reverse": [
                {
                    "object_id": "sampleTime",
                    "type": "Property"
                }
            ]
        }
      ]
    }
  ]
}

但我得到以下回复:

{
    "name": "ENTITY_GENERIC_ERROR",
    "message": "Error accesing entity data for device: urn:ngsi-ld:Device:device001 of type: Device"
}

查看 IOT 代理日志,我发现它正在尝试创建具有空属性的 Orion 订阅,这是不允许的:

time=2023-08-31T06:36:43.764Z | lvl=DEBUG | corr=1cfae922-438d-473a-9511-1f4fe7ad9f3e | trans=1cfae922-438d-473a-9511-1f4fe7ad9f3e | op=IoTAgentNGSI.BidirectionalPlugin | from=n/a | srv=n/a | subsrv=n/a | msg=Extracted variables: [] | comp=IoTAgent
time=2023-08-31T06:36:43.765Z | lvl=DEBUG | corr=1cfae922-438d-473a-9511-1f4fe7ad9f3e | trans=1cfae922-438d-473a-9511-1f4fe7ad9f3e | op=IoTAgentNGSI.RestUtils | from=n/a | srv=n/a | subsrv=n/a | msg=executeWithSecurity | comp=IoTAgent
time=2023-08-31T06:36:43.765Z | lvl=DEBUG | corr=1cfae922-438d-473a-9511-1f4fe7ad9f3e | trans=1cfae922-438d-473a-9511-1f4fe7ad9f3e | op=IoTAgentNGSI.MongoDBGroupRegister | from=n/a | srv=n/a | subsrv=n/a | msg=Looking for group params ["type"] with queryObj {"type":"Device"} | comp=IoTAgent
time=2023-08-31T06:36:43.768Z | lvl=DEBUG | corr=1cfae922-438d-473a-9511-1f4fe7ad9f3e | trans=1cfae922-438d-473a-9511-1f4fe7ad9f3e | op=IoTAgentNGSI.MongoDBGroupRegister | from=n/a | srv=openiot | subsrv=/ | msg=Device group data found: {"_id":"64f033436e41de0d07b70359","resource":"/iot/json","apikey":"4jggokgpepnvsb2uv4s40d59ov","type":"Device","service":"openiot","subservice":"/"} | comp=IoTAgent
time=2023-08-31T06:36:43.769Z | lvl=DEBUG | corr=1cfae922-438d-473a-9511-1f4fe7ad9f3e | trans=1cfae922-438d-473a-9511-1f4fe7ad9f3e | op=IoTAgentNGSI.Request | from=n/a | srv=openiot | subsrv=/ | msg=Options: {
    "method": "POST",
    "headers": {
        "fiware-service": "openiot",
        "fiware-servicepath": "/",
        "NGSILD-Tenant": "openiot",
        "NGSILD-Path": "/",
        "Content-Type": "application/ld+json"
    },
    "json": {
        "@context": "http://ngsi-ld-context-server/ngsild-context.jsonld",
        "type": "Subscription",
        "entities": [
            {
                "id": "urn:ngsi-ld:Device:device001",
                "type": "Device"
            }
        ],
        "watchedAttributes": [
            "sampleTime"
        ],
        "notification": {
            "endpoint": {
                "uri": "http://iot-agent-json:4041/notify",
                "accept": "application/json"
            },
            "attributes": [],
            "format": "normalized"
        }
    },
    "uri": "http://orion-ld:1026/ngsi-ld/v1/subscriptions/"
} | comp=IoTAgent
time=2023-08-31T06:36:43.786Z | lvl=DEBUG | corr=1cfae922-438d-473a-9511-1f4fe7ad9f3e | trans=1cfae922-438d-473a-9511-1f4fe7ad9f3e | op=IoTAgentNGSI.Request | from=n/a | srv=openiot | subsrv=/ | msg=Response {
    "type": "https://uri.etsi.org/ngsi-ld/errors/BadRequestData",
    "title": "Empty Array",
    "detail": "Subscription::notification::attributes"
} | comp=IoTAgent
time=2023-08-31T06:36:43.786Z | lvl=DEBUG | corr=1cfae922-438d-473a-9511-1f4fe7ad9f3e | trans=1cfae922-438d-473a-9511-1f4fe7ad9f3e | op=IoTAgentNGSI.Subscription-LD | from=n/a | srv=openiot | subsrv=/ | msg=Unknown error subscribing device with id [400] to entity [%s]: $s | comp=IoTAgent

我在配置中遗漏了什么吗?

我继续寻找解决方案,发现如果我在配置中添加一个表达式,它就可以工作:

{
  "devices": [
    {
      "device_id": "device001",
      "entity_name": "urn:ngsi-ld:Device:device001",
      "entity_type": "Device",
      "attributes": [
        {
            "name": "sampleTime",
            "type": "Property",
            "reverse": [
                {
                    "object_id": "sampleTime",
                    "type": "Property",
                    "expression": "sampleTime | tostring()"
                }
            ]
        }
      ]
    }
  ]
}

但是当我尝试使用 getCmd 参数获取命令时,它会返回该命令两次,并且当我在将其检索到设备之前再次更新它时,它不会返回更新的命令。看起来它没有在 mongodb 上正确存储命令。

由于此解决方案似乎不起作用,是否有任何“标准”方法来处理设备和用户都可以修改的属性?

fiware fiware-orion
1个回答
0
投票

从 IoTAgents 的角度来看,我们不鼓励使用双向插件。您正在讨论的用例可以使用轮询命令(?getCmd = 1)来解决,因此具有新配置的命令将作为发送措施的响应返回。

双向插件以及所有复杂的插件已在 IoTAgents 库版本 3.3.0 中弃用,并将很快被删除(在下一个 IoTAgent 库版本,即 3.4.0 中)。

我们知道有一些与 NGSI 注册不兼容的代理,需要从 CB 向 IoTAgent 发出命令,这促使使用双向插件作为解决方法。在 IoTAgents 命令的未来版本中,将通过订阅而不是注册来支持,因此这种解决方法的需求会被削弱。

© www.soinside.com 2019 - 2024. All rights reserved.