Skip to content

Devices

WebConfig

Let users set the Wi-Fi network and the Thinger.io credentials of an ESP32 or ESP8266 from a phone, without changing the firmware.

Feature5 min read

WebConfig lets the person who installs a device set its Wi-Fi network and its Thinger.io credentials from a phone or a computer. The device opens its own Wi-Fi network with a configuration page, so the same firmware works for every unit and every network.

When to use it ​

  • You ship the same firmware to many devices and each one goes to a different Wi-Fi network.
  • The person who installs the device cannot recompile the sketch.
  • You want to ask for extra settings at installation time, such as a location or an interval.

WebConfig is available on ESP32 and ESP8266 boards. It needs the WiFiManager library, version 2.0 or later: install it from the library manager of the Arduino IDE (search for WiFiManager by tzapu) or add tzapu/WiFiManager to lib_deps in PlatformIO.

Add WebConfig to a sketch ​

Use the WebConfig class of your board and create thing without credentials:

ESP32

main.cpp
cpp
#define THINGER_SERIAL_DEBUG

#include <ThingerESP32WebConfig.h>

ThingerESP32WebConfig thing;

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

  thing["millis"] >> outputValue(millis());
}

void loop() {
  thing.handle();
}

ESP8266

main.cpp
cpp
#define THINGER_SERIAL_DEBUG

#include <ThingerESP8266WebConfig.h>

ThingerESP8266WebConfig thing;

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

  thing["millis"] >> outputValue(millis());
}

void loop() {
  thing.handle();
}

Declare device resources as in any other sketch (see the Coding guide). For a private instance, add #define THINGER_SERVER "YOUR_SERVER" before the include: the server is fixed in the firmware and cannot be set from the configuration page.

Configure a device ​

Before you start, create the device in Devices > Add Device with the IOTMP Device (Thinger.io protocol) type, and keep its device ID and device credentials at hand. See Arduino.

The device startsSettings stored?YesJoins the storedWi-Fi networkNo1 · Opens its own networkThinger-Device, password thinger.io2 · A phone joins itThe page opens, or 192.168.4.13 · Enter the settingsWi-Fi network and password, user,device ID, credentials, extra fields4 · Stores themCloses its network, joins the Wi-FiConnected to Thinger.ioclean_credentials()deletes the stored settings:the next start takesthe "No" pathValues fixed in the firmware (user, device ID, credentials) are not asked in step 3.
How a WebConfig device gets its settings
  1. Join the device network

    Power the device. The first time, it opens a Wi-Fi network called Thinger-Device. Join it from your phone or computer with the password thinger.io.

  2. Open the configuration page

    The configuration page usually opens on its own. If it does not, open http://192.168.4.1 in the browser.

  3. Enter the settings

    Choose the Wi-Fi network the device will use and type its password. Fill in User Id (YOUR_USER), Device Id (YOUR_DEVICE) and Device Credential (the device credentials, YOUR_TOKEN). Save.

  4. Check the connection

    The device closes its network, joins yours and connects to Thinger.io. In Devices, the device shows as connected.

The device stores the settings, so it connects on its own every time it starts. On the ESP32, they are kept when you upload a firmware with another partition scheme.

When the Wi-Fi network is not available ​

If the device cannot join its stored Wi-Fi network, for example because it was moved to another place, it opens the Thinger-Device network and the configuration page again after 3 failed attempts. The page shows the current values of your extra fields. If nobody saves new settings in 180 seconds, the page closes, the stored settings stay as they were, and the device tries its network again.

Change both values before the include. THINGER_WEBCONFIG_ATTEMPTS set to 0 turns this off, so the device keeps trying its stored network:

cpp
#define THINGER_WEBCONFIG_ATTEMPTS 3          // failed attempts before the page opens
#define THINGER_WEBCONFIG_PORTAL_TIMEOUT 180  // seconds the page stays open

#include <ThingerESP32WebConfig.h>

Reset the configuration ​

thing.clean_credentials() deletes the stored Thinger.io credentials. On the next start, the device opens the Thinger-Device network and the configuration page again. A common pattern is to reset when a button is held while the board starts:

main.cpp
cpp
#define THINGER_SERIAL_DEBUG

#include <ThingerESP32WebConfig.h>

#define RESET_PIN 0  // the BOOT button on most ESP32 boards

ThingerESP32WebConfig thing;

void setup() {
  Serial.begin(115200);
  pinMode(RESET_PIN, INPUT_PULLUP);

  // hold the button while the board starts to configure it again
  if (digitalRead(RESET_PIN) == LOW) {
    thing.clean_credentials();
  }

  thing["millis"] >> outputValue(millis());
}

void loop() {
  thing.handle();
}

Ask for extra settings ​

Add up to five fields of your own to the configuration page with thing.add_setup_parameter(), and read their values in the configuration callback. The callback runs when the device is configured and at every start, with the stored values:

main.cpp
cpp
#include <ThingerESP32WebConfig.h>

ThingerESP32WebConfig thing;

char location[32] = "";

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

  // field id, label, default value, maximum length
  thing.add_setup_parameter("location", "Location", "", 32);

  thing.set_on_config_callback([](pson& config) {
    strlcpy(location, config["location"], sizeof(location));
  });

  thing["location"] >> [](pson& out) {
    out = (const char*) location;
  };
}

void loop() {
  thing.handle();
}

add_setup_parameter() returns false when the page already has five extra fields. An optional fifth argument adds HTML attributes to the field, for example "type=\"number\"".

Fix the credentials in the firmware ​

Values you set in the firmware are not asked on the configuration page. Pass them to the constructor, or set them in setup() before the first thing.handle():

main.cpp
cpp
#include <ThingerESP32WebConfig.h>

// the page asks only for the Wi-Fi network and the device credentials
ThingerESP32WebConfig thing("YOUR_USER", "YOUR_DEVICE");

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

  // close the configuration page after 5 minutes without activity
  thing.set_on_captive_portal_run([](WiFiManager& portal) {
    portal.setConfigPortalTimeout(300);
  });

  // report whether the Wi-Fi network connected when the page closes
  thing.set_on_wifi_config([](bool connected) {
    Serial.println(connected ? "Wi-Fi connected" : "Wi-Fi not connected");
  });

  thing["millis"] >> outputValue(millis());
}

void loop() {
  thing.handle();
}

set_on_captive_portal_run() receives the WiFiManager object just before the page opens, so you can use any option of the WiFiManager library, such as a timeout or a title.

Functions ​

FunctionWhat it does
ThingerESP32WebConfig thing(user, device, credential)Creates thing. The three arguments are optional; the ones you pass are not asked on the page. ThingerESP8266WebConfig takes the same arguments.
set_user(user), set_device(device), set_credential(credential)Set the username, the device ID or the device credentials from the firmware. The page does not ask for them.
add_setup_parameter(id, label, default, length, html)Adds an extra field to the page, up to five. html is optional.
set_on_config_callback(function)Runs function with the settings, stored or just entered, including the extra fields.
set_on_wifi_config(function)Runs function with true or false after the page closes, depending on whether the Wi-Fi network connected.
set_on_captive_portal_run(function)Runs function with the WiFiManager object before the page opens.
clean_credentials()Deletes the stored Thinger.io settings and extra fields. The next start opens the page again.

To change the name and password of the device network, define them before the include:

cpp
#define THINGER_DEVICE_SSID "Sensor-Setup"
#define THINGER_DEVICE_SSID_PSWD "change-me-123"

#include <ThingerESP32WebConfig.h>

Set the Wi-Fi network with ESP-Touch instead ​

On an ESP8266, ThingerSmartConfig takes only the Wi-Fi network from a phone, with Espressif's ESP-Touch app (SmartConfig), and keeps the Thinger.io credentials in the firmware. The phone sends the password of the network it is on; there is no configuration page. See ESP8266 set up with ESP-Touch.

WebConfigESP-Touch
BoardsESP32, ESP8266ESP8266
Wi-Fi networkChosen on the configuration pageSent by the ESP-Touch app
Thinger.io credentialsOn the page, or in the firmwareIn the firmware
Extra fieldsUp to fiveNone

Limits ​

  • ESP32 and ESP8266 only.
  • The username, device ID and device credentials are limited to 39 characters each.
  • At most five extra fields.
  • The server is set in the firmware, not on the configuration page.
  • The configuration page opens when the device has no stored settings, and when it cannot join its stored Wi-Fi network: see When the Wi-Fi network is not available.
  • While the configuration page is open, the device does not run the rest of the sketch: loop() waits. Set a timeout with set_on_captive_portal_run() to give up after a while. To show that the page is open, for example by blinking an LED, start a Ticker in set_on_captive_portal_run().
  • If the configuration page closes without a Wi-Fi network, thing.get_error() returns ThingerClient::NETWORK_NOT_CONFIGURED. See Why the network connection failed.