Iota Attachment Error Please Publish Again
Clarification: This tutorial extends the connection of IoT devices connecting to FIWARE to use alternate send. The UltraLight 2.0 IoT Agent created in the previous tutorial is reconfigured to communicate with a set of dummy IoT devices which transfer secure letters over the IOTA Tangle. An additional gateway component is added to the architecture of the previous MQTT tutorial to allow for secure indelible transactions across a distributed ledger network.
The tutorial is mainly concerned with the compages of the custom components, but uses gyre commands where necessary, and is also available equally Postman documentation
What is IOTA?
"Hansel took his trivial sister by the mitt, and followed the pebbles which shone like newly-coined silver pieces, and showed them the way."
― Jacob Grimm, Grimm'south Fairy Tales
The IOTA Tangle is a directed acyclic graph which can exist used equally a distributed ledger. Information technology is not a traditional blockchain, simply works with the concept of a Tangle which contains the current transaction history and links from parents to child transactions which provide a single source of truth in a distributed network. Whenever data is persisted to the tangle it is replicated across all nodes so that any client, anywhere around the world can transport valid transactions to a Node.
IOTA positions itself as existence an ideal distributed ledger for IoT due to its feeless nature and scalable distributed structure. Obviously when architecting whatever smart organization, the developer needs to compromise betwixt various factors such every bit price, speed, reliability, security and and then on. The previous MQTT tutorial was fast, but independent no security elements and was vulnerable to malicious attack. An IOTA-based IoT arrangement volition automatically include secure logging of all events and therefore could exist used to for charging customers on an event-by-issue ground.
A hybrid system could likewise be envisaged where some frequent just depression chance transactions could be made using a standard MQTT ship (e.thou. continuous tracking of the location an ARV), whereas infrequent but chargeable events could exist made using a secure system similar IOTA (e.g. credit carte du jour payment for an entire trip)
The basic IOTA architecture includes the post-obit bones components:
- Clients: Users of an IOTA network (wallets, apps, etc.) that send transactions to nodes to attach to the Tangle.
- Nodes: Connected devices responsible for ensuring the integrity of the Tangle. These devices form an IOTA network.
- Tangle: An fastened data structure (public ledger, main ledger), which is replicated on all nodes in an IOTA network.
For the purpose of this tutorial, all data from the dummy devices is existence stored within the IOTA Tangle. Each device reading will be placed in a transaction object and attached to the IOTA Tangle, once attached it cannot be changed and is immutable. It obviously takes time for all nodes to agree that a transaction hs occurred, and therefore all communication should be considered every bit asynchronous.
The IoT Agent for Ultralight currently offers three standard transport mechanisms - HTTP, MQTT and AMPQ. Whereas it would exist possible to create a new binding direct for IOTA, in this case, it makes more sense to re-use the existing asynchronous MQTT binding and extend using a gateway solution where a separate microservice deals with the IOTA letters. IoT Agents based on gateway solutions already exist for OPC-UA and LoRaWAN. In the case of the IoT Agent for OPC-UA for instance, in its own Tutorial, device readings are passed to an OPC-UA server and the IoT Amanuensis in turn subscribes to the OPC-UA server and transforms letters into NGSI format. With the Gateway solution described in this tutorial finer MQTT is at present just existence used as a message bus, so we can provision our IoT devices equally MQTT devices and intercept the relevant MQTT topics to transform the data into IOTA Tangle transactions to talk to IOTA Tangle enabled devices. The payload of each bulletin continues to use the existing UltraLight 2.0 syntax, and therefore nosotros can continue to use the same FIWARE generic enabler to connect the devices. It is only the underlying transport which has been customized in this scenario.
Mosquitto MQTT Broker
Mosquitto is a readily available, open source MQTT broker which will be used during this tutorial. Information technology is available licensed under EPL/EDL. More information tin exist institute at https://mosquitto.org/
Device Monitor
For the purpose of this tutorial, a series of dummy IoT devices have been created, which volition exist attached to the context banker. Details of the architecture and protocol used tin can exist found in the IoT Sensors tutorial The state of each device can exist seen on the UltraLight device monitor spider web page found at: http://localhost:3000/device/monitor
Architecture
This application builds on the components created in previous tutorials. It volition brand use of ii FIWARE components - the Orion Context Broker and the IoT Amanuensis for UltraLight 2.0. Usage of the Orion Context Banker is sufficient for an awarding to qualify as "Powered by FIWARE". Both the Orion Context Broker and the IoT Agent rely on open source MongoDB technology to keep persistence of the data they concur. We will also be using the dummy IoT devices created in the previous tutorial Additionally nosotros will add an example of the Mosquitto MQTT broker which is open source and bachelor under the EPL/EDL and create a custom MQTT-IOTA Gateway to enable usa to persist commands to the IOTA Tangle and to subscribe to topics to receive measurements and command acknowledgements when they occur.
Therefore, the overall compages volition consist of the following elements:
- The FIWARE Orion Context Broker which volition receive requests using NGSI-v2
- The FIWARE IoT Agent for UltraLight 2.0 which will:
- receive southbound requests using NGSI-v2 and convert them to UltraLight 2.0 MQTT topics for the MQTT Banker
- listen to the MQTT Banker on registered topics to transport measurements northbound
- The Mosquitto MQTT Broker which acts as a central communication signal, passing MQTT topics between the IoT Amanuensis and IoT devices as necessary.
- The underlying MongoDB database :
- Used by the Orion Context Broker to hold context information information such every bit data entities, subscriptions and registrations
- Used by the IoT Agent to hold device information such as device URLs and Keys
- A webserver acting as set of dummy IoT devices using the UltraLight 2.0 protocol running over the IOTA Tangle.
- An MQTT-IOTA gateway which persists MQTT topic messages to the tangle and vice-vera.
Since all interactions betwixt the elements are initiated by HTTP or MQTT requests over TCP, the entities can be containerized and run from exposed ports.
The necessary configuration information for wiring up the Mosquitto MQTT Broker, the IoT devices and the IoT Amanuensis can be seen in the services section of the associated docker-etch.yml file:
Mosquitto Configuration
mosquitto: image: eclipse-mosquitto hostname: mosquitto container_name: mosquitto networks: - default expose: - "1883" - "9001" ports: - "1883:1883" - "9001:9001" volumes: - ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf The mosquitto container is listening on two ports:
- Port
1883is exposed so we can post MQTT topics - Port
9001is the standard port for HTTP/Websocket communications
The attached book is a configuration file used to increment the debug level of the MQTT Bulletin Broker.
Dummy IoT Devices Configuration
tutorial: image: fiware/tutorials.context-provider hostname: iot-sensors container_name: fiware-tutorial networks: - default betrayal: - "3000" - "3001" ports: - "3000:3000" - "3001:3001" environment: - "DEBUG=tutorial:*" - "WEB_APP_PORT=3000" - "DUMMY_DEVICES_PORT=3001" - "DUMMY_DEVICES_API_KEYS=1068318794,3020035,3314136,3089326" - "DUMMY_DEVICES_TRANSPORT=IOTA" - "IOTA_NODE=https://chrysalis-nodes.iota.buffet" - "IOTA_MESSAGE_INDEX=fiware" The tutorial container is listening on 2 ports:
- Port
3000is exposed, so we can run across the web folio displaying the Dummy IoT devices. - Port
3001is exposed purely for tutorial access - so that cUrl or Postman can make UltraLight commands without being part of the same network.
The tutorial container is driven by environs variables as shown:
| Key | Value | Description |
|---|---|---|
| DEBUG | tutorial:* | Debug flag used for logging |
| WEB_APP_PORT | 3000 | Port used by web-app which displays the dummy device data |
| DUMMY_DEVICES_PORT | 3001 | Port used by the dummy IoT devices to receive commands |
| DUMMY_DEVICES_API_KEYS | 4jggokgpepnvsb2uv4s40d59ov | List of security key used for UltraLight interactions - used to ensure the integrity of interactions between the devices and the IoT Agent |
| DUMMY_DEVICES_TRANSPORT | IOTA | The ship protocol used by the dummy IoT devices |
| IOTA_NODE | https://chrysalis-nodes.iota.buffet | Starting IOTA node for the Gateway to connect to |
| IOTA_MESSAGE_INDEX | fiware | Message index used to persist the data devices |
The other tutorial container configuration values described in the YAML file are not used in this tutorial.
IoT Agent for UltraLight 2.0 Configuration
The IoT Agent for UltraLight 2.0 can be instantiated within a Docker container. An official Docker image is available from Docker Hub tagged fiware/iotagent-ul. The necessary configuration can be seen below:
iot-agent: image: fiware/iotagent-ul:latest hostname: iot-amanuensis container_name: fiware-iot-agent depends_on: - mongo-db networks: - default expose: - "4041" ports: - "4041:4041" environment: - IOTA_CB_HOST=orion - IOTA_CB_PORT=1026 - IOTA_NORTH_PORT=4041 - IOTA_REGISTRY_TYPE=mongodb - IOTA_LOG_LEVEL=DEBUG - IOTA_TIMESTAMP=truthful - IOTA_CB_NGSI_VERSION=v2 - IOTA_AUTOCAST=true - IOTA_MONGO_HOST=mongo-db - IOTA_MONGO_PORT=27017 - IOTA_MONGO_DB=iotagentul - IOTA_PROVIDER_URL=http://iot-amanuensis:4041 - IOTA_MQTT_HOST=mosquitto - IOTA_MQTT_PORT=1883 The iot-agent container relies on the presence of the Orion Context Broker and uses a MongoDB database to hold device information such equally device URLs and Keys. The container is listening on a single port:
- Port
4041is exposed purely for tutorial access - and so that roll or Postman tin make provisioning commands without existence part of the same network.
The iot-amanuensis container is driven by environs variables as shown:
| Primal | Value | Description |
|---|---|---|
| IOTA_CB_HOST | orion | Hostname of the context broker to update context |
| IOTA_CB_PORT | 1026 | Port that context broker listens on to update context |
| IOTA_NORTH_PORT | 4041 | Port used for Configuring the IoT Agent and receiving context updates from the context broker |
| 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 | Whether to supply timestamp information with each measurement received from attached devices |
| IOTA_CB_NGSI_VERSION | v2 | Whether to supply employ NGSI v2 when sending updates for active attributes |
| IOTA_AUTOCAST | true | Ensure Ultralight number values are read every bit numbers not strings |
| IOTA_MONGO_HOST | context-db | The hostname of mongoDB - used for holding device information |
| IOTA_MONGO_PORT | 27017 | The port mongoDB is listening on |
| IOTA_MONGO_DB | iotagentul | The name of the database used in mongoDB |
| IOTA_PROVIDER_URL | http://iot-agent:4041 | URL passed to the Context Broker when commands are registered, used equally a forwarding URL location when the Context Banker problems a command to a device |
| IOTA_MQTT_HOST | mosquitto | The hostname of the MQTT Broker |
| IOTA_MQTT_PORT | 1883 | The port the MQTT Broker is listening on to receive topics |
Equally you tin can run across, utilize of the MQTT send is driven by only two environment variables IOTA_MQTT_HOST and IOTA_MQTT_PORT
MQTT-IOTA Gateway Configuration
iota-gateway: epitome: iota-gateway hostname: iota-gateway container_name: iota-gateway build: context: iota-gateway dockerfile: Dockerfile networks: - default surroundings: - "DEBUG=gateway:*" - "MQTT_BROKER_URL=mqtt://mosquitto" - "IOTA_NODE=https://chrysalis-nodes.iota.cafe" - "IOTA_MESSAGE_INDEX=fiware" The iota-gateway container is a middleware connecting to the MQTT broker and reading and persisting transactions onto IOTA Tangle. This middleware therefore needs to connect to both the MQTT banker and the IOTA Tangle and repeats some parameters described above.
Start Upward
Before you start you should ensure that you have obtained or built the necessary Docker images locally. Please clone the repository and create the necessary images by running the commands as shown:
git clone https://github.com/FIWARE/tutorials.IoT-over-IOTA.git cd tutorials.IoT-over-IOTA git checkout NGSI-v2 ./services create Thereafter, all services can be initialized from the command-line past running the services Bash script provided inside the repository:
./services start :information_source: Note: If you lot want to clean upwardly and start over again you lot can do so with the following control:
fustigate ./services stop
Provisioning Devices
Provisioning devices is not the focus of this tutorial, and all the necessary device provisioning occurs automatically when the tutorial is started. However, for completeness the provisioning requests are repeated here and described below. It is not necessary to re-run these commands.
A series of service groups are created to associate classes of devices to an API Cardinal, in the example below services take been created for type=Bell and type=Motion. It should be noted that the resource aspect has been left blank and the transport fix to MQTT - this is the same as the in the previous MQTT tutorial, since the IoT Amanuensis is merely sending messsages to the MQTT banker and has no idea that a custom gateway component is also involved.
curlicue -X Mail service \ "http://localhost:4041/iot/services" \ -H 'Content-Type: application/json' \ -H 'fiware-service: openiot' \ -H 'fiware-servicepath: /' \ -d '{ "services": [ { "apikey": "1068318794", "cbroker": "'"http://orion:1026"'", "entity_type": "Move", "resources": "", "protocol": "PDI-IoTA-UltraLight", "transport": "MQTT", "timezone": "Europe/Berlin", "attributes": [ {"object_id": "c", "name":"count", "blazon":"Integer"}, {"object_id": "t", "name": "TimeInstant", "blazon":"DateTime"} ], "static_attributes": [ {"name": "category", "type":"Text", "value": ["sensor"]}, {"name": "controlledProperty", "type": "Text", "value": "motility"}, {"name": "part", "type": "Text", "value":["sensing"]}, {"name": "supportedProtocol", "type": "Text", "value": ["ul20"]}, {"proper noun": "supportedUnits", "type": "Text", "value": "C62"} ] }, { "apikey": "3020035", "cbroker": "'"http://orion:1026"'", "entity_type": "Bell", "resource": "", "protocol": "PDI-IoTA-UltraLight", "ship": "MQTT", "timezone": "Europe/Berlin", "commands": [ { "name": "ring", "type": "control" } ], "static_attributes": [ {"name": "category", "type":"Text", "value": ["actuator"]}, {"proper noun": "controlledProperty", "type": "Text", "value": "noiseLevel"}, {"name": "function", "type": "Text", "value":["onOff"]}, {"name": "supportedProtocol", "type": "Text", "value": ["ul20"]} ] } ] }' Commands and measures defined when individual devices are provisioned. Once again the ship is prepare to MQTT.
curl -X POST \ "http://localhost:4041/iot/devices" \ -H 'Content-Blazon: application/json' \ -H 'fiware-service: openiot' \ -H 'fiware-servicepath: /' \ -d '{ "devices": [ { "device_id": "motion001", "entity_name": "urn:ngsi-ld:Motility:001", "entity_type": "Motion", "transport": "MQTT", "static_attributes": [ {"proper noun": "refStore", "type": "Relationship","value": "urn:ngsi-ld:Shop:001"} ] }, { "device_id": "bell001", "entity_name": "urn:ngsi-ld:Bell:001", "entity_type": "Bell", "transport": "MQTT", "static_attributes": [ {"name": "refStore", "type": "Relationship","value": "urn:ngsi-ld:Shop:001"} ] } ] } ' Device Monitor
The device monitor tin can be found at: http://localhost:3000/device/monitor - open up the spider web folio to view the state of the devices and view the persisted IOTA Tangle traffic.
Display the IOTA-Gateway logs (1st Terminal)
Open up a new final, and follow the iota-gateway Docker container every bit follows:
docker logs -f iota-gateway The final will and so be ready to display received messages.
1st concluding - Gateway Outcome:
If the MQTT-IOTA Gateway is functioning correctly, the following messages should be displayed
2021-12-07T15:28:42.855Z gateway:app connected to IOTA Tangle: https://chrysalis-nodes.iota.buffet 2021-12-07T15:28:42.862Z gateway:app Subscribing to 'messages/indexation/fiware/attrs' 2021-12-07T15:28:42.872Z gateway:app Subscribing to 'letters/indexation/fiware/cmdexe' The gateway needs to subscribe to the IOTA Tangle to receive measures and command acknowledgements.
Display the Dummy Device logs (2nd Terminal)
A sensor sending northbound measurements volition persist transactions to the IOTA Tangle to which will be passed on to whatever subscriber than wants them. The sensor does non demand to make a connection to the subscriber direct. Similarly, whatsoever connected actuators volition need to subscribe to an IOTA Tangle message topic to receive aby commands that are relevant to them.
Open a new concluding, and run a fiware-tutorial Docker container to transport a message as follows:
docker logs -f fiware-tutorial The concluding volition then exist prepare to display received letters.
2d terminal - Device Result:
If the Devices are functioning correctly, the message should be received in the other terminal:
2021-12-07T15:29:22.163Z tutorial:server Listening on port 3000 2021-12-07T15:29:22.166Z tutorial:server Listening on port 3001 2021-12-07T15:29:22.522Z tutorial:application MongoDB is continued. 2021-12-07T15:29:22.612Z tutorial:iot-device connected to IOTA Tangle: https://chrysalis-nodes.iota.cafe 2021-12-07T15:29:22.613Z tutorial:iot-device Subscribing to 'messages/indexation/fiware/cmd' Using the IOTA Tangle every bit a Transport
Sending Commands
Since all the devices accept been pre-provisioned, a bong tin can exist rung using a standard NGSI-v2 PATCH request:
one Request:
curl -50 -X PATCH 'http://localhost:1026/v2/entities/urn:ngsi-ld:Bong:001/attrs' \ -H 'fiware-service: openiot' \ -H 'fiware-servicepath: /' \ -H 'Content-Type: awarding/json' \ --data-raw '{ "ring": { "type" : "control", "value" : "" } }' The NGSI request is transformed into an MQTT message (with an Ultralight payload) which is received by the MQTT-IOTA Gateway - this message is so persisted to the IOTA Tangle as shown:
1st concluding - Gateway Issue:
2021-12-07T15:50:54.848Z gateway:southbound Command received from MQTT bell001@ring| 2021-12-07T15:51:12.580Z gateway:southbound Command pushed to Tangle: i=bell001&thou=1068318794&d=bell001@band| to fiware/cmd 2021-12-07T15:51:12.581Z gateway:southbound messageId: 40431e6e39ade9babe02ef342ee9267f69982fe42db8f5d3f32d57bb686120d5 The dummy device is too subscribing to IOTA Tangle messages, a bulletin is received and the device is activated (in this case the bell will ring). At this bespeak an acknowledgement is placed onto the fiware/cmdexe topic:
2nd concluding - Device Result:
2021-12-07T15:51:12.583Z tutorial:iot-device IOTA Tangle message received: 40431e6e39ade9babe02ef342ee9267f69982fe42db8f5d3f32d57bb686120d5 2021-12-07T15:51:17.806Z tutorial:ultralight command response sent to fiware/cmdexe 2021-12-07T15:51:17.806Z tutorial:ultralight 960e8ac4a9e22e360f7e92c3a7b9ac3b71c59950fd2fba7f4be551f930342f94 2021-12-07T15:51:17.812Z tutorial:devices actuateDevice: bell001 band If yous are viewing the device monitor page, you lot tin also run across the state of the bell change.
The Gateway receives the acknowledgement from the IOTA Tangle fiware/cmdexe topic and returns the result of the request to the IoT Amanuensis.
1st terminal - Gateway Event:
2021-12-07T15:51:xviii.022Z gateway:northbound Control response received from Tangle: i=bell001&k=1068318794&d=bell001@ring| band OK 2021-12-07T15:51:18.027Z gateway:northbound Sent to MQTT topic /1068318794/bell001/cmdexe 2021-12-07T15:51:34.741Z gateway:northbound Command response received from Tangle: i=bell001&one thousand=1068318794&d=bell001@ring| band OK The effect of the control to band the bell can be read past querying the entity inside the Orion Context Banker.
ii Request:
whorl -L -10 GET 'http://localhost:1026/v2/entities/urn:ngsi-ld:Bell:001?options=keyValues' \ -H 'fiware-service: openiot' \ -H 'fiware-servicepath: /' Response:
{ "id": "urn:ngsi-ld:Bell:001", "type": "Bong", "TimeInstant": "2021-12-07T15:51:36.219Z", "category": ["actuator"], "controlledProperty": "noiseLevel", "function": ["onOff"], "refStore": "urn:ngsi-ld:Store:001", "ring_info": " ring OK", "ring_status": "OK", "supportedProtocol": ["ul20"], "ring": "" } The TimeInstant shows last the time any command associated with the entity has been invoked. The result of ring control tin can exist seen in the value of the ring_info aspect.
Note: IOTA Transactions are not instantaneous, if the bong is queried before the transaction is complete, the response volition get out the
ring_statusevery bitPENDING
{ "id": "urn:ngsi-ld:Bell:001", "type": "Bell", "TimeInstant": "2021-12-07T15:51:36.219Z", "category": [ "actuator" ], "controlledProperty": "noiseLevel", "function": [ "onOff" ], "refStore": "urn:ngsi-ld:Shop:001", "ring_info": "UNKNOWN", "ring_status": "Pending", "supportedProtocol": [ "ul20" ], "ring": "" }
Furthermore, all transactions can be found on the IOTA Tangle under https://explorer.iota.org/mainnet/bulletin/<message_id>, for example https://explorer.iota.org/mainnet/bulletin/40431e6e39ade9babe02ef342ee9267f69982fe42db8f5d3f32d57bb686120d5 permanently holds the following information:
Which indicates a request was sent to ring the bong.
Sending Device Measures
A measure out from a device tin be simulated by selecting Observe Motion from the dropdown and clicking on transport.
The device persists the measure out to the fiware/attrs topic on the IOTA Tangle Mainnet.
2d last - Device Result:
2021-12-07T16:34:25.767Z tutorial:devices fireMotionSensor 2021-12-07T16:34:26.185Z tutorial:northbound sendIOTAMeasure: motion001 2021-12-07T16:34:26.479Z tutorial:ultralight measure sent to fiware/attrs 2021-12-07T16:34:26.479Z tutorial:ultralight da4df31054df529a3ade74befb84edabf7697ae8a3a9ee3481be08ee0aabb3e7 Once the transactions is settled, it is passed onto the subscribing Gateway component.
1st terminal - Gateway Upshot:
2021-12-07T16:35:25.679Z gateway:northbound Measure received from Tangle: i=motion001&k=1068318794&d=c|0|t|2021-12-07T16:34:44.891Z 2021-12-07T16:35:25.680Z gateway:northbound Sent to MQTT topic /1068318794/motion001/attrs There may be a noticeable lag between reading the measure and it beingness received at the context banker. The payload of the measure therefore contains a timestamp t|2021-12-07T16:34:44.891Z which is mapped to TimeInstant in the IoT Agent to ensure that the correct metadata is associated with the measure out in the context banker.
The state of the sensor can be read by querying the entity within the Orion Context Banker.
iii Request:
gyre -L -X GET 'http://localhost:1026/v2/entities/urn:ngsi-ld:Motion:001?options=keyValues' \ -H 'fiware-service: openiot' \ -H 'fiware-servicepath: /' Response:
{ "id": "urn:ngsi-ld:Move:001", "type": "Motion", "TimeInstant": "2021-12-07T16:34:44.891Z", "category": ["sensor"], "controlledProperty": "movement", "count": "0", "function": ["sensing"], "refStore": "urn:ngsi-ld:Shop:001", "supportedProtocol": ["ul20"], "supportedUnits": "C62" } MQTT-IOTA Gateway - Sample Lawmaking
The MQTT-IOTA Gateway is a unproblematic application written in Node.js. Its only function is passing information between the two transports. MQTT Client libraries already exist so the application can be set up to listen to the normal MQTT topic for IoT Agent actuations.
const mqtt = require("mqtt"); const MQTT_CLIENT = mqtt.connect("mqtt://mosquitto"); MQTT_CLIENT.on("connect", () => { MQTT_CLIENT.subscribe("/+/+/cmd"); }); MQTT_CLIENT.on("message", Southbound.control); Similarly, there are equivalent client libraries available in multiple languages for persisting and listening to changes on the IOTA Tangle. The MQTT-IOTA Gateway needs to listen on ii topics - i for device measures and a 2d 1 for acknowledgements of commands:
const iotaClient = require("@iota/client"); const IOTA_CLIENT = new iotaClient.ClientBuilder().node("https://chrysalis-nodes.iota.cafe").build(); IOTA_CLIENT.getInfo() .and then(() => { IOTA_CLIENT.subscriber() .topic(IOTA_MESSAGE_INDEX + "messages/indexation/fiware/attrs") .subscribe((err, information) => { const messageId = IOTA_CLIENT.getMessageId(information.payload); IOTA_CLIENT.getMessage() .information(messageId) .and so((messageData) => { Northbound.measure out(messageData); }); }); IOTA_CLIENT.subscriber() .topic(IOTA_MESSAGE_INDEX + "letters/indexation/fiware/cmdexe") .subscribe((err, information) => { const messageId = IOTA_CLIENT.getMessageId(information.payload); IOTA_CLIENT.getMessage() .data(messageId) .then((messageData) => { Northbound.commandResponse(messageData); }); }); }) .take hold of((err) => { debug(err); }); MQTT-IOTA Gateway Southbound - Sample Code
For the southbound traffic, the API Key and device ID are extracted from the MQTT topic and moved into the IOTA payload. The syntax of the IOTA payload (with i, chiliad and d attributes) is based on the Ultralight HTTP syntax. The message is and then persisted to the Tangle using an appropriate index:
function control(topic = "cmd", bulletin) { const parts = topic.toString().dissever("/"); const apiKey = parts[1]; const deviceId = parts[2]; const action = parts[3]; forwardAsIOTATangle(apiKey, deviceId, message.toString(), action); } function forwardAsIOTATangle(apiKey, deviceId, state, topic) { const payload = "i=" + deviceId + "&k=" + apiKey + "&d=" + state; IOTA_CLIENT.message() .index("fiware/" + topic) .information(payload) .submit() .then((message) => { debug("messageId: " + message.messageId); }); } MQTT-IOTA Gateway Northbound - Sample Code
Northbound traffic is like - the payload is received from the IOTA Tangle, unmarshalled to reveal the API Key and device id, and the posted to an appropriate MQTT Topic.
function unmarshall(payload) { const parts = payload.divide("&"); const obj = {}; parts.forEach((elem) => { const keyValues = elem.split("="); obj[keyValues[0]] = keyValues[1]; }); return obj; } function measure(messageData) { const payload = Buffer.from(messageData.bulletin.payload.data, "hex").toString("utf8"); const data = unmarshall(payload); forwardAsMQTT(information.1000, data.i, data.d, "attrs"); } function forwardAsMQTT(apiKey, deviceId, state, topic) { const mqttTopic = "/" + apiKey + "/" + deviceId + "/" + topic; MQTT_CLIENT.publish(mqttTopic, land); } The full code of the MQTT-IOTA Gateway includes additional error handling and asynchronous data handling to defer the execution of a part until the next Event Loop iteration.
IOTA Tangle Device - Sample Code
The code for a device to connect to the IOTA Tangle is repeated on the device. Actuators must mind to an agreed topic in social club to be informed of commands. process.nextTick() can exist used to ensure commands are non missed and can exist candy when fourth dimension permits.
const iotaClient = crave("@iota/client"); const IOTA_CLIENT = new iotaClient.ClientBuilder().node("https://chrysalis-nodes.iota.cafe").build(); IOTA_CLIENT.getInfo().then(() => { IOTA_CLIENT.subscriber() .topic("letters/indexation/cmd") .subscribe((err, data) => { return process.nextTick(() => { readFromTangle(information); }); }); }); role readFromTangle(information) { const messageId = IOTA_CLIENT.getMessageId(payload); IOTA_CLIENT.getMessage() .information(messageId) .and so((messageData) => { const payload = Buffer.from(messageData.bulletin.payload.data, "hex").toString("utf8"); Southbound.processIOTAMessage(messageId, payload); }); } IOTA Tangle Device Command Acknowledgement
For real devices, the callback of a successful actuation should cause an acknowledgement to be sent. Acknowledgements are queued and sent in club. If an mistake occurs the acknowledgement must be resent or the command will remain in a PENDING state.
function processIOTAMessage(apiKey, deviceId, bulletin) { const keyValuePairs = message.split('|') || ['']; const command = getUltralightCommand(keyValuePairs[0]); process.nextTick(() => { IoTDevices.actuateDevice(deviceId, command) .and then((response) => { queue.push({ responsePayload, deviceId, command }); }); }); } const async = crave("async"); const queue = async.queue((data, callback) => { IOTA_CLIENT.message() .alphabetize("fiware/cmdexe") .data(data.responsePayload) .submit() .then((response) => { callback(); }) .take hold of((err) => { setTimeout(() => { queue.push(information); }, 1000); callback(err); }, 8); }); IOTA Tangle Device mensurate - Sample Code
Measures are dealt with in a similar manner. The payload is created in Ultralight syntax (including a timestamp) and pushed to a queue. The queue sends the measure to the IOTA Tangle and reschedules any failures.
function sendAsIOTA(deviceId, state) { const payload = 'i=' + deviceId + '&k=' + getAPIKey(deviceId) + '&d=' + state + '|t|' + new Appointment().toISOString(); queue.push(payload); } const async = require("async"); const queue = async.queue((payload, callback) => { IOTA_CLIENT.message() .index("fiware/attrs") .data(payload) .submit() .and then((message) => { callback(); }) .grab((err) => { setTimeout(() => { // resending measure queue.button(payload); }, 1000); callback(err); }, viii); }); Source: https://fiware-tutorials.readthedocs.io/en/latest/iot-over-iota-tangle.html
0 Response to "Iota Attachment Error Please Publish Again"
Post a Comment