This offer is only addressed to commercial customers including freelancers and entrepreneurs. All prices exclude all taxes.
Subscribe Find out first about new and important news
  • Share via email
  • Subscribe to blog alert

Connect a simple device to the Bosch IoT Suite

What you will learn

You will learn how to create an ESP8266-based device prototype and how to connect it to the Bosch IoT Suite services in the cloud.

By following this tutorial, you will also learn basics about what the Bosch IoT Suite is and how to work with its services. Additionally, you will experience your first steps with Bosch IoT Things and Bosch IoT Hub.

Duration of the tutorial

This tutorial will take you approximately three hours after having installed the necessary software.

What you need to prepare and download

Software:

Tasks to complete

Build your hardware device

Make sure to unplug the hardware from any power source before working on it. In the example setup below, we use a NodeMCU v2 and a 400 point breadboard. Feel free to replace them with any other ESP8266-based device and a fitting breadboard size.

Connect your illuminance sensor to the device as shown below.

Icon illustrating the registration of a device.

Book and configure the Bosch IoT Suite for Asset Communication package

Create a Bosch IoT Suite account

Login with your existing Bosch IoT Suite account or create a new one by following these steps:

  1. Navigate to the Bosch IoT Suite.
  2. Create a Bosch IoT Suite account.
  3. Login with your credentials.

Single sign-on with your Bosch user ID

In the process, you will create or reuse an existing Bosch ID. This user ID enables a single-sign-on (SSO) functionality that can be used for multiple Bosch applications.

Bosch IoT Suite documentation

For more information, have a look at the Bosch IoT Suite documentation.

Subscribe to the Bosch IoT Suite for Asset Communication package

Subscribe to the Bosch IoT Suite for Asset Communication package by following these steps:

  1. Navigate to Service Subscriptions.
  2. Click New Subscription.
  3. Follow the subscription wizard.

Your service subscription to the Asset Communication package includes:

  • A Bosch IoT Hub service instance
  • A Bosch IoT Things service instance
  • The unified Device Provisioning API for simplified device registration
  • Both are already fully preconfigured and connected to communicate with each other
  • A limited license for the Bosch IoT Suite Gateway Software, which is not used in this tutorial

Configure a namespace for your devices (digital twins)

Configure your unique Bosch IoT Things namespace by following these steps:

  1. Navigate to Bosch IoT Things by clicking Go to Dashboard.
  2. Click Solution/Namespace.
  3. Insert a new globally unique namespace using java package notation, e.g. your.things.namespace.
  4. Click Submit namespace.

Namespace

The namespace is used as a unique prefix for all your Thing IDs to make the thing IDs globally unique.

Bosch IoT Things documentation

For more information, have a look at the Bosch IoT Things documentation.

Create and configure a technical OAuth2.0 Client

Create an OAuth2 Client with full access to Bosch IoT Things and Bosch IoT Hub by following the next steps:

  1. Navigate to the Bosch IoT Suite.
  2. Click the user account icon , then click Sign In in the overlay.
  3. Once you are authenticated, click the user account icon , then click OAuth2 Clients in the overlay.
  4. In the section New OAuth2 Client insert a new name, e.g. Asset Communication Client.
  5. Select the Hub and the Things full access scopes.
  6. Click Create.

OAuth2.0 Client

You can use the OAuth2 Client in your application to authenticate it with many of the Bosch IoT Suite APIs as a technical client.

Generate a test token

Generate and copy a test token by following the next steps:

  1. Navigate to your Bosch IoT Suite.
  2. Click the user account icon , then click OAuth2 Clients in the overlay.
  3. Click Use next to your active OAuth2 Client.
  4. Copy the test token by clicking Copy to clipboard.

Test token

In this tutorial, you will mainly use a so-called test token of this client to authenticate against all HTTP REST APIs.

 

Note that the test token is only valid for 60 minutes each time you generate one.

Register your device with the Bosch IoT Suite

Register your device with the Bosch IoT Suite for Asset Communication package at the Device Provisioning API by following these steps:

  1. Click Authorize. A dialog opens. Paste the test token as value of the bearerAuth (http, Bearer) section. Proceed with Authorize, then Close the dialog.
  2. Unfold the provisioning section and click the POST method /{service-instance-id}/devices.
  3. Click Try it out.
  4. Add your Service Instance ID (you will find all important information as described in the infobox).
  5. Click Edit below the Edit Value field.
  6. Copy the following code and replace everything in the field Edit Value:
    { 
       "id":"<com.bosch.example:my-device-id-4711>",
       "hub":{ 
          "device":{ 
             "enabled":true
          },
          "credentials":{ 
             "type":"hashed-password",
             "secrets":[ 
                { 
                   "password":"<yourPassword>"
                }
             ]
          }
       },
       "things":{ 
          "thing":{ 
             "attributes":{ 
                "manufacturer":"<Robert Bosch GmbH>"
             },
             "features":{ 
                "illuminance":{ 
                   "definition":[ 
                      "org.eclipse.vorto:Illuminance:1.0.0"
                   ],
                   "properties":{ 
                      "status":{ 
                         "value":{ 
                            "currentMeasured":555,
                            "minMeasured":0,
                            "maxMeasured":999
                         }
                      }
                   }
                }
             }
          }
       }
    }
  7. Define your credentials (check the device credentials info box) by editing everything in <pointy brackets> (make sure to delete the <pointy brackets>).
  8. Click Execute to run your API call and register your device.

You should get a response with the code HTTP 201 created and a payload reflecting the device you just registered.

Service Instance ID

You can find all necessary information on your subscriptions in the Credentials section.

  1. Navigate to Service Subscriptions.
  2. Click Access Credentials in the specific row of the subscription you need the Instance ID for.
  3. For the Service Instance ID scroll down to the Access Credentials section.

Device credentials

"id":"<your.Things.namespace:your-generic-device-name>"

This is the ID put together by the namespace you already created here and the name of your device which you define here for the first time.

"password":"<your-device-password>"

Define your individual password here (we recommend six characters).

"manufacturer":"<Your awesome company>"

Insert the name of your company here.

Do not forget to delete the pointy brackets and remember your device password! Download the response in JSON notation. Thus, you can look up the authId and the password later.

HTTP 401 - Errorcode

If you get an HTTP 401 response, your test token has probably reached the end of its validity time. Generate a new token by opening your OAuth2.0 client list in a new tab, and clicking Use in the specific line where your client is listed.

Generate the boilerplate code for your firmware

Generate parts of the Bosch IoT Suite-related boilerplate code using a code generator and upload it to your device by following these steps:

Generate and download the firmware template

Generate parts of the Bosch IoT Suite-related boilerplate by following these steps:

  1. Open https://vorto.eclipse.org in a new browser window.
  2. Select the Bosch IoT Suite plugin from the list of Official Plugins on the right.
  3. Select the option Integrate device with Arduino and click Source Code.

This will download a ZIP file containing an Arduino project file and an additional src folder.

Visualization for click through Arduino code generation

Vorto Repository

Vorto is an open-source Eclipse IoT Community project, which aims to support standardization in the Internet of Things by creating a language, a repository, and a number of code generators for device descriptions.

Import the firmware and configure the Arduino IDE

Upload the firmware to your device by following these steps:

  1. Extract the downloaded package containing the Arduino project file SimpleIlluminanceApp.ino.
  2. Open Arduino IDE and open the project file.
  3. Import the PubSubClient library under Sketch/Include Library/Manage Libraries… In case of problems, you can download and add the pubsubclient-master.zip file manually.
  4. Adapt the PubSubClient.h header file (the path to the file is described in the infobox Where to find the PubSubClient.h file) by changing the MQTT_MAX_PACKET_SIZE to 1024.
  5. Connect your prototyping board to your computer via USB. Make sure to use a data cable, as a charging cable will not work.
  6. Select your ESP8266 prototyping board (e.g. NodeMCU 1.0) in Arduino under Tools/Board. If you cannot select any ESP8266-based board, install the ESP8266 Core for Arduino under Tools/Board/Boards Manager.
  7. Select the port your board has registered with under Tools/Port.
  8. Optional but recommended: Change the upload speed to the highest possible setting.

Troubleshooting

In case of problems, check Arduino IDE is behind a (corporate) proxy.

Where to find the PubSubClient.h file

On Windows and Mac, you will find the file in one of the following folders:

<Username>/Documents/Arduino/libraries/pubsubclient/src/
<Username>/Documents/Arduino/libraries/pubsubclient-2.7/src/
<Username>/Documents/Arduino/libraries/pubsubclient-master/src/

On Linux, you will find the file in the folder:

/home/<Username>/Sketchbook/libraries/pubsubclient-master/src/

Configure the firmware code for your prototype device

Configure your device firmware in the first 50 lines with the following details (replace everything in <pointy brackets> and delete them afterwards).

  • Asset Communication subscription credentials:
    tenantId: "<txxxxxxxxxxxxxxxxxxxx_hub>"
    hono_endpoint: "mqtt.bosch-iot-hub.com"

  • SHA-1 server fingerprint of the Bosch IoT Hub MQTT adapter:
    mqttServerFingerprint: "00 B6 42 DA A5 6F 5A 9F F3 B3 7E 50 90 58 32 4C 47 61 18 D5"
  • Your device provisioning request:
    deviceId: "<your.namespace>:<your-device-id-4711>"
    authId:  "<your.namespace>_<your-device-id-4711>"
    device_password: "<your-device-password>"
    
    ditto_topic: "<your.namespace>/<your-device-id-4711>"
  • Your WiFi details:
    ssid: "<ENTER YOUR WIFI SSID>"
    password: "<ENTER YOUR WIFI PASSWORD>"

Bosch IoT Hub - Eclipse Hono

Bosch IoT Hub is based on its open-source project Eclipse Hono. The endpoint of the Bosch IoT Hub service is pre-configured for your service instance.

Bosch IoT Things - Eclipse Ditto

Bosch IoT Things is based on its open-source project Eclipse Ditto.

Modify the firmware to send real data

Adapt the firmware on your device to send real data by following these steps:

  1. Initialize (initial and default values) the illuminance sensors by adding the following code at the end of the section setup():
    void setup() {
    
        ...
    
        org_eclipse_vorto_types::SensorValue value;
        /* minimum measured value since last reboot */
        value.setminMeasured(1024.0);
        /* maximum measured value since last reboot */
        value.setmaxMeasured(0.0);
        infoModel.illuminance.setvalue(value);
    }
    
  2. Read the current illuminance sensor reading, set the illuminance message payload accordingly, and publish the data by replacing the loop() function with:
    void loop() {    
        /* Check if connection to MQTT broker is still good */
        if (!mqttClient.connected()) {
            /* Reconnect if not */
            reconnect();
        }
    
        /* Event handling of the MQTT client */
        mqttClient.loop();
    
        /* Publish the telemetry data periodically */
        long now = millis();
        if (now - lastMqttMsg > MQTT_DATA_PERIOD) {
            lastMqttMsg = now;
    
            /* Read the values from input pin */
            int illuminanceValue = analogRead(A0);
            delay(3); //walk-around a bug in NodeMCU
    
            //Status Properties
            org_eclipse_vorto_types::SensorValue value = infoModel.illuminance.getvalue();
    
            /* current value */
            value.setcurrentMeasured(illuminanceValue);
    
            /* minimum value measured since last reboot */
            if (illuminanceValue < value.getminMeasured()) { value.setminMeasured(illuminanceValue); }; /* maximum value measured since last reboot */ if (illuminanceValue > value.getmaxMeasured()) {
                 value.setmaxMeasured(illuminanceValue);
            };
            
            infoModel.illuminance.setvalue(value);
    
            /* publish data to MQTT endpoint */
            publishIlluminance();
        }
    }
  3. Compile/verify the changes of the firmware by clicking the check button in the top left.
  4. Upload the firmware to your device by clicking the arrow button next to the check button.
  5. Open the serial monitor to check for debug information. If the output you received is unreadable output, change the baud rate of the serial monitor to 115200.

Functions of Arduino Sketches

Arduino Sketches has two main functions:

  • setup() is executed by the framework once at start-up, after bootloading is complete.
  • loop() will be executed repeatedly as soon as the setup is finished, with small interruptions for system tasks.

Check your work

Check your updated digital twin in the Bosch IoT Things. Open the API docs and switch to GET/things/{thingId}. Create a new test token (if the previous one is expired) by clicking Use on your OAuth2.0 client list.

  1. Click Authorize on the top right.
  2. In the dialog that opened, paste your test token as value of the bearer Auth (http, Baerer) section. Proceed with Authorize, then close the dialog.
  3. Click GET on the Things resource.
  4. Click Try it out.
  5. Add your Thing ID to the thingId field as follows:
    your.namespace:your-device-id-4711
  6. Click Execute to run your API call.

You should receive a response with the code HTTP 200 OK and a payload reflecting your Thing with the updated values for your sensors:

{ 
   "thingId":"com.bosch.example:my-device-id-4711",
   "policyId":"com.bosch.example:my-device-id-4711",
   "attributes":{ 
      "manufacturer":"Robert Bosch GmbH"
   },
   "features":{ 
      "illuminance":{ 
         "definition":[ 
            "org.eclipse.vorto:Illuminance:1.0.0"
         ],
         "properties":{ 
            "status":{ 
               "value":{ 
                  "currentMeasured":555,
                  "minMeasured":0,
                  "maxMeasured":999
               }
            }
         }
      }
   }
}

What your output should look like

On your serial monitor, the output should look like this:

Connecting to WiFi 
........................
WiFi connected
IP address: 123.123.123.123
MAC address: XX:XX:XX:XX:XX:XX
Device ID: com.bosch.iotacademy.demo:my-device-id-4711
Successfully established secure connection to broker
Successfully verified server certificate
Succesfully connected to MQTT Broker
Publishing Payload for illuminance: {"topic":"com.bosch.iotacademy.demo/my-device-id-4711/things/twin/commands/modify","headers":{"response-required": false},"path":"/features/illuminance","value": { "properties": {"status": {"value": {"currentMeasured": 723.00,"minMeasured": 723.00,"maxMeasured": 723.00,}},"configuration": {}}}} to topic: telemetry/txxxxxxxxxxxxxxxxxxxxxxxxx_hub/com.bosch.iotacademy.demo:my-device-id-4711
...

Icon illustrating the adapting of firmware.

Modify the firmware to enable command & control

In the sections above, you only used MQTT to push your device’s telemetry data to the Bosch IoT Hub MQTT Connector.

In order to receive data from the Bosch IoT Hub, the MQTT configuration of the device needs to be changed. After implementing the MQTT subscription, the device should send a response after receiving and processing the command.

To enable the command & control functionality via MQTT, you need to modify the firmware you already created by following these steps:

  1. Open Arduino IDE and open your project file SimpleIlluminanceApp.ino with which you have been working before.
  2. Replace the code of the reconnect() function with:
    void reconnect() {
      String username = String(authId) + "@" + String(tenantId);
        /* Loop while not connected */
        while (!mqttClient.connected()) {       
    
            /* If connected to the MQTT broker... */
                   
            if (mqttClient.connect(clientId.c_str(),username.c_str(),device_password)) {
                /* Attempt to Connect successful */               
                Serial.println("Successfully connected to MQTT Broker");
    
                /* Subscribe for command messages from Bosch IoT Hub */
                String topic = "control/+/+/req/#";
                mqttClient.subscribe(topic.c_str());
                Serial.println("Subscribed to topic: " + topic);
    
            } else {
              /* otherwise wait for 5 seconds before retrying */
              Serial.println("Waiting for next attempt to connect to MQTT Broker");
                delay(5000);
            }
        }
    }
  3. Replace the original mqttDataReceived() function code with the following code:
    void mqttDataReceived(char* mqttTopic, byte* mqttPayload, unsigned int mqttLength) {
    
        String reqTopic = (String) mqttTopic;
        reqTopic.toLowerCase();
        
        /* If this is a 'switch' command, flip the lights */
        if(reqTopic.startsWith("control") && reqTopic.endsWith("switch")) {
            String newState;
            Serial.println("Switch command received, switching ...");
            /* flip the lights  */
            if (digitalRead(2)==LOW) {
                digitalWrite(2,HIGH);
                newState="LED is now off!";
            } else {
                digitalWrite(2,LOW);
                newState="LED is now on!";
            }
    
            /* parse Bosch IoT Hub's message ID for response */
            String messageId = reqTopic.substring(reqTopic.indexOf("req/")+4);
            messageId = messageId.substring(0, messageId.indexOf("/"));
    
            /* if this is a 2-way command, respond */
            if (messageId != "") {
                /*Serial.println("Sender expects reply, responding to message with ID: " + messageId);*/
    
                /* create MQTT response topic */
                String resTopic = ("control///res/" + messageId + "/200").c_str();
    
                /* parse Bosch IoT Things correlation ID for response*/
                String reqPayload = (String) (char*) mqttPayload;
    
                /* 17 is the length of 'correlation-id' and subsequent '":"' */
                String correlationId;
                correlationId = reqPayload.substring(reqPayload.indexOf("correlation-id")+17);
           
                String correlationId2;
                correlationId2 = correlationId;
                correlationId.remove(correlationId2.indexOf("""));
    
                Serial.println("Sender expects reply, responding to message with Correlation-Id: " + correlationId);
    
                /* create Ditto compliant MQTT response payload */
                String resPayload = "{"topic":"" + ditto_topic + "/things/live/messages/switch",";
                resPayload += ""headers":{"correlation-id":"" + correlationId + "",";
                resPayload += ""version":2,"content-type":"text/plain"},";
                resPayload += ""path":"/inbox/messages/switch",";
                resPayload += ""value":"" + newState + "",";
                resPayload += ""status": 200 }";
    
                mqttClient.publish(resTopic.c_str(), resPayload.c_str());
            }
        }   
    }
    
  4. Add the following code lines at the end of the setup() function in order to integrate the LED functionality:
    /* Set GPIO 2 pin as output and switch the LED to LOW == 'on' */
    pinMode( 2, OUTPUT);
    digitalWrite( 2, LOW);
    
  5. Compile and upload the firmware to your prototyping device.

Fixed topic structure

When using MQTT and the Bosch IoT Hub, it is necessary to use a fixed topic structure while configuring a client.

  • Use control/+/+/req/# for regular subscriptions to receive command messages.
  • Use control///res/ + messageId + /200 in case of command & control to address a response message onto a message like a command.

Pin dependencies

The following code commands refer to a device-specific pin on the device board:

  • digitalRead(Pin) and
  • digitalWrite(Pin)

Make sure to use the correct pin depending on your hardware setup.

Further information

If you want to learn more about command & control with the Bosch IoT Suite, check out the documentation.

Handling of incoming messages

In reconnect(), you will need to implement an MQTT subscribtion to the control/+/+/req/ topic. This enables your device to receive data from the Bosch IoT Hub via MQTT.

 

The mqttDataReceived() function will be executed when an MQTT message comes in. Moreover, the received data needs to be interpreted to trigger a switching command. Additionally, the function should be pushed to the current LED state (JSON-compatible string) to keep the digital twin of your device up-to-date. This message should be handled as a response to the command which is defined in the MQTT response topic structure control///res/.

Check your work

Check your extended device functionality by sending commands out of Bosch IoT Things to switch the LED. In order to do, so open your digital twin in Bosch IoT Things – API V2.

  1. Scroll down and open the messages section by clicking Messages.
  2. Use the second Post method /things/{thingId}/inbox/messages/{messageSubject}.
  3. Click Try it out.
  4. Add your Thing ID into the thingId field.
  5. Insert switch into the messageSubject field.
  6. Click Edit below the Edit value field.
  7. Create an empty JSON object by inserting {}.
  8. Click Execute.

The LED of your device should now switch its state and you should receive a response with the code 200 and the text LED on or LED off depending on its current state.

Shortcut

If your code is not running properly, you can find the complete code example at the end of the troubleshooting section. Compare your code with the code example to get your device running. Feel free to copy sections but keep your credentials in mind.

Troubleshooting

In case of irregularities during the process check this section for help.

Arduino IDE is behind a (corporate) proxy

  • If you cannot download the list of additional boards, you might need to setup your proxy in the Arduino IDE. Go to File/Preferences/Network and setup your proxy accordingly.
  • If you can find the ESP8266 board plugin, but downloading does not work and gives you an SSL error, you might be behind a TSL terminating proxy. You need to add your proxy’s SSL certificate to your Arduino IDE’s shipped Java truststore, or simply replace the truststore with your system’s Java truststore. To do so, you need to copy the cacerts file from:
    C:/Program Files (x86)/Java/jre8/lib/security/

    and replace the existing cacerts file in:

    C:/Program Files (x86)/Arduino/java/lib/security/

Device is behind a proxy

This is currently not supported by the ESP8266 Core libraries. Your device needs to be connected in a proxy-free environment.

Find the right serial port

Arduino IDE does not discover the correct port for the ESP8266-based boards automatically. You need to set it using the Tools/Port menu. To find what you need to set, check the descriptions below:

Windows:

  1. Find the COM port number in the Windows Device Manager. Silicon Labs CP210x USB to UART Bridge (COM) indicates that the port is properly configured.
  2. If your prototyping board shows up with a yellow exclamation mark, you might need to install the driver for it manually. You can find the driver for the NodeMCU on their website.


Serial monitor displays “Secure connection failed, restart”

Make sure you have installed version 2.4.1 of the ESP8266 Core in Tools/Board/Boards Manager.

Screenshot of Arduino IDE Boards Manager with ESP8266 Core version 2.4.1 installed

Serial monitor displays “Verification failed, restart Device”

Make sure you are using the correct SHA-1 fingerprint and version 2.4.1 of the ESP8266 Core.

Serial monitor displays unreadable characters or “wdt reset”

Try to reset your device by pushing the reset button (e.g. RST Button in case of NodeMCU).

The Things API V.2 responds “timeout”

Reset the connection between your Bosch IoT Things and your Bosch IoT Hub service instance. Follow these steps:

  1. Navigate to Bosch IoT Things and open Solution/Connections/Integrations.
  2. Click the Devices via Bosch IoT Suite button.
  3. Open Management.
  4. Click the Close connection, wait a few seconds, and click the Open connection button.

Other problems concerning the device code

After all modifications, your code should look as follows:

// Generated by Vorto from com.bosch.iotacademy.tutorial.SimpleIlluminance:1.0.0

#define USE_SECURE_CONNECTION 1

#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#if (USE_SECURE_CONNECTION == 1)
    #include <WiFiClientSecure.h>
#endif
#include "src/model/functionblock/Illuminance.h"
#include "src/model/infomodel/SimpleIlluminance.h"

/**************************************************************************/
/* Configuration section, adjust to your settings                         */
/**************************************************************************/

#define tenantId "t8b3af6289f554943bdac1d55f112075a_hub"

/* MQTT broker endpoint */
const char* hub_adapter_host = "mqtt.bosch-iot-hub.com";

#if (USE_SECURE_CONNECTION == 1)
            /* SHA-1 fingerprint of the server certificate of the MQTT broker, UPPERCASE and spacing */
            const char* mqttServerFingerprint = "00 B6 42 DA A5 6F 5A 9F F3 B3 7E 50 90 58 32 4C 47 61 18 D5";
#endif

/* Define the period of data transmission in ms */
#define MQTT_DATA_PERIOD 10000

/* Define the buffer size for payload strings */
#define MQTT_MAX_SIZE  50

/* Device Configuration */
String deviceId = "my.second.thing:mcu";
String authId = "my.second.thing_mcu";
const char* device_password = "xxxxxx";

/* Payload Configuration*/
String ditto_topic = "my.second.thing/mcu";

/* WiFi Configuration */
const char* ssid = "Your SSID";
const char* password = "Your Wifi Password";

/* BEGIN SAMPLE CODE */
/* dummy numeric */
long dummy_value = 0;

/* Sample text value */
char msg[MQTT_MAX_SIZE];
/* END SAMPLE CODE */

/**************************************************************************/
/* Implementation                                                         */
/**************************************************************************/

/* Port on which the MQTT broker is listening */
#if (USE_SECURE_CONNECTION == 1)
    #define MQTT_SERVER_PORT 8883
#else
    #define MQTT_SERVER_PORT 1883
#endif

/* Topic on which the telemetry data is published */
String telemetryTopic = String("telemetry/") + String(tenantId) + String("/");

/* This variables stores the client ID in the MQTT protocol */
String clientId;

/* Timestamp of previous data transmission */
long lastMqttMsg;

/* Setup WiFi mqttClient and MQTT mqttClient */
#if (USE_SECURE_CONNECTION == 1)
    WiFiClientSecure wifiClient;
#else
    WiFiClient wifiClient;
#endif
PubSubClient mqttClient(wifiClient);

/* The information model object */
com_bosch_iotacademy_tutorial::SimpleIlluminance infoModel;

/**************************************************************************/
/* Function to connect to the WiFi network                                */
/**************************************************************************/
void setup_wifi() {

    delay(10);
  
    /* We start by connecting to a WiFi network */
    Serial.print("Connecting to WiFi with SSID: ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);

    /* Wait for succesful connection, hang if there is none? */
    while (WiFi.status() != WL_CONNECTED) {
            Serial.print(".");
        delay(500);
    }

    randomSeed(micros());

    Serial.println("");
    Serial.println("WiFi connected");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
    Serial.print("MAC address: ");
    Serial.println(WiFi.macAddress());
}

/**************************************************************************/
/* Function called when data on a subscribed topic arrives                */
/**************************************************************************/
void mqttDataReceived(char* mqttTopic, byte* mqttPayload, unsigned int mqttLength) {

    String reqTopic = (String) mqttTopic;
    reqTopic.toLowerCase();
    
    /* If this is a 'switch' command, flip the lights */
    if(reqTopic.startsWith("control") && reqTopic.endsWith("switch")) {
        String newState;
        Serial.println("Switch command received, switching ...");
        /* flip the lights  */
        if (digitalRead(2)==LOW) {
            digitalWrite(2,HIGH);
            newState="LED is now off!";
        } else {
            digitalWrite(2,LOW);
            newState="LED is now on!";
        }

        /* parse Bosch IoT Hub's message ID for response */
        String messageId = reqTopic.substring(reqTopic.indexOf("req/")+4);
        messageId = messageId.substring(0, messageId.indexOf("/"));

        /* if this is a 2-way command, respond */
        if (messageId != "") {
            /*Serial.println("Sender expects reply, responding to message with ID: " + messageId);*/

            /* create MQTT response topic */
            String resTopic = ("control///res/" + messageId + "/200").c_str();

            /* parse Bosch IoT Things correlation ID for response*/
            String reqPayload = (String) (char*) mqttPayload;

            /* 17 is the length of 'correlation-id' and subsequent '":"' */
            String correlationId;
            correlationId = reqPayload.substring(reqPayload.indexOf("correlation-id")+17);
       
            String correlationId2;
            correlationId2 = correlationId;
            correlationId.remove(correlationId2.indexOf("""));

            Serial.println("Sender expects reply, responding to message with Correlation-Id: " + correlationId);

            /* create Ditto compliant MQTT response payload */
            String resPayload = "{"topic":"" + ditto_topic + "/things/live/messages/switch",";
            resPayload += ""headers":{"correlation-id":"" + correlationId + "",";
            resPayload += ""version":2,"content-type":"text/plain"},";
            resPayload += ""path":"/inbox/messages/switch",";
            resPayload += ""value":"" + newState + "",";
            resPayload += ""status": 200 }";

            mqttClient.publish(resTopic.c_str(), resPayload.c_str());
        }
    }   
}


/**************************************************************************/
/* Reconnect to MQTT broker in case the connection dropped                */
/**************************************************************************/
void reconnect() {
  String username = String(authId) + "@" + String(tenantId);
    /* Loop while not connected */
    while (!mqttClient.connected()) {       

        /* If connected to the MQTT broker... */
               
        if (mqttClient.connect(clientId.c_str(),username.c_str(),device_password)) {
            /* Attempt to Connect successful */               
            Serial.println("Successfully connected to MQTT Broker");

            /* Subscribe for command messages from Bosch IoT Hub */
            String topic = "control/+/+/req/#";
            mqttClient.subscribe(topic.c_str());
            Serial.println("Subscribed to topic: " + topic);

        } else {
          /* otherwise wait for 5 seconds before retrying */
          Serial.println("Waiting for next attempt to connect to MQTT Broker");
            delay(5000);
        }
    }
}

/**************************************************************************/
/* Functions for publishing data using MQTT                                                                     */
/**************************************************************************/

boolean publishIlluminance() {                            
                        String mqttPayload = infoModel.illuminance.serialize(ditto_topic ,deviceId, "illuminance");
            
                        /* Debug output on console */
                        Serial.print("Publishing Payload for illuminance: "); 
                        Serial.print(mqttPayload);
                        Serial.print(" to topic: "); 
                        Serial.println(telemetryTopic);
            
                        /* Publish all available illuminance data to the MQTT broker */
                        if(!mqttClient.publish(telemetryTopic.c_str(), mqttPayload.c_str())) {                              
                                    Serial.println("Publish illuminance failed, if this happens repeatedly increase MQTT_MAX_PACKET_SIZE in PubSubClient.h");                                
                                    return false;
                        } else {                             
                                    return true;                                
                        }                       
}           

/**************************************************************************/
/* Arduino Setup and Loop Functions                                                                                            */
/**************************************************************************/
void setup() {                     
    Serial.begin(115200);
    
    setup_wifi();
  
   /* Create a MQTT client ID */
    clientId = deviceId;
    
    Serial.print("Device ID: ");
    Serial.println(clientId);
    
    /* Add the device ID to the telemetry topic as the final element */
    telemetryTopic += deviceId;
  
    /* Configure the MQTT client with the server and callback data */
    mqttClient.setServer(hub_adapter_host, MQTT_SERVER_PORT);
    mqttClient.setCallback(mqttDataReceived);

    #if (USE_SECURE_CONNECTION == 1)
        if (!wifiClient.connect(hub_adapter_host, MQTT_SERVER_PORT)) {
             Serial.println("Secure connection failed, restart Device");                         
                    ESP.restart();
        } else {
             Serial.println("Successfully established secure connection to broker");
                        }
                        
        if (!wifiClient.verify(mqttServerFingerprint, hub_adapter_host)) {
            Serial.println("Verification failed, restart Device"); 
                    ESP.restart();
        } else {
             Serial.println("Successfully verified server certificate");
        }
    #endif
    
    /*Test MQQT Client*/
    mqttClient.publish("","");

org_eclipse_vorto_types::SensorValue value;
    /* minimum measured value since last reboot */
    value.setminMeasured(1024.0);
    /* maximum measured value since last reboot */
    value.setmaxMeasured(0.0);
    infoModel.illuminance.setvalue(value);

  /* Set GPIO 2 pin as output and switch the LED to LOW == 'on' */
      pinMode( 2, OUTPUT);
    digitalWrite( 2, LOW);

    
}

void loop() {    
    /* Check if connection to MQTT broker is still good */
    if (!mqttClient.connected()) {
        /* Reconnect if not */
        reconnect();
    }

    /* Event handling of the MQTT client */
    mqttClient.loop();

    /* Publish the telemetry data periodically */
    long now = millis();
    if (now - lastMqttMsg > MQTT_DATA_PERIOD) {
        lastMqttMsg = now;

        /* Read the values from input pin */
        int illuminanceValue = analogRead(A0);
        delay(3); //walk-around a bug in NodeMCU

        //Status Properties
        org_eclipse_vorto_types::SensorValue value = infoModel.illuminance.getvalue();

        /* current value */
        value.setcurrentMeasured(illuminanceValue);

        /* minimum value measured since last reboot */
        if (illuminanceValue < value.getminMeasured()) { value.setminMeasured(illuminanceValue); }; /* maximum value measured since last reboot */ if (illuminanceValue > value.getmaxMeasured()) {
             value.setmaxMeasured(illuminanceValue);
        };
        
        infoModel.illuminance.setvalue(value);

        /* publish data to MQTT endpoint */
        publishIlluminance();
    }
}
Cookie Information

This website uses cookies for reasons of functionality, comfort, and statistics. If you consent to this use of cookies, please click ”Ok“. If you like to disable the cookies for webtracking, please click here. For more information see our Privacy Policy