Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config from Device API not used. #1624

Open
jason-fox opened this issue Jun 27, 2024 · 4 comments · May be fixed by #1625
Open

Config from Device API not used. #1624

jason-fox opened this issue Jun 27, 2024 · 4 comments · May be fixed by #1625

Comments

@jason-fox
Copy link
Contributor

jason-fox commented Jun 27, 2024

IoT Agent Node Lib version the issue has been seen with

4.4.0

Bound or port used (API interaction)

Northbound (Provision API and NGSI Interactions)

NGSI version

NGSI-LD and NGSI-v2

Are you running a container?

Yes, I am using a contaner (Docker, Kubernetes...)

Image type

distroless

Expected behaviour you didn't see

When provisioning attributes for a device using the API, the attribute is ignored.

Unexpected behaviour you saw

When a measure is sent, the device takes static data from the group, but the device provisioning is ignored, and the measure is sent to the context broker using auto provisioned attribute names and static attributes are ignored. This also means that linked data functionality as described in the documentation no longer works.

Steps to reproduce the problem

curl -L 'http://localhost:4041/iot/about'
{
    "libVersion": "4.4.0",
    "port": "4041",
    "baseRoot": "/",
    "version": "3.4.0"
}

Using 4.4.0 library.

Provision Group with apikey

curl -L 'http://localhost:4041/iot/services' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-H 'Content-Type: application/json' \
-d '{
    "services": [
        {
            "apikey": "4jggokgpepnvsb2uv4s40d59ov",
            "cbroker": "http://orion:1026",
            "entity_type": "Device",
            "resource": "/iot/d",
            "static_attributes": [
                {
                    "name": "category",
                    "type": "Property",
                    "value": "sensor"
                },
                {
                    "name": "supportedProtocol",
                    "type": "Property",
                    "value": "ul20"
                }
            ]
        }
    ]
}'

Provision Device temperature001

curl -L 'http://localhost:4041/iot/devices' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-H 'Content-Type: application/json' \
-d '{
  "devices": [
    {
      "device_id": "temperature001",
      "entity_name": "urn:ngsi-ld:Device:temperature001",
      "entity_type": "Device",
      "timezone": "Europe/Berlin",
      "attributes": [
        {
          "object_id": "t",
          "name": "temperature",
          "type": "Property",
          "metadata": {
            "unitCode": {
              "type": "Text",
              "value": "CEL"
            }
          }
        }
      ],
      "static_attributes": [
        {
          "name": "controlledAsset",
          "type": "Relationship",
          "value": "urn:ngsi-ld:Building:barn001"
        }
      ]
    }
  ]
}'

Send measure - this is using the Ultralight IoT agent

curl -L 'http://localhost:7896/iot/d?k=4jggokgpepnvsb2uv4s40d59ov&i=temperature001' \
-H 'Content-Type: text/plain' \
-d 't|3'

Result

curl -L 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:Device:temperature001' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-H 'Link: <http://context/ngsi-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"'

Attribute called t present, controlledAsset is missing. ❌

{
    "id": "urn:ngsi-ld:Device:temperature001",
    "type": "Device",
    "t": {
        "type": "Property",
        "value": 3,
        "observedAt": "2024-06-27T06:13:10.308Z"
    },
    "category": {
        "type": "Property",
        "value": "sensor",
        "observedAt": "2024-06-27T06:13:10.308Z"
    },
    "supportedProtocol": {
        "type": "Property",
        "value": "ul20",
        "observedAt": "2024-06-27T06:13:10.308Z"
    }
}

Repeat with previous library:

curl -L 'http://localhost:4041/iot/about'
{
    "libVersion": "4.3.0",
    "port": "4041",
    "baseRoot": "/",
    "version": "3.3.0"
}

Using 4.3.0 library the behaviour was as expected.

Provision Group with apikey

curl -L 'http://localhost:4041/iot/services' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-H 'Content-Type: application/json' \
-d '{
    "services": [
        {
            "apikey": "4jggokgpepnvsb2uv4s40d59ov",
            "cbroker": "http://orion:1026",
            "entity_type": "Device",
            "resource": "/iot/d",
            "static_attributes": [
                {
                    "name": "category",
                    "type": "Property",
                    "value": "sensor"
                },
                {
                    "name": "supportedProtocol",
                    "type": "Property",
                    "value": "ul20"
                }
            ]
        }
    ]
}'

Provision Device temperature001

curl -L 'http://localhost:4041/iot/devices' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-H 'Content-Type: application/json' \
-d '{
  "devices": [
    {
      "device_id": "temperature001",
      "entity_name": "urn:ngsi-ld:Device:temperature001",
      "entity_type": "Device",
      "timezone": "Europe/Berlin",
      "attributes": [
        {
          "object_id": "t",
          "name": "temperature",
          "type": "Property",
          "metadata": {
            "unitCode": {
              "type": "Text",
              "value": "CEL"
            }
          }
        }
      ],
      "static_attributes": [
        {
          "name": "controlledAsset",
          "type": "Relationship",
          "value": "urn:ngsi-ld:Building:barn001"
        }
      ]
    }
  ]
}'

Send measure - this is using the Ultralight IoT agent

curl -L 'http://localhost:7896/iot/d?k=4jggokgpepnvsb2uv4s40d59ov&i=temperature001' \
-H 'Content-Type: text/plain' \
-d 't|3'

Result

curl -L 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:Device:temperature001' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-H 'Link: <http://context/ngsi-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"'

Attribute called temperature is present, controlledAsset is present. ✅

{
    "id": "urn:ngsi-ld:Device:temperature001",
    "type": "Device",
    "controlledAsset": {
        "type": "Relationship",
        "object": "urn:ngsi-ld:Building:barn001",
        "observedAt": "2024-06-27T06:28:42.949Z"
    },
    "category": {
        "type": "Property",
        "value": "sensor",
        "observedAt": "2024-06-27T06:28:42.949Z"
    },
    "supportedProtocol": {
        "type": "Property",
        "value": "ul20",
        "observedAt": "2024-06-27T06:28:42.949Z"
    },
    "temperature": {
        "type": "Property",
        "value": 3,
        "unitCode": "CEL",
        "observedAt": "2024-06-27T06:28:42.949Z"
    }
}

Configs

environment:
      - IOTA_NORTH_PORT=${IOTA_NORTH_PORT}
      - IOTA_REGISTRY_TYPE=mongodb #Whether to hold IoT device info in memory or in a database
      - IOTA_LOG_LEVEL=DEBUG # The log level of the IoT Agent
      - IOTA_TIMESTAMP=true # Supply timestamp information with each measurement
      - IOTA_AUTOCAST=true # Ensure Ultralight number values are read as numbers not strings
      - IOTA_MONGO_HOST=mongo-db # The host name of MongoDB
      - IOTA_MONGO_PORT=${MONGO_DB_PORT} # The port mongoDB is listening on
      - IOTA_MONGO_DB=iotagentul # The name of the database used in mongoDB
      - IOTA_HTTP_PORT=${IOTA_SOUTH_PORT} # The port used for device traffic over HTTP
      - IOTA_PROVIDER_URL=http://iot-agent:${IOTA_NORTH_PORT}
      - IOTA_CB_NGSI_VERSION=ld # use NGSI-LD when sending updates for active attributes
      - IOTA_JSON_LD_CONTEXT=http://context/ngsi-context.jsonld
      - IOTA_FALLBACK_TENANT=openiot
      - IOTA_MULTI_CORE=true

Log output

No response

@jason-fox
Copy link
Contributor Author

jason-fox commented Jun 27, 2024

The same issue occurs using NGSI-v2

curl -L 'http://localhost:1026/v2/entities/' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' 

libversion: 4.3.0

The temperature001 device is correctly mapped to urn:ngsi-ld:Device:temperature001.
Attribute called temperature is present, controlledAsset is present. ✅

{
    "id": "urn:ngsi-ld:Device:temperature001",
    "type": "Device",
    "TimeInstant": {
        "type": "DateTime",
        "value": "2024-06-27T06:40:01.074Z",
        "metadata": {}
    },
    "category": {
        "type": "Property",
        "value": "sensor",
        "metadata": {
            "TimeInstant": {
                "type": "DateTime",
                "value": "2024-06-27T06:40:01.074Z"
            }
        }
    },
    "controlledAsset": {
        "type": "Relationship",
        "value": "urn:ngsi-ld:Building:barn001",
        "metadata": {
            "TimeInstant": {
                "type": "DateTime",
                "value": "2024-06-27T06:40:01.074Z"
            }
        }
    },
    "supportedProtocol": {
        "type": "Property",
        "value": "ul20",
        "metadata": {
            "TimeInstant": {
                "type": "DateTime",
                "value": "2024-06-27T06:40:01.074Z"
            }
        }
    },
    "temperature": {
        "type": "Property",
        "value": 3,
        "metadata": {
            "TimeInstant": {
                "type": "DateTime",
                "value": "2024-06-27T06:40:01.074Z"
            },
            "unitCode": {
                "type": "Text",
                "value": "CEL"
            }
        }
    }
}

libversion: 4.3.0

The Device configuration is ignored - the id is taken as an anonymous device and the id constructed.
Attribute called temperature is incorrectly called t, controlledAsset is not present. ❌

{
    "id": "Device:temperature001",
    "type": "Device",
    "TimeInstant": {
        "type": "DateTime",
        "value": "2024-06-27T06:41:53.709Z",
        "metadata": {}
    },
    "category": {
        "type": "Property",
        "value": "sensor",
        "metadata": {
            "TimeInstant": {
                "type": "DateTime",
                "value": "2024-06-27T06:41:53.709Z"
            }
        }
    },
    "supportedProtocol": {
        "type": "Property",
        "value": "ul20",
        "metadata": {
            "TimeInstant": {
                "type": "DateTime",
                "value": "2024-06-27T06:41:53.709Z"
            }
        }
    },
    "t": {
        "type": "Text",
        "value": 3,
        "metadata": {
            "TimeInstant": {
                "type": "DateTime",
                "value": "2024-06-27T06:41:53.709Z"
            }
        }
    }
}

@jason-fox jason-fox linked a pull request Jun 27, 2024 that will close this issue
@AlvaroVega
Copy link
Member

IMHO no autoprovisioned devices should be provisioned with apikey, and then apikey should be provided in json:

curl -L 'http://localhost:4041/iot/devices' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-H 'Content-Type: application/json' \
-d '{
  "devices": [
    {
      "device_id": "temperature001",
      "apikey": "4jggokgpepnvsb2uv4s40d59ov",
      "entity_name": "urn:ngsi-ld:Device:temperature001",
      "entity_type": "Device",
      "timezone": "Europe/Berlin",
      "attributes": [
        {
          "object_id": "t",
          "name": "temperature",
          "type": "Property",
          "metadata": {
            "unitCode": {
              "type": "Text",
              "value": "CEL"
            }
          }
        }
      ],
      "static_attributes": [
        {
          "name": "controlledAsset",
          "type": "Relationship",
          "value": "urn:ngsi-ld:Building:barn001"
        }
      ]
    }
  ]
}'

@jason-fox
Copy link
Contributor Author

I would have no problem with doing things that way as best practice (assuming it works - I haven't tried yet). Effectively you're saying use this service data for this apikey + use this device data for this apikey and then merge the two right?

The problem is that until 4.4.0 it was equally possible to provisions saying: use this service data for this entity_type + use this device data for this entity_type and then merge the two. So removal of this mechanism should be noted at a breaking change, and also inhibits users from upgrading to the latest image without re-creating their provisioned devices.

Furthermore, there is nothing in the iotagent-node-lib documentation to describe what is required, and looking at the IoT Agents themselves (e.g. Getting Started for ultralight) provision the service with an apikey but do not add it to the device.

@jason-fox
Copy link
Contributor Author

I can confirm that adding apiKey to the Device provisioning call does indeed work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants