This tutorial explains how to integrate a device with the Bosch IoT Suite using MQTT. Your device should already be created as a thing from an Information Model at this point.
We will use our RaspberryPi Information Model again.
-
Python is installed
-
Some code editor is installed (e.g. VSCode)
-
Created a thing in the Bosch IoT Suite (refer to Creating a Thing in the Bosch IoT Suite).
Note: This tutorial will only show the integration of the in-built temperature sensor of the RaspberryPi. Sending the data to hub, however, is similarilly done for the other sensors.
- Setup your device
- Download the generated integration script
- Configure the scripts with the information of your created thing
- Reading the sensor data
- Start sending data
Note: This tutorial will assume that your RaspberryPi is already running a version of Raspbian and is connected to the network.
You can either use a display, keyboard, and mouse to directly work on the RaspberryPi or setup SSH and later copy your script over to it.
1. On the Vorto Repository page of your Information Model (we will use the RaspberryPi Information Model), click on the Bosch IoT Suite
generator. This will trigger a pop up to appear with the available generators.
2. We want to integrate a device using Python. Click the Source Code
button to download the generated python script.
3. Unzip the downloaded file and open it in your code editor.
4. In order to guarantee secure transmission of your data, the integration uses SSL. We therefore need a certificate.
Right click and save the iothub.crt file and place it in the root folder of the just unzipped folder.
5. Before we start reading in the sensor data and sending it to Hub, we need to configure our credentials. This will allow the script to send the sensor data to our digital twin.
The main .py
file (RaspberryPiApp.py
in this case) will contain a section that looks like this:
# DEVICE CONFIG GOES HERE
tenantId = "ADD TENANT HERE"
device_password = "ADD DEVICE PASSWORD HERE"
hub_adapter_host = "mqtt.bosch-iot-hub.com"
deviceId = "ADD DEVICE ID HERE"
clientId = deviceId
authId = "ADD AUTH ID HERE"
certificatePath = "./iothub.crt"
ditto_topic = "ADD TOPIC HERE, e.g. com.mycompany/4711"
Note: Make sure to point the
certificatePath
at your just downloaded.crt
file.
6. We will use the request response we got upon creating a thing with the postman script. Since it holds exactly the information we need, we can copy and paste the different ids from the response.
7. After filling in the credentials, we can start integrating our sensors.
The implementation is done inside of the periodicAction
function.
This function is called periodically every timePeriod
seconds. It is meant to periodically read your sensor's values and transmit them using the thing type as a data model layer and the Paho MQTT Client.
The variable timePeriod
is set further down in the file. In this example, the variable timePeriod
is set to 10.
# Period for publishing data to the MQTT broker in seconds
timePeriod = 10
8. We will only cover the integration of the built-in cpu temperature sensor here.
The code contains comments which will tell you where to edit code and do your implementation.
There is no need to edit any other section of the python file.
Code sections which can be customized for your needs are marked with
### BEGIN SAMPLE CODE
...
### END SAMPLE CODE
In order to read the cpu temperature, we need to add this code block inside the periodicAction
function between the BEGIN
and END
comments.
def get_cpu_temperature():
with open("/sys/class/thermal/thermal_zone0/temp", "r") as tempFile:
temp = float(tempFile.read())
tempC = temp/1000
return tempC
# Read the data and assign it to the functional block properties
infomodel.cpuTemperature.value = {
"currentMeasured" : get_cpu_temperature()
}
Note: In order to implement the sensors in the right way, we have to look at the specifc paths of the attributes.
How do I find the specific path?
The cpuTemperature
in our Raspbi IM is a Temperature Function Block.
infomodel RaspberryPi {
functionblocks {
...
cpuTemperature as Temperature
}
}
This means we have to check the internals of this FB.
functionblock Temperature {
status {
value as SensorValue
}
}
As we can see, it has a value
which is a SensorValue Data Type. This DT has one mandatory value, currentMeasured
and two optional ones.
Since the nesting ends with this DT, we know that the path to our currentMeasured
and optional values is:
cpuTemperature -> value -> currentMeasured, minMeasured, ...
Therefore the structure will look like this:
cpuTemperature.value.currentMeasured
cpuTemperature.value.minMeasured
cpuTemperature.value.maxMeasured
Which in combination with the parent element is represented like this:
infomodel.cpuTemperature.value = {
"currentMeasured" : 0.0,
"minMeasured": 0.0,
"maxMeasured": 0.0
}
9. Before we can run the script, we need to install additional dependencies. The bundle contains a file called requirements.txt
. This file describes the dependencies that still have to be installed in order to run the script.
Install the dependencies using the pip install -r requirements.txt
command which looks at the current requirements.txt
file and installs the dependecies listed there.
10. Once the dependencies are installed, we can start the script by simply typing python RaspberryPiApp.py
.
After starting the script using you Terminal, you should be able to observe the sensor data being sent to Hub. This will looks something like this:
Publish Payload: {"topic": "com.bosch.xyz.sandbox/raspbi123/things/twin/commands/modify","headers": {"response-required": false},"path": "/features/location/properties","value" : {"status" : {"latitude": 1.34749, "longitude": 103.841133}, "configuration" : {} } } to Topic: telemetry/t0e7d25ea57db4191ab41415a432f5a50_hub/com.bosch.xyz.sandbox:raspbi123
Publish Payload: {"topic": "com.bosch.xyz.sandbox/raspbi123/things/twin/commands/modify","headers": {"response-required": false},"path": "/features/battery/properties","value" : {"status" : {"remainingCapacity": {"value": 86}, "value": {"currentMeasured": 86, "minMeasured": 0, "maxMeasured": 100}}, "configuration" : {"remainingCapacityAmpHour": 0} } } to Topic: telemetry/t0e7d25ea57db4191ab41415a432f5a50_hub/com.bosch.xyz.sandbox:raspbi123
If you don't see the Terminal outputting this kind of sensor data packages, unfold the following section.
Your script is not sending data?
If you started the script and you can't see any data being sent your script most likely contains an error in the way the values are assigned to the attributes.
In order to see the error message, you need to add a logger to the script.
This is easily done by adding the logging module at the top:
import logging
logging.basicConfig(level=logging.DEBUG)
And near the end of the file, where the client is created, you have to only paste in those two lines:
# Create the MQTT client
client = mqtt.Client(hono_clientId)
...
logger = logging.getLogger(__name__)
client.enable_logger(logger)
If you see the sensor data being sent as shown in the Publish Payload:...
example above but you still can't see any changes in the Dashboard or SwaggerUI API when retrieving the current state of the Thing, the connection between Hub and Things might have corrupted at some point.
This is simple to solve. This so called "Bridge" is created by default one subscribing to the Asset Communication.
-
Head over to your Subscriptions page and click on the Go to Dashboard button of your Asset Communication Subscription.
-
On the newly opened tab, click on the Connection tab that will display all the connections you've set up. By default there will be a Telemetry Bosch IoT Hub connection.
Note that if there is a problem, you will see a triangle with an exclamation mark inside that indicates some failed connection.
-
Click on the connection and hit the Close connection button. Wait until the connection is closed.
-
Once the connection was closed, re-open it by clicking the Open connection button.
-
After the connection has been re-established, restart your sensor data sending script and observe.
Your get an error message?
If you started the script and you get an getaddr
error, this means that the address resolution could not take place. This can have several reasons.
However, it's most likely that you either are not connected to the internet or a proxy is blocking the sending of sensor data.
Unfortunately, for now you can't set any proxy. Please switch to a network without Proxy.
If you see the sensor a log message with the error value of 4
, this means that the connection was refused due to some bad user name or password. However, this can relate to any of the fields in the configuration tab.
Therefore you have to go in and double check every field of the configuration section for an additional space or some character that does not belong there.
Please note that if you have followed the other tutorials, this error is definitely due to a fault in entering the credentials correctly.
11. We can now verify that there is data incoming by either using
- the Vorto Dashboard that simply displays your data in different UI widgets.
- or the SwaggerUI which doesn't require anything to be installed and allows a quick insight into whether your data is updating.
Once you can see your data updating, you have successfully connected your ESP8266 device to the Bosch IoT Suite! Now you can go in and connect and integrate the GPS and battery.
- Use the Vorto Dashboard to visualize the device data in UI widgets.
- Generate an OpenAPI Spec for your device
- Integrate your device with the Bosch IoT Suite using:
In case you're having difficulties or facing any issues, feel free to create a new question on StackOverflow and we'll answer it as soon as possible!
Please make sure to use eclipse-vorto
as one of the tags.