> For the complete documentation index, see [llms.txt](https://wiki.codeandcompile.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.codeandcompile.com/product-reviews/smart-platforms/thingsboard/thingsboard-edge-setup.md).

# ThingsBoard (Edge Setup)

Unlike fragmented solutions that require multiple tools glued together, **ThingsBoard provides the full system operators actually use, from device connectivity to role-based dashboards, out of the box**.

**By the end of this guide, you will have:**

* ThingsBoard running on a **reComputer R2100**
* A device connected via **MQTT**
* Simulated telemetry generated from **Node-RED.** In our guide, we will be using **Node-RED** to emulate device data for this setup. Learn more about Node-RED [here](https://nodered.org/)
* A **live industrial dashboard** (motor, energy, vibration, etc.)
* Optional **RPC control** from the dashboard to the device

{% embed url="<https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FXX5i4KqlYXHfbyxxxpFY%2FThingsBoard.mp4?alt=media&token=1c3cdfb8-77e4-4c75-b7e5-b87374b7266e>" %}

{% hint style="success" %}

#### Want to get started with ThingsBoard? Sign up [here](https://thingsboard.io/?fpr=n5sson\&fp_sid=rajvir).

{% endhint %}

### Hardware & Software Used

#### Hardware

* **reComputer R2100** (Edge device) from Seeed Studio
* Development PC / Laptop

#### Software

* ThingsBoard Community Edition (CE)
* Node-RED (for sending simulated telemetry data)
* MQTT Broker (built into ThingsBoard)

***

### Step 1 – Install ThingsBoard on the reComputer R2100

{% hint style="info" %}
You can use any Linux-based edge device with at least 4GB of RAM. Get more information [here](https://thingsboard.io/docs/user-guide/install/rpi/?utm_source=inf\&utm_medium=rjvr\&utm_campaign=edgesetup)
{% endhint %}

{% stepper %}
{% step %}

### Log in to reComputer via Putty

<figure><img src="/files/ErDsoMdsI3azEDWsdNfG" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Install ThingsBoard

You can follow the instructions given on thingsBoard documentation here: <https://thingsboard.io/docs/user-guide/install/rpi/?utm_source=inf&utm_medium=rjvr&utm_campaign=edgesetup>

Once you have finished installing ThingsBoard, come back here.
{% endstep %}
{% endstepper %}

### Step 2- Start ThingsBoard and open the WebUI

{% stepper %}
{% step %}

### Start ThingsBoard on your edge device

```shellscript
sudo service thingsboard start
```

{% endstep %}

{% step %}

### Open WebUI

Open this on your browser: [http://192.168.0.195:8080](http://192.168.0.195:8080/login) where 192.168.0.195 is the IP address of the edge device.
{% endstep %}

{% step %}

### Log in as Admin

Log in using the following credentials:

* **Username**: <sysadmin@thingsboard.org>&#x20;
* **Password**: sysadmin

<figure><img src="/files/pN6OSfY7mLkEqR8scI43" alt="" width="278"><figcaption></figcaption></figure>

<figure><img src="/files/4jkh21t3xWp1QEsjgv18" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Create a new Tenant

**Multitenancy in ThingsBoard** enables you to manage multiple organizations within a single system. Each tenant works like an independent environment with its own users, devices, and dashboards.

<figure><img src="/files/ghoTaxqvzvRzOin0JnFz" alt=""><figcaption></figcaption></figure>

The steps to create the tenant are given here: <https://thingsboard.io/docs/user-guide/ui/tenants/?utm_source=inf&utm_medium=rjvr&utm_campaign=edgesetup>
{% endstep %}

{% step %}

### Add the user in the Tenant as 'Admin'

The **System administrator** can also create multiple users with the Tenant Administrator **role** in each tenant.

<figure><img src="/files/uUufo1uXQTyfQhVxntND" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Log in as 'Tenant user.'

<figure><img src="/files/iSIaVvke9pcmbSQW4F0C" alt=""><figcaption></figcaption></figure>
{% endstep %}
{% endstepper %}

### Step 3- Add a new device and send a test value

Let's add a device that sends telemetry data to ThingsBoard.&#x20;

{% stepper %}
{% step %}

### Add a device

The detailed steps of instructions on adding a device are given here: <https://thingsboard.io/docs/getting-started-guides/helloworld/?utm_source=inf&utm_medium=rjvr&utm_campaign=edgesetup>

<figure><img src="/files/X26XZGaw3KsD7FhlqXhL" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Select the communication protocol

There are multiple ways to connect to the ThingsBoard device. In our example, we will use MQTT.&#x20;

<figure><img src="/files/cF7ONJKk73UDbBjHlXoc" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Get ThingsBoard MQTT connection details

The ThingsBoard has an internal MQTT Broker running on port 1883. You will find more details for the connection in the wizard.

```shellscript
mosquitto_pub -d -q 1 -h 192.168.0.195 -p 1883 -t v1/devices/me/telemetry -u "IPOJzEMJHs0wWhzz2K3R" -m "{temperature:25}"
```

In the above lines of code, we can extract the following information needed to send telemetry data to ThingsBoard via MQTT:

* Broker URL: 192.168.0.195 (IP Address of the edge device)
* MQTT Port: 1883
* MQTT Topic: v1/devices/me/telemetry
* Username: IPOJzEMJHs0wWhzz2K3R
* Password: — leave blank --
  {% endstep %}

{% step %}

### Send a test value to ThingsBoard via MQTT

Take the inject node as 'Timestamp' with an interval of 1 second.

<figure><img src="/files/XWb8YXLQofKXQLkYELcQ" alt=""><figcaption></figcaption></figure>

Add a function node to simulate temperature value

```javascript
let number = Number((Math.random() * 100).toFixed(2));
msg.payload = {
    temperature: number
}
return msg;
```

Take the MQTT out node and set up the ThingsBoard's MQTT broker parameters as shown in the image:

<figure><img src="/files/opTx7FqIz0TcQzAi5fiJ" alt=""><figcaption></figcaption></figure>

Enter the username:

<figure><img src="/files/VcHl15w73fFwPKPIKz1b" alt=""><figcaption></figcaption></figure>

Define the MQTT topic:

<figure><img src="/files/EwFJbKUXk22gLC3skhZX" alt=""><figcaption></figcaption></figure>

Once the connection is established, send a test value as 'temperature':

<figure><img src="/files/f9wjhG4ag0H1U8qkbxFW" alt=""><figcaption></figcaption></figure>

Open the telemetry log to view the temperature value. Navigate to **Entities > Devices > IoT1 > Latest Telemetry**

<figure><img src="/files/KSqwUmOekNrePPMO9FwA" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}
{% endstepper %}

### Step 4- Update telemetry data in the Node-RED

To visualize multiple parameters on the ThingsBoard dashboard, we need additional telemetry data. Use the following code in the function node of Node-RED.

```javascript
// Rich telemetry generator for ThingBoard dashboards
// Put this in a Function node and trigger it every 1s-5s with an Inject node.

let s = context.get('s') || {
    t: 0,
    baseTemp: 24,
    baseHum: 48,
    motorOn: true,
    speedRpm: 900,
    energyKWh: 0,
    runtimeSec: 0,
    cycleCount: 0,
    lastCycleT: 0,
    fault: false,
    faultCode: 0
};

s.t += 1;

// Helpers
function clamp(v, min, max) { return Math.max(min, Math.min(max, v)); }
function rand(min, max) { return min + Math.random() * (max - min); }
function chance(p) { return Math.random() < p; }

// ---- Motor state machine (feels realistic)
if (chance(0.02)) s.motorOn = !s.motorOn;              // occasional start/stop
if (chance(0.01) && !s.fault) {                        // rare fault event
    s.fault = true;
    s.faultCode = [101, 202, 303, 404][Math.floor(Math.random() * 4)];
}
if (s.fault && chance(0.15)) {                         // fault clears after some time
    s.fault = false;
    s.faultCode = 0;
}

// Speed ramping
let targetRpm = s.motorOn && !s.fault ? rand(800, 1450) : 0;
s.speedRpm = s.speedRpm + (targetRpm - s.speedRpm) * 0.15;
s.speedRpm = clamp(s.speedRpm, 0, 1600);

// ---- Environmental signals (slow drift + small noise)
let dayWave = Math.sin(s.t / 120) * 1.5;               // slow wave
s.baseTemp += rand(-0.02, 0.02);
s.baseHum += rand(-0.05, 0.05);

let temperature = clamp(s.baseTemp + dayWave + rand(-0.2, 0.2), 18, 35);
let humidity    = clamp(s.baseHum - dayWave + rand(-0.5, 0.5), 30, 70);

// ---- Vibration rises with RPM + faults
let vibBase = (s.speedRpm / 1600) * 4.0;               // 0..4 mm/s
let vibrationRms = vibBase + rand(0.1, 0.5);
if (s.fault) vibrationRms += rand(2, 5);               // big increase when faulty
vibrationRms = clamp(vibrationRms, 0, 12);

// ---- Current / Power / Energy
let currentA = s.motorOn && !s.fault ? clamp((s.speedRpm / 1600) * 7 + rand(0, 1), 0, 10) : rand(0, 0.3);
if (s.fault) currentA += rand(2, 4);

let voltageV = 230 + rand(-3, 3);
let powerW = clamp(voltageV * currentA * 0.85, 0, 4000);   // rough PF/efficiency

// energy integration: Wh per second -> kWh
s.energyKWh += (powerW / 1000) / 3600;

// ---- Production-ish signals
if (s.motorOn && !s.fault) s.runtimeSec += 1;

// create a "cycle" every ~15-35 seconds when running
if (s.motorOn && !s.fault && (s.t - s.lastCycleT) > rand(15, 35)) {
    s.cycleCount += 1;
    s.lastCycleT = s.t;
}
let cycleTimeSec = s.motorOn && !s.fault ? clamp((s.t - s.lastCycleT), 0, 60) : null;

// ---- Quality / OEE-ish
let rejectRate = s.fault ? rand(3, 12) : rand(0.3, 2.0);   // %
let goodParts = Math.round(s.cycleCount * (1 - rejectRate / 100));
let availability = clamp((s.runtimeSec / s.t) * 100, 0, 100);

// ---- Alarm levels (nice for color-changing widgets)
let alarmLevel = 0;
if (temperature > 30 || vibrationRms > 7) alarmLevel = 1;
if (s.fault || vibrationRms > 9) alarmLevel = 2;

// Build payload
msg.payload = {
    // Environment
    temperature: Number(temperature.toFixed(2)),          // °C
    humidity: Number(humidity.toFixed(2)),                // %

    // Machine
    motorOn: s.motorOn && !s.fault,                       // boolean
    speedRpm: Math.round(s.speedRpm),
    vibrationRms: Number(vibrationRms.toFixed(2)),        // mm/s
    currentA: Number(currentA.toFixed(2)),                // A
    voltageV: Number(voltageV.toFixed(1)),                // V
    powerW: Math.round(powerW),                           // W
    energyKWh: Number(s.energyKWh.toFixed(3)),            // kWh

    // Production / KPIs
    cycleCount: s.cycleCount,
    cycleTimeSec: cycleTimeSec === null ? null : Number(cycleTimeSec.toFixed(1)),
    goodParts: goodParts,
    rejectRate: Number(rejectRate.toFixed(2)),            // %
    availability: Number(availability.toFixed(1)),        // %

    // Faults / Alarms
    fault: s.fault,
    faultCode: s.faultCode,
    alarmLevel: alarmLevel                               // 0 normal, 1 warn, 2 critical
};

context.set('s', s);
return msg;

```

This updated code will give you multiple simulated values as shown below:

<figure><img src="/files/RLlc6owy0wWVyqos3bf6" alt="" width="563"><figcaption></figcaption></figure>

### Step 5- Create Dashboard

We will now create a dashboard to visualize telemetry data. The step-by-step information on creating the dashboard is given here: <https://thingsboard.io/docs/user-guide/dashboards/?utm_source=inf&utm_medium=rjvr&utm_campaign=edgesetup>

<figure><img src="/files/kANUevednq5dGNY8SDcS" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/jAqcghqxAfiBEWazc5rI" alt="" width="563"><figcaption></figcaption></figure>

{% stepper %}
{% step %}

### Add new widget

Open your dashboard and click on 'Add new widget'

<figure><img src="/files/swTZNuFA9MTEai47jL3I" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Select 'Cards' in the widget bundle

<figure><img src="/files/QwlxvaD8I03ycs0k4DRW" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Select Label & value card

<figure><img src="/files/28khgdUZmWxaCvPHTuCS" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Configure the parameters

* Locate your IoT device. In our case, it is 'IoT1.'
* Update the label to 'Temperature.'
* Update the icon and color as required.
* Click on 'Add'

<figure><img src="/files/LJAQBs03RdZtPRfhuKBK" alt="" width="563"><figcaption></figcaption></figure>

{% hint style="info" %}
💡 **Best practice (recommended for shared dashboards)**

In production or reusable dashboards, avoid selecting a fixed **Device**.\
Instead, use an **Entity Alias** resolved from the dashboard state.

This allows the same dashboard to work across different devices and instances.
{% endhint %}
{% endstep %}

{% step %}

### Visualize the Dashboard

You will instantly see the Temperature value on the dashboard

<figure><img src="/files/pZ2CzPdymE7d74sEX8un" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}
{% endstepper %}

## Step 6- Import dashboard

ThingsBoard makes it really easy to share a dashboard. Follow these steps to duplicate my ThingsBoard dashboard.

{% stepper %}
{% step %}

### Click on Add Dashboard > Import

<figure><img src="/files/nIhJ7JRCegNJYhOMS7e1" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Download my dashboard

Click on the file below to keep a copy of the dashboard

{% file src="/files/nqMuNfU6DtPOIa9kMGS4" %}
{% endstep %}

{% step %}

### 🔁 About Entity Alias & Reusability (Important)

This dashboard is exported using **an entity alias** instead of a fixed device.

What this means:

* The dashboard is **not hard-coded** to a specific device
* It can be reused across **different ThingsBoard instances**
* All widgets dynamically resolve the device from the **dashboard state**

During import, ThingsBoard will automatically use the **default state entity** defined in the dashboard.\
You can change this at any time to point the dashboard to **your own device**.

***

### Importing Dashboard

Drag and drop the file into the wizard, then click 'Import.' You will find the imported dashboard in the list.&#x20;

***

#### After importing the dashboard

If your device name is different from `IoT1`, follow these steps:

1. Open the imported dashboard
2. Click **Edit → Aliases**
3. Select the alias (for example: `IoT1`)
4. Choose your own **Device**
5. Save the dashboard

All widgets will update automatically. Click it to view all sample telemetry data on your screen.

<figure><img src="/files/daerBfYHFK2P5JerfGzt" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/jsmW6RNeiIa2H3OA2aDj" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/bDIajE3MJ7H8GBDKhsWc" alt="" width="563"><figcaption></figcaption></figure>

Enjoy exploring the dashboard elements.&#x20;

***

#### Why Entity Alias is recommended

Using Entity Alias instead of selecting a device directly:

* Makes dashboards **portable and shareable**
* Prevents broken widgets after import
* Allows the same dashboard to work with **multiple devices**
* Follows **ThingsBoard's best practices** for production dashboards
  {% endstep %}
  {% endstepper %}

## ♥️ Work With Me

I regularly test **industrial automation and IIoT devices**. If you’d like me to **review your product** or showcase it in my courses and YouTube channel:

📧 Email: <rajvir@codeandcompile.com> or drop me a message on [LinkedIn](https://www.linkedin.com/in/singhrajvir/)
