Hi,
I want to share with the community a way to make a self provisioning device, so you don’t need to create at the cloud to get connected, just add all the fields needed in the code and it will check if there is a device and will try to create if it doesn’t exists, note that if the device exists with different credentials, will check that the device exists but never will connected.
Besides thinger library, need aditionally the HTTPClient library.
It was done by:
Arduino IDE 1.8.12
Thinger.io 2.15.0
ESP32 1.0.4
#include <HTTPClient.h>
#define _DEBUG_
#define THINGER_SERVER "yourServerAddress"
#include <ThingerESP32.h>
String USERNAME = "yourUsername";
String DEVICE_ID = "SelfProvisioningDevice";
String DEVICE_CREDENTIAL = "deviceCredentials";
String assetGroup = "TestAssetGroup";
String assetType = "TestAssetGroup";
String description = "TestDescription";
String name = "TestName";
String type = "Generic";
String token = "yourGeneratedToken";
#define SSID "TEST"
#define SSID_PASSWORD "11111111" //if you are in my neighborhood and get my wifi from this forum, be my guest
#define LED_BUILTIN 3 //just to avoid the error message on esp32
bool device = 0; //variable to check the device, after is verified will be 1
ThingerESP32 thing(USERNAME.c_str(), DEVICE_ID.c_str(), DEVICE_CREDENTIAL.c_str());
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
thing.add_wifi(SSID, SSID_PASSWORD);
thing["led"] << digitalPin(LED_BUILTIN);
thing["millis"] >> outputValue(millis());
}
void loop() {
thing.handle();
if (WiFi.status() == WL_CONNECTED && !device) {
if (checkDevice(THINGER_SERVER, USERNAME, token, DEVICE_ID)) {
Serial.println("Device already exists");
device = 1;
}
else {
Serial.println("Device doesn't exists, will try to create it");
int response = createDevice(THINGER_SERVER, USERNAME, token, assetGroup, assetType, DEVICE_CREDENTIAL, description, DEVICE_ID, name, type);
if (response == 200) {
Serial.println("Device created successfully");
device = 1;
}
else {
Serial.print("Device not created, error code : ");
Serial.println(response);
}
}
}
}
int createDevice(String serverName, String user, String token, String assetGroup, String assetType, String credentials, String description, String device, String name, String type) {
int httpCode;
if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
HTTPClient http;
String aux = "http://" + serverName + "/v1/users/" + user + "/devices";
http.begin(aux);
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", "Bearer " + token);
aux = "{\"asset_group\": \"" + assetGroup + "\", \"asset_type\": \"" + assetType + "\",\"credentials\": \"" + credentials + "\", \"description\": \"" + description + "\", \"device\": \"" + device + "\", \"name\": \"" + name + "\", \"type\": \"" + type + "\"}";
httpCode = http.POST(aux);
http.end();
}
return httpCode;
}
bool checkDevice(String serverName, String user, token, String device) {
String payload;
String aux;
if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
HTTPClient http; //Declare an object of class HTTPClient
aux = "http://" + serverName + "/v1/users/" + user + "/devices?name=" + device + "&authorization=" + token;
http.begin(aux); //Specify request destination
int httpCode = http.GET(); //Send the request
if (httpCode > 0) { //Check the returning code
payload = http.getString(); //Get the request response payload
// Serial.println(payload); //Print the response payload
}
http.end(); //Close connection
}
aux = "\"" + device + "\"";
if (payload.indexOf(aux) > 0) return true;
else return false;
}
To check if the device exists, it make the request with the device name, and it gets all the devices that has that string into the “device” and “name” fields, and will compare the DEVICE_ID against those fields.
It can be optimized to work with thinger library and get the events, but it is a pretty basic example, fell free to adapt to your needs and share your achievements.
I guess something similar could be done with the buckets and dashboards.
Hope this helps.