-1

I'm using IoTAgent over MQTT configuration. After going step by step with the tutorial presented on FIWARE's website is there a way to invoke command using measurment input of the IoT Agent?

Let's say i have 2 arduinos: one is an actuator and the other one is a sensor. The actuator has LED attached, sensor has a button. I want to send a message from sensor-arduino with command ON (to MQTT Broker or directly as an Ultralight message via HTTP - as far as I tested IoTA for Ultralight can run simultaneously both modes which is great) what will invoke sending the command defined for given device.

Let's say im using this config:

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": "command" }
       ],
       "static_attributes": [
         {"name":"refStore", "type": "Relationship","value": "urn:ngsi-ld:Store:001"}
      ]
    }
  ]
}
'

I can invoke command like this (which is very inconvenient):

curl -iX POST \
  'http://localhost:4041/v1/updateContext' \
  -H 'Content-Type: application/json' \
  -H 'fiware-service: openiot' \
  -H 'fiware-servicepath: /' \
  -d '{
    "contextElements": [
        {
            "type": "Bell",
            "isPattern": "false",
            "id": "urn:ngsi-ld:Bell:001",
            "attributes": [
                { "name": "ring", "type": "command", "value": "" }
            ],
            "static_attributes": [
               {"name":"refStore", "type": "Relationship","value": "urn:ngsi-ld:Store:001"}
            ]
        }
    ],
    "updateAction": "UPDATE"
}'

Or after registering the command, I can use Orion Context Broker:

curl -iX PATCH \
  'http://localhost:1026/v2/entities/urn:ngsi-ld:Lamp:001/attrs' \
  -H 'Content-Type: application/json' \
  -H 'fiware-service: openiot' \
  -H 'fiware-servicepath: /' \
  -d '{
  "on": {
      "type" : "command",
      "value" : ""
  }
}'

Those approaches give me a response in Mosquitto subscriber.

How can I create a message sent to IoTAgent (via MQTT or HTTP) that will invoke command sent to MQTT Broker? The command is further managed in actuator-arduino as long as is received in the MQTT Broker.

Jason Fox
  • 5,115
  • 1
  • 15
  • 34
Szymon Caban
  • 127
  • 1
  • 8
  • Please do not post images of text, it is impossible to search. Post the actual text and use the toolbar to format it as code so the indentations are honoured. – hardillb Jul 16 '19 at 20:16
  • Screens of configuration are a part of tutorial that I linked at the beginning. They are certainly correct and don't add any layer to the problem. Moreover, as I tried to copypaste the config as a code it was inefficient and didn't present itself great for people familiar with enviroment. Furthermore, the question is about possibility of doing something I don't know is possible so I don't get how checking config would help in aswering. – Szymon Caban Jul 17 '19 at 10:33

1 Answers1

1

Using the IoT Agent North Port

I can invoke command like this (which is very inconvenient):

This is a command direct to the North Port of the IoT Agent itself - as the tutorial states it should only be used for testing the connectivity. You should never need to do this yourself - this is the command the Orion Context Broker sends to the IoT Agent

Using NSGI v2

Or after registering the command, I can use Orion Context Broker:

Using the PATCH command is the way to go - pre-registration of commands is not necessary in the more recent releases of the IoT Agent Library.

How to use FIWARE to send Commands to Arduino

How can I create a message sent to IoTAgent (via MQTT or HTTP) that will invoke the command sent to MQTT Broker? The command is further managed in actuator-arduino as long as is received in the MQTT Broker.

The context broker is merely receiving changes of context and informing subscribed services. Within the tutorial an NSGI v2 PATCH request is programmatically sent to the Context Broker using an HTTP request :

https://github.com/FIWARE/tutorials.Step-by-Step/blob/master/context-provider/controllers/ultraLight.js

const options = {
    method: 'PATCH',
    url: UL_CONTEXT_BROKER + '/entities/' + UL_NGSI_PREFIX + id + '/attrs',
    headers: {
      'Content-Type': 'application/json',
      'fiware-servicepath': '/',
      'fiware-service': 'openiot'
    },
    body: payload,
    json: true
  };

request(options, error => {
  if (error) {
    debug(error);
  }
});

With a configured IoT Agent the result will be a topic posted to the MQTT broker. There needs to be some code in the device to ensure it is subscribed to the right topic and then receive the payload.

https://github.com/FIWARE/tutorials.Step-by-Step/blob/master/context-provider/iot.js

const mqtt = require('mqtt');
const apiKey = process.env.DUMMY_DEVICES_API_KEY || '1234';
const topics = '/' + apiKey + '/#';
const mqttBrokerUrl = process.env.MQTT_BROKER_URL || 'mqtt://mosquitto';
global.MQTT_CLIENT = mqtt.connect(mqttBrokerUrl);

MQTT_CLIENT.on('connect', () => {
  debug('Subscribing to MQTT Broker: ' + mqttBrokerUrl + ' ' + topics);
  MQTT_CLIENT.subscribe(topics);
  MQTT_CLIENT.subscribe(topics + '/#');
});

mqtt.connect(mqttBrokerUrl);

MQTT_CLIENT.on('message', function(topic, message) {
  // message is Buffer 
  Ultralight.processMqttMessage(topic.toString(), message.toString());
});
Jason Fox
  • 5,115
  • 1
  • 15
  • 34
  • _Using the PATCH command is the way to go(...)The context broker is merely receiving changes of context and informing subscribed services_. Is there a way to make IoTA for UL2.0 sent this message further up the road to the OCB? Your explanation imposes only one possibility for triggering sending a message to the actuator, which is a PATCH to the OCB. In my opinion sending command to the IoTA would be equally good method. Let's say we want OCB to be behind firewall of some kind and we have access only to the IoTA. My question is if it's at all possible without additional application logic? – Szymon Caban Jul 19 '19 at 13:35