1
votes

My setup: docker-compose:

version: "3.1"
services:
  mongo-db:
    image: mongo:3.6
    hostname: mongo-db
    container_name: db-mongo
    expose:
      - "27017"
    ports:
      - "27017:27017"
    networks:
      - default
    command: --bind_ip_all --smallfiles
    volumes:
      - mongo-db:/data

  orion:
    image: fiware/orion:2.1.0
    hostname: orion
    container_name: fiware-orion
    depends_on:
      - mongo-db
    networks:
      - default
    expose:
      - "1026"
    ports:
      - "1026:1026"
    command: -dbhost mongo-db -logLevel DEBUG
    logging:
      driver: none
    healthcheck:
      test: curl --fail -s http://localhost:1026/version || exit 1

  iot-agent:
    image: fiware/iotagent-ul:latest
    hostname: iot-agent
    container_name: fiware-iot-agent
    depends_on:
        - mongo-db
    networks:
        - default
    expose:
        - "4041"
        - "7896"
    ports:
        - "4041:4041"
        - "7896:7896"
    logging:
      driver: none
    environment:
        - "IOTA_CB_HOST=orion"
        - "IOTA_CB_PORT=1026"
        - "IOTA_NORTH_PORT=4041"
        - "IOTA_REGISTRY_TYPE=mongodb"
        - "IOTA_LOG_LEVEL=DEBUG"
        - "IOTA_TIMESTAMP=true"
        - "IOTA_MONGO_HOST=mongo-db"
        - "IOTA_MONGO_PORT=27017"
        - "IOTA_CB_NGSI_VERSION=v2"
        - "IOTA_MONGO_DB=iotagentul"
        - "IOTA_HTTP_PORT=7896"
        - "IOTA_PROVIDER_URL=http://iot-agent:4041"


networks:
  default:
    ipam:
      config:
        - subnet: 172.18.1.0/24

volumes:
  mongo-db: ~

context:

curl -iX POST \
  'http://localhost:1026/v2/op/update' \
  -H 'Content-Type: application/json' \
  -H 'fiware-service: didi' \
  -H 'fiware-servicepath: /' \
  -d '{
  "actionType":"APPEND",
  "entities":[
    {
      "id":"urn:ngsi-ld:Furniture:unit001", "type":"Furniture",
      "name":{
        "type":"Text", "value":"Bürostuhl"
      },
      "price":{
        "type":"Integer", "value":404.40
      }
    },
    {
      "id":"urn:ngsi-ld:Furniture:unit002", "type":"Furniture",
      "name":{
        "type":"Text", "value":"Bürotisch"
      },
      "price":{
        "type":"Integer", "value":203.40
      }
    },
    {
      "id":"urn:ngsi-ld:DeliverService:unit001", "type":"ServiceProvider",
      "name":{
        "type":"Text", "value":"trinkajo"
      },
       "address":{
            "type":"PostalAddress",
            "value":{
               "telephoneNumber":"43q4q53",
               "internetAdresse":"https://www.345345.de/"
            }
         }
    },
    {
      "id":"urn:ngsi-ld:BottleCounter:001", "type":"BottleCounter",
      "name":{
        "type":"Text", "value":"Wasserflaschenzähler"
      },
      "numberOfBottles": {"type":"Integer", "value":645}
    }
  ]
}'




curl -iX POST \
  'http://localhost:1026/v2/op/update' \
  -H 'Content-Type: application/json' \
  -H 'fiware-service: didi' \
  -H 'fiware-servicepath: /' \
  -d '{
  "actionType":"APPEND",
  "entities":[
    {
      "id":"urn:ngsi-ld:Furniture:unit001", "type":"Furniture",
      "refOffice": {
        "type": "Relationship",
        "value": "urn:ngsi-ld:Office:001"
      }
    },
    {
      "id":"urn:ngsi-ld:Furniture:unit002", "type":"Furniture",
      "refOffice": {
        "type": "Relationship",
        "value": "urn:ngsi-ld:Office:001"

      }  
    },
    {
      "id":"urn:ngsi-ld:DeliverService:unit001", "type":"ServiceProvider",
      "refOffice": {
        "type": "Relationship",
        "value": "urn:ngsi-ld:Office:001"

      }  
    }
  ]
}'
curl -iX POST \
  'http://localhost:1026/v2/op/update' \
  -H 'Content-Type: application/json' \
  -H 'fiware-service: didi' \
  -H 'fiware-servicepath: /' \
  -d '{
   "actionType":"APPEND",
   "entities":[
      {
         "id":"urn:ngsi-ld:Office:001", "type" : "Office",
         "name":{
            "type":"Text",
            "value":"didi-Hamburg"
         },
         "sizeInM2":{
            "type":"Integer",
            "value":60
         },
         "address":{
            "type":"PostalAddress",
            "value":{
               "country":"Germany",
               "locality":"sdfg",
               "street":"sdfg",
               "houseNumber" : "34",
               "postalCode":"34533"
            }
         }
      }
   ]
}'


curl -iX POST \
  'http://localhost:4041/iot/services' \
  -H 'Content-Type: application/json' \
  -H 'fiware-service: didi' \
  -H 'fiware-servicepath: /' \
  -d '{
 "services": [
   {
     "apikey":      "4jggokgpepnvsb2uv4s40d59ov",
     "cbroker":     "http://orion:1026",
     "entity_type": "Thing",
     "resource":    "/iot/d"
   }
 ]
}'
curl -G -X GET \
  'http://localhost:1026/v2/entities/urn:ngsi-ld:Office:001' \
  -H 'fiware-service: didi' \
  -H 'fiware-servicepath: /' \
  -d 'type=Office' \
  -d 'options=keyValues' | json_pp

curl -iX POST \
  'http://localhost:4041/iot/devices' \
  -H 'Content-Type: application/json' \
  -H 'fiware-service: didi' \
  -H 'fiware-servicepath: /' \
  -d '{
 "devices": [
   {
     "device_id":   "bottleCounter001",
     "entity_name": "urn:ngsi-ld:BottleCounter:001",
     "entity_type": "BottleCounter",
     "timezone":    "Europe/Berlin",
     "attributes": [
       { "object_id": "c", "name": "numberOfBottles", "type": "Integer" }
     ],
     "static_attributes": [
       { "name":"refOffice", "type": "Relationship", "value": "urn:ngsi-ld:Office:001"}
     ]
   }
 ]
}'

The subscription:

curl -iX POST \
  --url 'http://localhost:1026/v2/subscriptions' \
  --header 'Content-Type: application/json' \
  -H 'fiware-service: didi' \
  -H 'fiware-servicepath: /' \
  --data '{
  "description": "Notify me of low stock in Office 001",
  "subject": {
    "entities": [{"idPattern": ".*", "type" : "BottleCounter"}],
    "condition": {
      "attrs": ["numberOfBottles"],
      "expression": {"q": "numberOfBottles<10;refOffice==urn:ngsi-ld:Office:001"}
    }
  },
  "notification": {
    "http": {
      "url": "http://delivery:8080/subscription/office"
    }
  }
}'

How I successfully update the value numberOfBottles:

curl -iX POST \
  'http://localhost:7896/iot/d?k=4jggokgpepnvsb2uv4s40d59ov&i=bottleCounter001' \
  -H 'fiware-service: didi' \
  -H 'fiware-servicepath: /' \
  -H 'Content-Type: text/plain' \
  -d 'c|2'

My usecase is something like:

There is an office with water bottles for the employee. There is a 'sensor' which can count the water bottles. When an employee is taking a water bottle the sensor will update the value in fiware. When the number is below 3 fiware should notify the subscriber. The subscriber can now order new water bottles.

I have several problems:

  1. With the condition numberOfBottles<10 the subscription never get triggered. When I use something like numberOfBottles!=10 it is working
  2. There is only an empty body sent to the url http://delivery:8080/subscription/office

A bonus question: if I can fix the first issues: Is there a way to send the attribute address from urn:ngsi-ld:DeliverService:unit001 to the url http://delivery:8080/subscription/office when the subscription get triggered?

1
Could you edit your question post to provide more information about the background of your use case, please? I mean, I see a collection of requests (some of them for Orion, some of them for IOTA) but I don't fully understand how they are "orchestrated". An special important point is how do you update the entities covered by the subscription (BottleCounter). Do you update directly at Context Brokker using the NGSIv2 API? Or do you send your measure through IOTAgent? - fgalan
Hey, there is not really a "use case". I'm just trying to play with it. I update the value through an IOTAgent. I will update the question! - SamuelTJackson
Regarding the bonus question: - it all depends on how you structure your entities. You could have a duplicate address static attribute within the BottleCounter and send that, or you could send refOffice in the response and make a subsequent NGSI request from your receiving endpoint to get the additional data. - Jason Fox
Your existing entities correctly reference other entities in a classic linked data structure. Ideally you should avoid thinking of entities in the same fashion as relational database structures - the making a subsequent request is the correct way to go (for example, in your case, what if the name of the road has changed?) - Jason Fox
Regarding question number 2: what do you mean by "empty body"? No body at all (i.e. content-length: 0)? Or a body with {} payload or some other way empty? - fgalan

1 Answers

1
votes

As far as I remember, IOTAs are configured by default to use NGSIv1 to send updates to CB. One of the limitations of the NGSIv1 API (deprecated :) is that numbers are parsed always as strings. Thus it makes sense the numberOfBottles<10 filter doesn't work.

In order to overcome this problem IOTA should be configured to use NGSIv2. Add the following to the envrironment of the iot-agent in your docker-compose.yml and redeploy:

- IOTA_CB_NGSI_VERSION=v2

With regards to bonus question, I think @JasonFox has already answered it in the question comments.

EDIT: I have realized you are using UL agent. Different from JSON agent (which allows you to specify JSON supported values, such as numbers, in the request sent to the agent) UL encoding is based on text. Thus, in order to progress numeric values to CB you need (in addition to the IOTA_CB_NGSI_VERSION setting described above):

  1. Set the IOTA_AUTOCAST configuration to true:

    - IOTA_AUTOCAST=true
    
  2. Use "Number" as attribute type at provisioning time (instead of "Integer").

This is described in more detail in this section of the documentation.