Contents

DashIO IoT Guide (ESP32)

7 September 2022

So, what is DashIO? It is a quick effortless way to connect your IoT device to your phone, tablet or iPad. It allows easy setup of controls such as Dials, Text Boxes, Maps, Graphs, Notifications..., from your IoT device. You can define the look and layout of the controls on your phone from your IoT device. There are three methods to connect to your phone; Bluetooth Low Energy (BLE), TCP or MQTT. What's dash then? dash is a MQTT server with extra bits added in to allow you to store data, send notifications, share your devices, and save your DashIO app setup.

This guide demonstractes how to make BLE, TCP and MQTT connections to an ESP32 IoT device using the Arduino IDE.

The MQTT connection discussed in this guide is SSL/TLS enabled and we highly recommend that you only use SSL/TLS connections. The Dash MQTT server only accepts SSL connections.

Getting Started

For the big picture on DashIO, take a look at our website: dashio.io

For the DashIO arduino library: github.com/dashio-connect/arduino-dashio

Requirements

Grab an ESP32 board, Arduino IDE and follow this guide. The examples in this guide should work on ESP32 development boards available for the Arduino IDE.

You will need to install the DashIO app on your pobile phone or tablet. And if you'd like to connect to one IoT device for free, setup a free DashIO account from within the DashIO app.

Install

DashIO

You will need to add the DashIO library into your project. Download the DashIO library from GitHub with the following link: https://github.com/dashio-connect/arduino-dashio

Place the DashIO library files into your project directory or add them into your library.

ESP32 Support (WiFi, TCP and mDNS)

If you haven't yet installed the ESP32 Arduino IDE support from espressif, please check the following link for instructions: https://github.com/espressif/arduino-esp32#installation-instructions

From the ESP32 espressif library, we will use the secure WiFi client (WiFiClientSecure.h) to enable SSL connections, which are required for the dash server.

For mDNS, we are using the ESPmDNS library, which is included in the ESP32 espressif library.

MQTT

For MQTT we are using the arduino-mqtt library created by Joël Gähwiler. This is available in the Arduino IDE Library Manager, by searching for "mqtt" and installing the library titled "MQTT" by Joël Gähwiler. This library is also stored on GitHub where there are examples and other useful information: https://github.com/256dpi/arduino-mqtt

BLE

We will use the ESP32 BLE Arduino library by Neil Kolban, which is included in the Arduino IDE Library manager. Seach the library manager for the library titled "ESP32 BLE Arduino" and install.

Guide

BLE Basics

Lets start with a simple BLE connection.

#include "DashioESP.h"

DashioDevice dashioDevice("ESP32_Type");
DashioBLE    ble_con(&dashioDevice, true);

void setup() {
    Serial.begin(115200);
    
    ble_con.begin();
    dashioDevice.setup(ble_con.macAddress(), "Joe Name"); // unique deviceID, and device name
}

void loop() {
    ble_con.run();
}

This is about the fewest number of lines of code necessary to get talking to the DashIO app. There is a lot happening under the hood to make this work. After the #include "DashioESP.h" we create a device with the device_type as its only attribute. We also create a BLE connection, with the newly created device being an attribute to the connection. The second attribute of the BLE connection enables the received and transmitted messages to be printed to the serial monitor to make debugging easier.

In the setup() function we start the BLE connection with ble_conn.begin(). For BLE connections we start the connection before dashioDevice.setup. This is to make sure we get a sensible value for the mac address, which is then supplied to the device as a unique device_ID.

We call the device setup function dashioDevice.setup(ble_con.macAddress(), "Joe Name") with two parameters that describe the device to the DashIO app to allow it uniquely identify and provide a name for each device.

This device is discoverable by the DashIO app. You can also discover your IoT device using a thiry party BLE scanner (e.g. "BlueCap" or "nRF Connect"). The BLE advertised name of your IoT device will be a concatentation of "DashIO_" and the device_type.

Setup the Arduino IDE serial monitor to 115200 baud and run the above code. Then run the DashIO app on your mobile device and you will see connection "WHO" messages on the Arduino serial monitor as the DashIO app detects and communicates with your IoT device.

Troubleshooting: Occasionally, the DashIO app is unable to discover a BLE connection to the IoT device. If this occurs, try deleting the the IoT device from the Bluetooth Settings of your phone or tablet.

Lets add Dial control messages that are sent to the DashIO app every second. To do this we create a new task to provide a 1 second time tick and then send a Dial value message from the loop every second.

#include "DashioESP.h"

DashioDevice dashioDevice("ESP32_Type");
DashioBLE    ble_con(&dashioDevice, true);

bool oneSecond = false; // Set by timer every second.

void oneSecondTimerTask(void *parameters) {
    for(;;) {
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        oneSecond = true;
    }
}

void setup() {
    Serial.begin(115200);
    
    ble_con.begin();
    dashioDevice.setup(ble_con.macAddress(), "Joe Name"); // unique deviceID, and device name

    // Setup 1 second timer task
    xTaskCreate(
        oneSecondTimerTask,
        "One Second",
        1024, // stack size
        NULL,
        1, // priority
        NULL // task handle
    );
}

void loop() {
    ble_con.run();

    if (oneSecond) { // Tasks to occur every second
        oneSecond = false;
        ble_con.sendMessage(dashioDevice.getDialMessage("D01", int(random(0, 100))));
    }
}

The line dashioDevice.getDialMessage("D01", int(random(0, 100))) creates the message with two parameters. The first parameter is the control_ID which identifies the specific Dial control in the DashIO app and the second parameter is simply the Dial value.

Once again, run the above code and the DashIO app. This time, a new "DIAL" messages will be seen on the serial monitor every second.

The next step is to show the Dial values from the messages on a control on the DashIO app.

In the DashIO app, tap the All Devices button, followed by the Find New Device button. Then select the BLE Scan option to show a list of new IoT devices that are BLE enabled. Your IoT device shpuld be shown in the list. Select your device and from the next menu select Create Device View. This will create an empty Device View for your new IoT deivce. You can now add controls to the Device View:

  • Start Editing: Tap the Edit button (it not already in editing mode).
  • Add Dial Control: Tap the Add Control button and select the Dial control from the list.
  • Edit Controls: Tap the Dial control to select it. The Control Settings Menu button will appear in the middle of the Control. The Control can then be dragged and resized (pinch). Tapping the button allows you to edit the Control settings where you can setup the style, colors and other characteristics of your Control. Make sure the Control_ID is set to the same value that is used in the dial messages (in this case it should be set to "D01").
  • Quit editing: Tap the Edit button again.

The Dial on the DashIO app will now show the random Dial values as they arrive.

The next piece of the puzzle to consider is how your IoT device can receive data from the DashIO app. Lets add a Knob and connect it to the Dial.

In the DashIO app you will need to add a Knob control onto your Device View, next to your Dial control. Edit the Knob to make sure the Control ID of the knob matches what you have used in your knob messages (in this case it should be "KB01"), then quit edit mode.

Next, in the Arduino code we need to respond to messages coming in from a Knob control that we just added to the DashIO app. To make the changes to your IoT device we add a callback, processIncomingMessage, into the BLE connection with the setCallback function.

#include "DashioESP.h"

DashioDevice dashioDevice("ESP32_Type");
DashioBLE    ble_con(&dashioDevice, true);

void processIncomingMessage(MessageData * messageData) {
    switch (messageData->control) {
    case knob:
        if (messageData->idStr == "KB01") {
            String message = dashioDevice.getDialMessage("D01", (int)messageData->payloadStr.toFloat());
            ble_con.sendMessage(message);
        }
        break;
    }
}

void setup() {
    Serial.begin(115200);
    
    ble_con.setCallback(&processIncomingMessage);
    ble_con.begin();
    dashioDevice.setup(ble_con.macAddress(), "Joe Name"); // unique deviceID, and device name
}

void loop() {
    ble_con.run();
}

We obtain the Knob value from the message data payload that we receive in the processIncomingMessage function. We then create a Dial message with the value from the knob and send this back to the DashIO app. Remember to remove the timer and the associated Dial ble_con.sendMessage from the loop() function.

When you adjust the Knob on the DashIO app, a message with the knob value is sent your IoT device, which returns the knob value into the dial control, which you will see on the DashIO app.

Finally, we should respond to the STATUS message from the DashIO app. STATUS messages allows the IoT device to send initial conditions for each control to the DashIO app as soon as a connection becomes active. Once again, we do this from the processIncomingMessage function and our complete code looks like this:

#include "DashioESP.h"

DashioDevice dashioDevice("ESP32_Type");
DashioBLE    ble_con(&dashioDevice, true);

int dialValue = 0;

void processStatus(ConnectionType connectionType) {
    String message((char *)0);
    message.reserve(1024);

    message = dashioDevice.getKnobMessage("KB01", dialValue);
    message += dashioDevice.getDialMessage("D01", dialValue);

    ble_con.sendMessage(message);
}

void processIncomingMessage(MessageData * messageData) {
    switch (messageData->control) {
    case status:
        processStatus(messageData->connectionType);
        break;
    case knob:
        if (messageData->idStr == "KB01") {
            dialValue = messageData->payloadStr.toFloat();
            String message = dashioDevice.getDialMessage("D01", dialValue);
            ble_con.sendMessage(message);
        }
        break;
    }
}

void setup() {
    Serial.begin(115200);
    
    ble_con.setCallback(&processIncomingMessage);
    ble_con.begin();
    dashioDevice.setup(ble_con.macAddress(), "Joe Name"); // unique deviceID, and device name
}

void loop() {
    ble_con.run();
}

If you would like to use a secure BLE connection, simply add "true" as an parameter to the BLE begin:

ble_con.begin(true);

TCP Basics

Lets have a look at a TCP connection. For this we also need WiFi so it is slightly more complicated than BLE.

#include "DashioESP.h"

char WIFI_SSID[] = "yourWiFiSSID";
char WIFI_PASSWORD[] = "yourWiFiPassword";
#define TCP_PORT 5650

DashioDevice dashioDevice("ESP32_Type");
DashioTCP    tcp_con(&dashioDevice, TCP_PORT, true);
DashioWiFi   wifi;

void setup() {
    Serial.begin(115200);
    delay(1000);
    
    dashioDevice.setup(wifi.macAddress(), "Joe Name"); // unique deviceID, and device name
    wifi.attachConnection(&tcp_con);
    wifi.begin(WIFI_SSID, WIFI_PASSWORD);
}

void loop() {
    wifi.run();
}

Similar to the BLE example above, we create a device and a TCP connection, with the device being an attribute to the connection. We also provide a port and the third attribute of the TCP connection enables the received and transmitted messages to be printed to the serial monitor to help with debugging.

In the setup() function we call the device setup with dashioDevice.setup(wifi.macAddress(), "Joe Name");. The two parameters describe the device to the DashIO app to allow it uniquely identify each device. The wifi object supplies the mac to the device, to be used as a unique device_ID.

We then attach the TCP connection to the wifi with wifi.attachConnection(&tcp_con);. This enables the wifi object to manage the TCP connection from here on in.

We start the WiFi wifi.begin(WIFI_SSID, WIFI_PASSWORD); with the WiFi SSID and password. This starts the wifi and TCP connection and sets up the the mDNS (also called Bonjour or Zeroconf) to make the device discoverable on the DashIO app.

wifi.run(); is used to regularly check that the WiFi is connected and manage the attached connection.

This device is discoverable by the DashIO app. You can also discover your IoT device using a third party Bonjour/Zeroconf discovery tool. The mDNS service will be "_DashIO._tcp." and individual IoT devices on this service are identified by their mac address (device_ID).

In the code above, make sure you replace yourWiFiSSID with your WiFi SSID and yourWiFiPassword with your WiFI password. Setup the Arduino IDE serial monitor with 115200 baud and run the code. You will see messages on the Arduino serial monitor, and after a few attampts, your IoT device should connect to your WiFi and start the mDNS service. Then run the DashIO app on your mobile device and you will see connection "WHO" messages on the Arduino serial monitor.

Message processing for a TCP connection is done exactly the same way as for the BLE connection, by adding the processIncomingMessage callback into the TCP connection during setup function. Our finished code, with Dial and Knob added is:

#include "DashioESP.h"

char WIFI_SSID[] = "yourWiFiSSID";
char WIFI_PASSWORD[] = "yourWiFiPassword";
#define TCP_PORT 5650

DashioDevice dashioDevice("ESP32_Type");
DashioTCP    tcp_con(&dashioDevice, TCP_PORT, true);
DashioWiFi   wifi;

int dialValue = 0;

void processStatus(ConnectionType connectionType) {
    String message((char *)0);
    message.reserve(1024);

    message = dashioDevice.getKnobMessage("KB01", dialValue);
    message += dashioDevice.getDialMessage("D01", dialValue);

    tcp_con.sendMessage(message);
}

void processIncomingMessage(MessageData *messageData) {
    switch (messageData->control) {
    case status:
        processStatus(messageData->connectionType);
        break;
    case knob:
        if (messageData->idStr == "KB01") {
            dialValue = messageData->payloadStr.toFloat();
            String message = dashioDevice.getDialMessage("D01", dialValue);
            tcp_con.sendMessage(message);
        }
        break;
    }
}

void setup() {
    Serial.begin(115200);
    delay(1000);
    
    tcp_con.setCallback(&processIncomingMessage);
    dashioDevice.setup(wifi.macAddress(), "Joe Name"); // unique deviceID, and device name
    wifi.attachConnection(&tcp_con);
    wifi.begin(WIFI_SSID, WIFI_PASSWORD);
}

void loop() {
    wifi.run();
}

Run the DashIO app once more. Tap the All Devices button, followed by the Find New Device button. Then select the TCP Discovery option to show a list of new IoT devices that are mDNS enabled. Your device will be shown (named "Joe Name"). Select your IoT device.

Troubleshooting: The mac that is provided by the WiFi peripheral in the ESP32 is not the same as the mac provided by the BLE peripheral. Therefore, when you select your new TCP connection it will create a new Device. You will need to edit the Device View that you created in the BLE example to be associated with your new device.

When you adjust the Knob on the DashIO app, a message with the knob value is sent your IoT device, which returns the knob value into the Dial control, which you will see on the DashIO app.

MQTT Basics

Lastly, lets look at a MQTT connection. We also need the WiFi for MQTT.

#include "DashioESP.h"

// WiFi
char WIFI_SSID[] = "yourWiFiSSID";
char WIFI_PASSWORD[] = "yourWiFiPassword";

// MQTT
char MQTT_USER[] = "yourMQTTuserName";
char MQTT_PASSWORD[] = "yourMQTTpassword";

DashioDevice dashioDevice("ESP32_Type");
DashioMQTT   mqtt_con(&dashioDevice, 2048, true, true);
DashioWiFi   wifi;

void setup() {
    Serial.begin(115200);

    dashioDevice.setup(wifi.macAddress(), "Joe Name"); // unique deviceID, and device name
    mqtt_con.setup(MQTT_USER, MQTT_PASSWORD);
    wifi.attachConnection(&mqtt_con);
    wifi.begin(WIFI_SSID, WIFI_PASSWORD);
}

void loop() {
    wifi.run();
}

Once again we create a device and this time a MQTT connection, with the device being an attribute to the connection. We also provide a buffer size (2048) and the third attribute of the MQTT connection enables a push notification to be sent to your mobile phone when the IoT device reboots (dash MQTT broker only). The final attribute enables the received and transmitted messages to be printed to the serial monitor for easy debugging.

In the setup() function we setup the device with two parameters. These parameters describe the device to the DashIO app to allow it uniquely identify each device. The wifi object supplies the mac address to the device, to be used as a unique device_ID.

For MQTT connections, the device must be setup before we begin the wifi.

The MQTT connection setup requires the MQTT broker username and password, supplied in the mqtt_con.setup(MQTT_USER, MQTT_PASSWORD); method.

We then attach the MQTT connection to the wifi with wifi.attachConnection(&mqtt_con);. This enables to wifi object to manage the MQTT connection from here on in.

Finally, we start the WiFi with wifi.begin(WIFI_SSID, WIFI_PASSWORD);, including parameters for the SSID and password.

wifi.run(); is used to regularly check that the WiFi is connected and to manage the attached connection.

This device is discoverable by the DashIO app.

In the code above, make sure you replace yourWiFiSSID with your WiFi SSID, yourWiFiPassword with your WiFI password, yourMQTTuserName with you dash account username and yourMQTTpassword with your dash account password. Setup the Arduino IDE serial monitor with 115200 baud and run the code. You will see messages on the Arduino serial monitor, and after a few attampts, your IoT device should connect to your WiFi and then connect to the dash MQTT server.

Message processing for a MQTT connection is done exactly the samy way as for the BLE connection, by adding the processIncomingMessage callback into the MQTT connection during the setup() function. Our finished code, with Dial and Knob added is:

#include "DashioESP.h"

// WiFi
char WIFI_SSID[] = "yourWiFiSSID";
char WIFI_PASSWORD[] = "yourWiFiPassword";

// MQTT
char MQTT_USER[] = "yourMQTTuserName";
char MQTT_PASSWORD[] = "yourMQTTpassword";

DashioDevice dashioDevice("ESP32_Type");
DashioMQTT   mqtt_con(&dashioDevice, 2048, true, true);
DashioWiFi   wifi;

int dialValue = 0;

void processStatus(ConnectionType connectionType) {
    String message((char *)0);
    message.reserve(1024);

    message = dashioDevice.getKnobMessage("KB01", dialValue);
    message += dashioDevice.getDialMessage("D01", dialValue);

    mqtt_con.sendMessage(message);
}

void processIncomingMessage(MessageData *messageData) {
    switch (messageData->control) {
    case status:
        processStatus(messageData->connectionType);
        break;
    case knob:
        if (messageData->idStr == "KB01") {
            dialValue = messageData->payloadStr.toFloat();
            String message = dashioDevice.getDialMessage("D01", dialValue);
            mqtt_con.sendMessage(message);
        }
        break;
    }
}

void setup() {
    Serial.begin(115200);

    dashioDevice.setup(wifi.macAddress(), "Joe Name"); // unique deviceID, and device name
    mqtt_con.setup(MQTT_USER, MQTT_PASSWORD);
    mqtt_con.setCallback(&processIncomingMessage);
    wifi.attachConnection(&mqtt_con);
    wifi.begin(WIFI_SSID, WIFI_PASSWORD);
}

void loop() {
    wifi.run();
}

Run the DashIO app once more. Tap the All Devices button, followed by the Find New Devices button. Then select the My Devices On DashIO option to show a list of new IoT devices that have announced themselves to the dash server. Your device will be shown (named "Joe Name"). Select your IoT device to add the MQTT connection to your existing IoT device with the TCP connection.

When you adjust the Knob on the DashIO app, a message with the knob value is sent your IoT device, which returns the knob value into the dial control, which you will see on the DashIO app.

For MQTT connections operating through the dash MQTT broker, a service is available for sending alarms (push notifications) to your mobile device. These are handy for sending messages or alarms to the user when they are not currently using the DashIO app. To send an alarm, simply call the sendMessage method with two attrbutes; the first being any message String and the second having alarm_topic specified.

mqtt_con.sendMessage("message", alarm_topic);

Combining BLE, TCP and MQTT

The ESP32 is capable of operating with any two of the three connection types at the same time. It just desn't have enough jibbers to run all three together. It's relativelty easy to combine the code for two connections in one ESP32 IoT device where each connection calls a common processIncomingMessage callback.

However, BLE connections consume large amounts of resources and significantly slow down the connections on ESP32. Therefore, it is recommended that the ESP32 is setup to switch between BLE and other connections. This may be done with a physical switch or other methods. It is best to use BLE for provisioning and then switch to a more secure protocol (TCP or MQTT).

Note that the wifi mac address is not identical to the BLE mac addresss. Therefore, if you are combining connections, it is best to stick with the wifi mac address for your device_ID.

This is just the beginning and there is a lot more we can do. Take a look at the examples in the library to see more details.

Layout Configuration

Layout configuration allows the IoT device to hold a copy of the complete layout of the device as it should appear on the DashIO app. It includes all infomration for the device, controls (size, colour, style etc.), device views and connections.

When the DashIO app discovers a new IoT device, it will download the Layout Configuration from the IoT device to display the device controls they way they have been designed by the developer. This is particularly useful developing commercial products and distributing your IoT devices to other users.

To include the Layout Configuration in your IoT device, simply follow these steps:

  • Design your layout in the DashIO app and include all controls and connections that you need in your layout.
  • Export the layout: Tap on the Device button, then tap the Export Layout button.
  • Select the provisioning setup that you want (see below for provisioning details) and tap the Export button. The Layout Configuration will be emailed to you.
  • Copy and paste the C64 configuration text from the email into your Arduino code, assigning it to a pointer to store the text in program memory. Your C64 configuration text will be different to that shown below.
  • Add the pointer to the C64 configuration text (configC64Str) as a second attribute to the DashioDevice object.
  • Add the Layout Config Revision integer (CONFIG_REV) as a third attribute to the DashioDevice object.
const char configC64Str[] PROGMEM =
"lVRNb+IwEP0rlQ97SlYJCZRyIyGpVv2gopTVatWDSWbBqmNHjlNgEf99x/kqLVTa3uyZefNm3ni8JxmIsiCj388W4XQJvDlr2OpA"
"bqG5ZjRvTstSaymulSzfW5rLStF83To4hFIISDSTgoz2RAFNn55+TMiIBFHQ94deZHuDyLX9wXBoB5dx347GzqU3cIPeYDwkFilA"
"vbIEGpAfj+Ow57i2Gwd92+9fRfYwDkM77IdXoee5V64fIGijmIav8Bws8iLk0pS9J4XecUDk/XR2N77FdIkUWklepbsJHLcqS6RT"
"wXdTMQMOtMB4rUowOm3JyHUci+RUgdAVaLKoQArSBeUlxl6iXzNd0dwgMTrXwFZrPaMoFRk533uDJuJBFqyWj8ynD4Z6LTd3TNwZ"
"oppz18Z0aL9XNxRKLhUiZ5AiMmWUx5JzuSkq0gZuzG3gLzBuIyFL9brL1/ctsj1h6aE1Y1iZc3iu09QC5goSVlQ1e1YnZzCefdBy"
"UqnydcUmyHResapDxrt2rhWAIJ8peaqbix3lkgkN6kQRUWZLUEdJwuh+Hs3OTuR/1SsF06gZIcdCJshcqmaFKKcqa1eSZXB9tF4p"
"mNXADfvDVma76vsj6DLHnIJmUJc9qewLBhsEuocW2BhwYIlWHKuPcTaP7C9K7DmmKxwHqlBmom0Lc9UGk+fDLOuBmUzBy0qkrXyB"
"mV5jlyoFNe2yvdna4J9r3Nsm+sTWJaTJC3n/GC6+XTRb1PHPFRVF9aCSHepae+YGg5/ameJa1+e4N3XcoUUYNn9vFB6Rp5yYsRX4"
"ESRatoMrOMPO2kkxVX+C7VTLlMkFK0rafrfwik//Vq6q6+Ef";

DashioDevice    dashioDevice(DEVICE_TYPE, configC64Str, CONFIG_REV);

Provisioning (Commissioning)

Provisioning is the method by which the DashIO app can send user credentials and other setup information to the IoT device and the IoT device will store this data in non-volatile memory.

Details of the provisioning functionality available in an IoT device are contained in the Layout Configuration and must be setup when exporting the Layout Configuration from the DashIO app.

A provisioning library is available within the DashIO library for the ESP32 (DashioProvisionESP.h and DashioProvisionESP.cpp) which stores the following provisioning data to EEPROM:

  • Device Name
  • WiFi SSID
  • WiFI Password
  • Dash MQTT broker User Name
  • Dash MQTT broker Password

The library exposes the following structure to contain the provisioning data:

struct DeviceData {
    char deviceName[32];
    char wifiSSID[32];
    char wifiPassword[63];
    char dashUserName[32];
    char dashPassword[32];
    char saved;
};

Use the provisioning library as follows:

Include the library

#include "DashioProvisionESP.h"

Create a provisioning object

DashioProvision dashioProvision(&dashioDevice);

Setup provisioning in the setup() function. For the TCP connection, we assign the provisioning information to the WiFi object or, for an MQTT connection, we assign the provisioning information to the WiFI object and MQTT connection object:

// setup
DeviceData defaultDeviceData = {DEVICE_NAME, WIFI_SSID, WIFI_PASSWORD, MQTT_USER, MQTT_PASSWORD};
dashioProvision.load(&defaultDeviceData, &onProvisionCallback);

dashioDevice.setup(wifi.macAddress());
    
mqtt_con.setup(dashioProvision.dashUserName, dashioProvision.dashPassword);
mqtt_con.setCallback(&processIncomingMessage);
    
wifi.attachConnection(&mqtt_con);
wifi.begin(dashioProvision.wifiSSID, dashioProvision.wifiPassword);

Here we update the provisioning object with the default provisioning data (using the DeviceData structure), then load the provisioning data. If the provisioning data has never been saved, then the the default provisionig data will be used. We also include a provision callback (discussed later).

Add provisioning process message in the processIncomingMessage callback from the example above becomes:

void processIncomingMessage(MessageData * messageData) {
    switch (messageData->control) {
    case status:
        processStatus(messageData->connectionType);
        break;
    case knob:
        if (messageData->idStr == "KB01") {
            dialValue = messageData->payloadStr.toFloat();
            String message = dashioDevice.getDialMessage("D01", dialValue);
            ble_con.sendMessage(message);
        }
        break;
    default:
        dashioProvision.processMessage(messageData);
        break;
    }
}

Your IoT device will let the DashIO app know what provisioning services are available when it down loads the layout configuration.

And finally, here is the onProvisionCallback:

void onProvisionCallback(ConnectionType connectionType, const String& message, bool commsChanged) {
    sendMessage(connectionType, message);

    if (commsChanged) {
        mqtt_con.setup(dashioProvision.dashUserName, dashioProvision.dashPassword);
        wifi.begin(dashioProvision.wifiSSID, dashioProvision.wifiPassword);
    }
}

The callback has two purposes. Firstly, we send a message back to the DashIO app to let it know that provisioning is complete. And secondly, if the WiFi or MQTT connection credentials have changed, we need to restart the WiFi or MQTT connection. In the above example we call mqtt_con.setup to update the MQTT connection with the new username and password and wifi.begin to update wifi with the new SSID and password. Alternatively, you could reboot the processor for a fresh start which would also update the MQTT connection and WiFi credentials.

To provision your device, run the DashIO app and tap the All Devices button and select your device. Tap the Provisioning button and follow the instructions.

Jump In and Build Your Own IoT Device

When you are ready to create your own IoT device, the following links will provide you with more details about what you need to know.

Devices & Connections

https://dashio.io/dashio-arduino-devices/

Messaging for All Controls

https://dashio.io/dashio-arduino-messaging/