在 IoT 代理中创建执行器设备时出错 (FIWARE | NGSI-LD)

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

如标题中所述,我正在与 FIWARE 合作,特别是与 NGSI-LD 合作。为此,我使用 Docker Compose 部署了一系列容器:ld-context(这是为 Context Broker 提供上下文的容器)、orion-ld(我正在使用的 Context Broker)、quantumleap、mongo- db、crate-db 和 redis-db。

此外,我还部署了IoT Agent(我使用此 GitHub 存储库作为参考:https://github.com/telefonicaid/iotagent-json)。

我一直在通过在 IoT 代理中创建不同的设备和在 Context Broker 中创建不同的实体进行测试,没有遇到任何问题。这是我创建它们的方法。对于这些测试,我一直在使用 Bruno。

Service Group Creation:

POST: http://localhost:4041/iot/services
Headers:
    Content-Type: application/json
    fiware-service: openiot_device
    fiware-servicepath: /
Body:
{
    "services": [
      {
        "apikey": "openiot_device",
        "cbroker": "http://localhost:1026",
        "entity_type": "Device",
        "resource": "/iot/json"
      }
    ]
}

Device Creation:

POST: http://localhost:4041/iot/devices
Headers:
    Content-Type: application/json
    fiware-service: openiot_device
    fiware-servicepath: /
Body:
{
    "devices": [
      {
        "device_id": "device004",
        "entity_name": "urn:ngsi-ld:Device:004",
        "entity_type": "Device",
        "timezone": "Europe/Berlin",
        "attributes": [
          {
            "object_id": "t",
            "name": "temperature",
            "type": "Property",
            "metadata": {
              "unitCode": {
                "type": "Text",
                "value": "CEL"
              }
            }
          }
        ],
        "static_attributes": []
      }
    ]
}

Entity Creation:

POST: http://localhost:1026/ngsi-ld/v1/entities/
Headers:
    Content-Type: application/ld+json
    fiware-service: openiot_device
    fiware-servicepath: /
Body:
{
    "id": "urn:ngsi-ld:Device:002",
    "type": "Device",
    "temperature": {
      "type": "Property",
      "value": 22
    },
    "@context": "http://context/user-context.jsonld"
}

我能够毫无问题地创建这些项目。我访问了 mongo-db 容器并验证了所有三个项目均已成功创建,并且我能够毫无问题地更新实体值。

当我尝试创建执行器时出现问题,因为我希望能够向它发送命令。为此,我遵循了类似的方法。

首先,为了启用命令发送,我修改了config.js文件:

var config = {};
config.http = {  
      port: 7896
};

config.iota = {
      logLevel: 'DEBUG',
      timestamp: true,
      contextBroker: {        
          host: 'localhost',        
          port: '1026',        
          ngsiVersion: 'ld',
          jsonLdContext: ['http://context/ngsi-context.jsonld', 
                          'http://context/json-context.jsonld'],
          fallbackTenant: 'openiot',
          fallbackPath: '/'
      },

      server: {        
          port: 4041,
          ldSupport: {
              null: true,
              datasetId: true,
              merge: false
          }
      },

      deviceRegistry: {
          type: 'mongodb'
      },

      mongodb: {        
          host: 'localhost',        
          port: '27017',        
          db: 'iotagentjson'
      },
      
      types: {
          /*Added type actuator with the command I want to use*/
          Actuator: {
              commands: ['download_json_data']
            }
      },
      
      service: 'openiot',
      subservice: '/',    
      providerUrl: 'http://localhost:4041',    
      deviceRegistrationDuration: 'P20Y',    
      defaultType: 'mtoolkit',
      defaultResource: '/iot/json',
      explicitAttrs: true,
      contextBrokerUpdate: true
};

config.jexlTransformations = {};
config.configRetrieval = false;
config.defaultKey = 'mtoolkit1234';
config.defaultTransport = 'HTTP';
module.exports = config;

我将“download_json_data”命令添加到执行器类型中。我尝试以两种不同的方式创建执行器(我为这种类型的设备创建了一个带有固件服务的组:openiot_actuator):

1)直接使用命令创建设备:

帖子:

http://localhost:4041/iot/devices

标题:

    Content-Type: application/json
    fiware-service: openiot_actuator
    fiware-servicepath: / 

身体:

{
    "devices": [
      {
        "device_id": "actuator005",
        "entity_name": "urn:ngsi-ld:Actuator:005",
        "entity_type": "Actuator",
        "timezone": "Europe/Berlin",
        "transport": "HTTP",
        "commands": [
          {
            "name": "download_json_data",
            "type": "command"
          }
        ],
        "static_attributes": [
          {
            "name": "base_url",
            "type": "URL",
            "value": "https://..."
          }
        ]
      }
    ]
}

我收到以下错误:

{
    "name": "BAD_REQUEST",
    "message": "Request error connecting to the Context Broker: 400"
}

这个错误没有多大意义,因为我能够以相同的方式创建设备类型而没有任何问题。

2)无需传递命令即可创建设备,因为它是在 config.js 中定义的:

帖子:

http://localhost:4041/iot/devices

标题:

    Content-Type: application/json
    fiware-service: openiot_actuator
    fiware-servicepath: /

身体:

{
    "devices": [
        {
          "device_id": "actuator004",
          "entity_name": "urn:ngsi-ld:Actuator:004",
          "entity_type": "Actuator",
          "timezone": "Europe/Berlin",
          "transport": "HTTP",
          "static_attributes": [
            {
              "name": "base_url",
              "type": "URL",
              "value": "https://..."
            }
          ]
        }
    ]
}

这样,执行器设备就创建成功了,但是还没有分配命令。这是我在数据库中看到的:

{
 _id: ObjectId('672375b3d05e4d4395dcd078'),
 lazy: [],
 commands: [],
 staticAttributes: [
   {
     name: 'base_url',
     type: 'URL',
     value: 'https://...'
   }
 ],
 creationDate: ISODate('2024-10-31T12:18:59.467Z'),
 id: 'actuator004',
 type: 'Actuator',
 name: 'urn:ngsi-ld:Actuator:004',
 service: 'openiot_actuator',
 subservice: '/',
 internalId: null,
 transport: 'HTTP',
 polling: true,
 __v: 0
}

更新

在这里,我在尝试 POST 执行器时添加来自 IoT 代理的日志:

time=2024-11-04T11:57:02.827Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentNGSI.GenericMiddlewares | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Request for path [/iot/devices] query [{}] from [localhost:4041] | comp=IoTAgent
time=2024-11-04T11:57:02.827Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentNGSI.GenericMiddlewares | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Body:

{
    "devices": [
        {
            "device_id": "actuator005",
            "entity_name": "urn:ngsi-ld:Actuator:005",
            "entity_type": "Actuator",
            "timezone": "Europe/Berlin",
            "transport": "HTTP",
            "static_attributes": [
                {
                    "name": "base_url",
                    "type": "URL",
                    "value": "https://..."
                }
            ]
        }
    ]
}

 | comp=IoTAgent
time=2024-11-04T11:57:02.828Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentNGSI.DeviceProvisioning | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Handling device provisioning request. | comp=IoTAgent
time=2024-11-04T11:57:02.828Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentJSON.Agent | from=n/a | srv=openiot_actuator | subsrv=/ | msg=deviceProvisioningHandler for device {"id":"actuator005","type":"Actuator","name":"urn:ngsi-ld:Actuator:005","service":"openiot_actuator","subservice":"/","staticAttributes":[{"name":"base_url","type":"URL","value":"https://datosabiertos.castro-urdiales.net/transdat.aspx"}],"timezone":"Europe/Berlin","transport":"HTTP","internalId":null} | comp=IoTAgent
time=2024-11-04T11:57:02.828Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentNGSI.RestUtils | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Looking for bindings for the function deviceProvisioningHandler and protocol null | comp=IoTAgent
time=2024-11-04T11:57:02.828Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentNGSI.RestUtils | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Creating execution for function deviceProvisioningHandler and protocol null | comp=IoTAgent
time=2024-11-04T11:57:02.828Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentNGSI.RestUtils | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Binding found for function deviceProvisioningHandler and protocol null | comp=IoTAgent
time=2024-11-04T11:57:02.828Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentNGSI.RestUtils | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Binding found for function deviceProvisioningHandler and protocol null | comp=IoTAgent
time=2024-11-04T11:57:02.828Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentNGSI.RestUtils | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Binding found for function deviceProvisioningHandler and protocol null | comp=IoTAgent
time=2024-11-04T11:57:02.828Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentNGSI.RestUtils | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Binding found for function deviceProvisioningHandler and protocol null | comp=IoTAgent
time=2024-11-04T11:57:02.828Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IOTAJSON.HTTP.Binding | from=n/a | srv=openiot_actuator | subsrv=/ | msg=httpbinding.deviceProvisioningHandler device {"id":"actuator005","type":"Actuator","name":"urn:ngsi-ld:Actuator:005","service":"openiot_actuator","subservice":"/","staticAttributes":[{"name":"base_url","type":"URL","value":"https://datosabiertos.castro-urdiales.net/transdat.aspx"}],"timezone":"Europe/Berlin","transport":"HTTP","internalId":null} | comp=IoTAgent
time=2024-11-04T11:57:02.828Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentNGSI.MongoDBGroupRegister | from=n/a | srv=n/a | subsrv=n/a | msg=Looking for group params ["resource","apikey"] with queryObj {"resource":"/iot/json"} | comp=IoTAgent
time=2024-11-04T11:57:02.830Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.MongoDBGroupRegister | from=n/a | srv=openiot_device | subsrv=/ | msg=Device group data found: {"_id":"6720f8ce6dd0222e8d9057a4","resource":"/iot/json","apikey":"openiot_device","type":"Device","service":"openiot_device","subservice":"/"} | comp=IoTAgent
time=2024-11-04T11:57:02.831Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IOTAJSON.HTTP.Binding | from=n/a | srv=openiot_actuator | subsrv=/ | msg=httpbinding.deviceProvisioningHandler group {"_id":"6720f8ce6dd0222e8d9057a4","resource":"/iot/json","apikey":"openiot_device","type":"Device","service":"openiot_device","subservice":"/"} | comp=IoTAgent
time=2024-11-04T11:57:02.831Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IOTAJSON.HTTP.Binding | from=n/a | srv=openiot_actuator | subsrv=/ | msg=httpbinding.setPollingAndDefaultTransport device {"id":"actuator005","type":"Actuator","name":"urn:ngsi-ld:Actuator:005","service":"openiot_actuator","subservice":"/","staticAttributes":[{"name":"base_url","type":"URL","value":"https://datosabiertos.castro-urdiales.net/transdat.aspx"}],"timezone":"Europe/Berlin","transport":"HTTP","internalId":null} group {"_id":"6720f8ce6dd0222e8d9057a4","resource":"/iot/json","apikey":"openiot_device","type":"Device","service":"openiot_device","subservice":"/"} | comp=IoTAgent
time=2024-11-04T11:57:02.831Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.MongoDBDeviceRegister | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Looking for device with id [actuator005] and queryParams [{"id":"actuator005","service":"openiot_actuator","subservice":"/"}]. | comp=IoTAgent
time=2024-11-04T11:57:02.832Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.MongoDBDeviceRegister | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Device [actuator005] not found. | comp=IoTAgent
time=2024-11-04T11:57:02.833Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.MongoDBGroupRegister | from=n/a | srv=n/a | subsrv=n/a | msg=Looking for group params ["service","subservice","type","apikey"] with queryObj {"service":"openiot_actuator","subservice":"/","type":"Actuator"} | comp=IoTAgent
time=2024-11-04T11:57:02.835Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.MongoDBGroupRegister | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Device group data found: {"_id":"67233c6c390fec5139030d86","resource":"/iot/json","apikey":"openiot_actuator","type":"Actuator","service":"openiot_actuator","subservice":"/"} | comp=IoTAgent
time=2024-11-04T11:57:02.835Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.DeviceService | from=n/a | srv=openiot_device | subsrv=/ | msg=Prepare device data:
{
    "id": "actuator005",
    "type": "Actuator",
    "name": "urn:ngsi-ld:Actuator:005",
    "service": "openiot_actuator",
    "subservice": "/",
    "staticAttributes": [
        {
            "name": "base_url",
            "type": "URL",
            "value": "https://..."
        }
    ],
    "timezone": "Europe/Berlin",
    "transport": "HTTP",
    "internalId": null,
    "polling": true
} | comp=IoTAgent
time=2024-11-04T11:57:02.835Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.DeviceService | from=n/a | srv=openiot_device | subsrv=/ | msg=deviceData before merge with conf: {"id":"actuator005","type":"Actuator","name":"urn:ngsi-ld:Actuator:005","service":"openiot_actuator","subservice":"/","staticAttributes":[{"name":"base_url","type":"URL","value":"https://datosabiertos.castro-urdiales.net/transdat.aspx"}],"timezone":"Europe/Berlin","transport":"HTTP","internalId":null,"explicitAttrs":true,"polling":true} defaults: [null,null,[],[],[],[],[]] fields: ["lazy","active","staticAttributes","commands","subscriptions"] configuration {"_id":"67233c6c390fec5139030d86","resource":"/iot/json","apikey":"openiot_actuator","type":"Actuator","service":"openiot_actuator","subservice":"/"} | comp=IoTAgent
time=2024-11-04T11:57:02.835Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.DeviceService | from=n/a | srv=openiot_device | subsrv=/ | msg=deviceData after merge with conf: {"id":"actuator005","type":"Actuator","name":"urn:ngsi-ld:Actuator:005","service":"openiot_actuator","subservice":"/","active":null,"staticAttributes":[{"name":"base_url","type":"URL","value":"https://datosabiertos.castro-urdiales.net/transdat.aspx"}],"lazy":null,"commands":[],"timezone":"Europe/Berlin","transport":"HTTP","internalId":null,"explicitAttrs":true,"polling":true,"subscriptions":[]} | comp=IoTAgent
time=2024-11-04T11:57:02.835Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.DeviceService | from=n/a | srv=openiot_device | subsrv=/ | msg=Registering device into NGSI Service:
{
    "id": "actuator005",
    "type": "Actuator",
    "name": "urn:ngsi-ld:Actuator:005",
    "service": "openiot_actuator",
    "subservice": "/",
    "active": null,
    "staticAttributes": [
        {
            "name": "base_url",
            "type": "URL",
            "value": "https://..."
        }
    ],
    "lazy": null,
    "commands": [],
    "timezone": "Europe/Berlin",
    "transport": "HTTP",
    "internalId": null,
    "explicitAttrs": true,
    "polling": true,
    "subscriptions": []
} | comp=IoTAgent
time=2024-11-04T11:57:02.835Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.Registration | from=n/a | srv=openiot_device | subsrv=/ | msg=Registration with Context Provider is not needed. Device without lazy atts or commands | comp=IoTAgent
time=2024-11-04T11:57:02.835Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.DeviceService | from=n/a | srv=openiot_device | subsrv=/ | msg=Storing device :
{
    "id": "actuator005",
    "type": "Actuator",
    "name": "urn:ngsi-ld:Actuator:005",
    "service": "openiot_actuator",
    "subservice": "/",
    "staticAttributes": [
        {
            "name": "base_url",
            "type": "URL",
            "value": "https://..."
        }
    ],
    "lazy": [],
    "commands": [],
    "timezone": "Europe/Berlin",
    "transport": "HTTP",
    "internalId": null,
    "polling": true
} | comp=IoTAgent
time=2024-11-04T11:57:02.841Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.MongoDBDeviceRegister | from=n/a | srv=openiot_actuator | subsrv=/ | msg=Storing device with id [actuator005] and type [Actuator] | comp=IoTAgent
time=2024-11-04T11:57:02.852Z | lvl=DEBUG | corr=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | trans=33d4e532-a2e3-4bb2-a4ad-43c0d1d01db4 | op=IoTAgentNGSI.DeviceProvisioning | from=n/a | srv=openiot_device | subsrv=/ | msg=Device provisioning request succeeded | comp=IoTAgent
time=2024-11-04T11:57:02.852Z | lvl=DEBUG | corr=4a1a766f-41d6-42fb-94cb-2109155f9b9b | trans=4a1a766f-41d6-42fb-94cb-2109155f9b9b | op=IoTAgentNGSI.DomainControl | from=n/a | srv=openiot_actuator | subsrv=/ | msg=response-time: 26 | comp=IoTAgent

ld fiware json-ld fiware-orion
1个回答
0
投票

配置执行器与配置传感器类似。 对于 HTTP 传输,您需要包含一个

endpoint
属性来保存 IoT 代理需要发送命令的位置,并且
commands
数组包含可以调用的每个命令的列表。下面的示例使用
device_id=water001
提供水,它在上下文代理中称为
urn:ngsi-ld:Device:water001
。我注意到您对传感器和执行器使用不同的租户,这不是常见的做法,但我已将您的
openiot_actuator
租户包括在内。 HTTP 端点是
http://iot-sensors:3001/iot/water001
,它可以接受
on
off
命令。 Transport=HTTP 属性定义要使用的通信协议。

curl -L -X POST 'http://localhost:4041/iot/devices' \
    -H 'fiware-service: openiot_actuator' \
    -H 'fiware-servicepath: /' \
    -H 'Content-Type: application/json' \
--data-raw '{
  "devices": [
    {
      "device_id": "water001",
      "entity_name": "urn:ngsi-ld:Device:water001",
      "entity_type": "Device",
      "apikey": "4jggokgpepnvsb2uv4s40d59ov",
      "protocol": "PDI-IoTA-UltraLight",
      "transport": "HTTP",
      "endpoint": "http://iot-sensors:3001/iot/water001",
      "commands": [
        {
          "name": "on",
          "type": "Property"
        },
        {
          "name": "off",
          "type": "Property"
        }
       ]
    }
  ]
}'

使用 MQTT 传输执行相同的操作略有不同,不需要端点:

curl -iX POST \
  'http://localhost:4041/iot/devices' \
  -H 'Content-Type: application/json' \
  -H 'fiware-service: openiot' \
  -H 'fiware-servicepath: /' \
  -d '{
  "devices": [
    {
      "device_id": "bell001",
      "entity_name": "urn:ngsi-ld:Bell:001",
      "entity_type": "Bell",
      "protocol": "PDI-IoTA-UltraLight",
      "transport": "MQTT",
      "commands": [
        { "name": "ring", "type": "Property" }
       ]
    }
  ]
}'

发送上下文代理请求会将消息推送到

/<apikey>/<deviceid>/cmd
主题进行收集。

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