Skip to main content

Sending and receiving

Every widget sits on a virtual pin, V0 to V124. Send to a pin to update the widget there; register a callback on a pin to react when a user uses the control there. Ask the organization which widget is on which pin.

The functions are the same for WiFi (ThingsLinker) and 4G (ThingsLinkerGSM).

Send values (device → dashboard)​

FunctionWidgetValue
iot.gauge("V1", value)Gaugenumber
iot.chart("V1", value)Chartnumber, recorded for history
iot.display("V1", value)Value Displaynumber, text or on/off
iot.label("V1", value)Labeltext, number or on/off
iot.terminal("V1", text)Terminala line of text
iot.led("V1", on)LEDtrue / false
iot.button("V1", on)Buttontrue / false, for example after a physical button press
iot.slider("V1", value)Slidernumber, to move the slider
iot.map("V1", lat, lng)Maplatitude and longitude
iot.status("V1", value)Statusnumber or text, shown as a named state
iot.progress("V1", value)Progress Barnumber
iot.selector("V1", value)Selectorthe option that is active now
iot.numberInput("V1", value)Number Inputthe current number
iot.publish("Type", "V1", value)any widget, by its type name in the portalnumber, text or on/off
iot.gauge("V3", 52.6);
iot.label("V4", "Door open");
iot.led("V5", relayOn);
iot.map("V12", 23.0225, 72.5714);

Send on a timer with millis(), not on every loop. Every few seconds is plenty for most readings; on 4G, every message uses mobile data.

Receive commands (dashboard → device)​

Register callbacks in setup(), before iot.begin():

FunctionWidgetCallback receives
iot.onSwitch("V1", cb)Switchbool on
iot.onButton("V1", cb)Buttonbool pressed
iot.onLED("V1", cb)LEDbool on
iot.onSlider("V1", cb)Sliderfloat value
iot.onValue("V1", cb)Value Displayfloat value
iot.onTerminal("V1", cb)Terminalconst char* text
iot.onSelector("V1", cb)Selector with number valuesfloat option
iot.onSelectorText("V1", cb)Selector with text valuesconst char* option
iot.onNumberInput("V1", cb)Number Inputfloat value
iot.onTextInput("V1", cb)Text Inputconst char* text
iot.onKeypad("V1", cb)Keypad with number valuesfloat key
iot.onKeypadText("V1", cb)Keypad with text valuesconst char* key
iot.onRGB("V1", cb)RGBuint8_t r, g, b, bool on, uint16_t count, const char* pattern
iot.onTimer("V1", cb)Timerfloat value
iot.onJoystick("V1", cb)Joystickfloat x, float y
iot.onWidget("Type", "V1", cb)any widget type that sends a numberfloat value
iot.onWidgetText("Type", "V1", cb)any widget type that sends textconst char* text
void onBrightness(float value) {
analogWrite(LED_PIN, map((int)value, 0, 100, 0, 255));
}

void onMode(const char* option) {
Serial.printf("Mode: %s\n", option);
}

void setup() {
iot.onSlider("V7", onBrightness);
iot.onSelectorText("V9", onMode);
iot.begin();
}

Notes:

  • A const char* passed to a callback is only valid during the callback. Copy it if you need it later.
  • Up to 20 callbacks of each kind (number, on/off, text) can be registered.
  • Keep callbacks short: set a variable or switch an output, and do longer work in loop().
  • RGB: pattern is the name picked in the widget's Effect list, such as Default, Blinking or Rainbow Cycle; your firmware draws the effect. The 07_All_Widgets_Test and 08_ESP32S3_Full_Dashboard examples include RGBEffects.h, which draws every effect in the list on a NeoPixel strip and gamma-corrects the colour so the LEDs match the colour on screen. Copy it into your sketch folder to use it.

Data types​

Each widget has a Data Type, set by the organization. The library sends the JSON type that matches the C++ value you pass: 42 is an Integer, 23.5 a Float, true a Boolean and "Running" a String. Nothing is guessed from the content, so "123" stays text.

iot.display("V3", 42);           // {"v":42}
iot.display("V3", 23.5f); // {"v":23.5}
iot.display("V3", true); // {"v":1}
iot.display("V3", "Running"); // {"v":"Running"}

Send the type the widget expects. A chart only plots numbers, and alerts only compare numbers. Text values can be up to about 300 characters; longer values are not sent and an error is logged. The full table is in Widget types.

Settings come back after a reconnect​

The app and the User Portal ask ThingsLinker to keep the last command sent to most controls. When your device connects, it receives those commands again and can return to the user's chosen settings:

WidgetOn connect
Switch, Button, LED, Slider, Selector, Number Input, RGB, Timer, JoystickThe last command arrives again.
Keypad, Text InputNothing arrives: each press or message is sent once. Use these for one-off actions such as "restart".
TerminalThe last line typed arrives again, so do not trigger one-off actions directly from onTerminal().

So a device can restore its outputs from the dashboard after a restart. To keep settings even while it is offline, save them in flash as well; see Saving settings.

Your own messages are ignored​

A device also listens on the pins it sends to. The library recognises its own messages coming back from the broker and ignores them, so a callback only runs for commands from the dashboard. You can, for example, call iot.led("V5", state) and handle iot.onLED("V5", cb) in the same sketch.