[PYTHON] Send and receive data with MQTT via Watson IoT Platform

Introduction

Watson IoT Platform (Internet of Things Platform, hereafter WIOTP) is a platform for IoT based on IBM Cloud. It provides various functions such as collecting, accumulating, and visualizing data obtained from devices such as sensors. The official SDK for connecting devices and applications is provided, and data can be sent and received via MQTT. This article will explain how to do this.

Watson IoT Platform concept

First, I will explain the concept of "things" handled by WIOTP. WIOTP defines the following three types of "things" to be connected, and the functions and connection methods that can be implemented differ for each.

--Application --Device --Gateway

application

The application can use the most features of the three things, receive events sent from the device and use them for services, or send events as a device on its own. In order to implement it as an application, it is necessary to issue an API key in the WIOTP console in advance. By authenticating with the API key when connecting to WIOTP, the connected application can be identified by WIOTP. In addition, WIOTP defines the expected application type, and you can limit the functions that can be used by selecting the application type for each API key.

The following features are available in the application: --Receive events sent from your device --Send commands to the device --Send events as a device --Receive commands as a device

device

The role of the device is to send the surrounding information obtained by sensors etc. to WIOTP. In order to implement it as a device, it is necessary to set the device type and device ID in the WIOTP console in advance, and set the device ID so that it is unique for each device. In WIOTP, the device ID can be used to identify which device made the connection request or data transmission.

The following features are available on your device: --Send an event to the application, such as "A person was detected by a motion sensor" --Receive commands sent by the application

gateway

When there are multiple devices of the same type and role, the role of the gateway is to relay data between them and WIOTP. By doing so, WIOTP can actually treat the data sent from multiple devices as if it was sent from one device (gateway), making it easier to process the data. As with the device, the gateway needs to set the device type and device ID on the WIOTP console in advance. It is treated as one of the devices in WIOTP.

The following features are available on the gateway: --Receive events sent by your device and relay them to your application --Receive commands sent by the application and relay them to the device

Creating a sample

We will actually use the official SDK to create a sample app that sends and receives events to WIOTP on a regular basis. This time, create the sender as a device and the receiver as an application.

Premise

--Own an IBM Cloud account --You have already created an instance of Watson IoT Platform on IBM Cloud.

Advance preparation

Device settings in WIOTP

Register the device required to implement the device.

--Open an instance of Watson IoT Platform and open "Devices" from the menu on the left side of the screen. ――The page that says "Browse for device" is displayed. Click the "Add device" button on the upper right. image.png

--Set any value for "Device Type" and "Device ID", and click the "Next" button. image.png

--On the next page, just click the "Next" button without entering anything. --The "Automatically Generated Authentication Token" page is displayed. The "authentication token" can be automatically generated or set to any value. After setting, click the "Next" button. image.png

--The summary screen will be displayed. Click the "Finish" button. --Device registration is complete when the "Device Drilldown" page is displayed. Make a note of the information displayed here as you will use it later. image.png

Issuing API keys with WIOTP

Issue the API key needed to implement your application. For details, see "1. Issuing API Keys" in the following article. https://qiita.com/Motonaga/items/6304f5f66f63cb566943

Sender implementation

Implement the sending device.

publish.py


import wiotp.sdk.application
import time
import json

##Embed various parameters for "device" set in WIOTP in JSON format configuration information (options)
org_id = "xxxx" #WIOTP Organization ID
device_id = "sample_id" #"Device ID" set in advance
device_type = "sample_type" #"Device type" set in advance
token = "sample-token" #"Authentication token" set in advance
event_id = "sample" #The identifier of the event to send. Any value can be set. Make it the same value as the receiving side

options = {
  "identity": {
    "orgId": org_id,
    "typeId": device_type,
    "deviceId": device_id
  },
  "auth": {
    "token": token
  }
}

#Connect to WIOTP as a "device" using the SDK
client = wiotp.sdk.device.DeviceClient(options,  logHandlers=None)
client.connect()

#Every 2 seconds{count}Increment and send to WIOTP
myData = {'message': 'foo', 'count': 0}
while True:
  print("data published: ", json.dumps(myData))
  client.publishEvent(event_id, "json", myData)
  myData['count'] += 1
  time.sleep(2)

Implementation on the receiving side

Implement the receiving application.

subscribe.py


import wiotp.sdk.application
import json
import time

app_id = "sample_app" #Application identifier. Set any value
app_auth_key = "xxxx" #API key of application issued by WIOTP
app_auth_token = "xxxx" #WIOTP-issued application authentication token

#Embed various parameters for "application" set in WIOTP in JSON format configuration information (options)
options = {
  "identity": {
    "appId": app_id
  },
  "auth": {
    "key": app_auth_key,
    "token": app_auth_token
  }
}

#Connect to WIOTP as an "application" using the SDK
client = wiotp.sdk.application.ApplicationClient(options, logHandlers=None)
client.connect()

#Set the callback function when an event is received. Here, the received event information is written to the standard output.
def event_callback(event):
  #The body of the received data is event.Can be obtained with data
  print("{} event '{}' received from device [{}]: {}".format(event.format, event.eventId, event.device, json.dumps(event.data)))
client.deviceEventCallback = event_callback

#Set the parameters of the device to subscribe to (same as the sender) and start Subscribe
device_id = "sample_id" #"Device ID" set in advance
device_type = "sample_type" #"Device type" set in advance
event_id = "sample" #The identifier of the event to receive. Any value can be set. Make it the same value as the sender

client.subscribeToDeviceEvents(typeId=device_type, deviceId=device_id, eventId=event_id)

#Run a loop to keep your app up and running
while True: 
  time.sleep(3)

Execution result

If you execute both the sender and the receiver, you will get the following results, and you can confirm that the data can be sent and received via MQTT as expected.

WIOTP device console (displays the contents of sent events)

image.png

Receiving console

$ python subscribe.py 
2019-12-23 15:41:58,308   wiotp.sdk.application.client.ApplicationClient  INFO    Connected successfully: a:a54k3u:sample_app
json event 'sample' received from device [sample_type:sample_id]: {"message": "foo", "count": 0}
json event 'sample' received from device [sample_type:sample_id]: {"message": "foo", "count": 1}
json event 'sample' received from device [sample_type:sample_id]: {"message": "foo", "count": 2}
json event 'sample' received from device [sample_type:sample_id]: {"message": "foo", "count": 3}
json event 'sample' received from device [sample_type:sample_id]: {"message": "foo", "count": 4}
json event 'sample' received from device [sample_type:sample_id]: {"message": "foo", "count": 5}
json event 'sample' received from device [sample_type:sample_id]: {"message": "foo", "count": 6}

Summary

In this article, I explained the concept of "things" that connect to Watson IoT Platform and how to connect using the official SDK. Regarding the connection method, I created the sender as a device and the receiver as an application, but when using it in the actual field, I think that there will be many implementations in which multiple devices are relayed by the gateway.

Reference material

Recommended Posts

Send and receive data with MQTT via Watson IoT Platform
Send and receive binary data via serial communication with python3 (on mac)
Send and receive image data as JSON over the network with Python
Start communication with UDP and send and receive with TCP
Send and receive Gmail via the Gmail API using Python
Send and receive Flask images
Let's use Watson IoT Platform Data Store Connector a little more
[aws] Send and receive sqs messages
Send email via gmail with Python 3.4.3.
Access WebAPI with Python and register / acquire IoT data (dweet.io, Requests, HTTPie)
Data pipeline construction with Python and Luigi
POST variously with Python and receive with Flask
Send data to DRF API with Vue.js
Send files via bastion server with scp