> 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)

This guide shows how to build a complete end-to-end IIoT system using ThingsBoard running on an edge device and simulated telemetry data.

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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FNKmLXVlwT4IOksnxcTWy%2Fimage.png?alt=media&amp;token=74db0ae9-df77-413d-89a5-363d03fa650a" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2Fz11Um6TG2W2PuAZUqhAq%2Fimage.png?alt=media&amp;token=e7c2175a-d369-43a6-998d-d781ef8892cb" alt="" width="278"><figcaption></figcaption></figure>

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FfUlgDTLmRTDQ51Hikfbf%2Fimage.png?alt=media&amp;token=ba3c2236-857a-4b85-8f69-0608bf5c6eb0" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FzFzDwIYuwrMkYXrtXqub%2Fimage.png?alt=media&amp;token=fad7c58c-b932-41a9-b4e5-2047b7594b18" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FDg44wUVePm894NOAkH2S%2Fimage.png?alt=media&amp;token=010f6429-4a21-47a7-bb7e-b9758b39b747" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Log in as 'Tenant user.'

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FBdjnRuBifLAwLNRLvHnO%2Fimage.png?alt=media&amp;token=7b371b8d-8b92-4e52-972d-023b2e2b88cd" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FAmKLNGWGiZjoIIKcogN1%2Fimage.png?alt=media&amp;token=af4df41a-669d-43f1-a920-7ddc25a6cd94" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FjwjkZtmftNqtNBbi8EXN%2Fimage.png?alt=media&amp;token=4865fe7f-2858-43ad-9a8f-617d721fa9c9" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2F8M4AMxJ1amurqLjpAkMO%2Fimage.png?alt=media&amp;token=b26aea0d-35c4-4ac1-82a8-59906381d651" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FyHL6GHrUWV695rNLYL5f%2Fimage.png?alt=media&amp;token=3c55d812-2529-4c7f-b125-5b8883f6649b" alt=""><figcaption></figcaption></figure>

Enter the username:

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FPHOpZoN4DBxjHnpNMmqB%2Fimage.png?alt=media&amp;token=8d60c5bc-1e74-4f58-a6bb-5ac96bf506c7" alt=""><figcaption></figcaption></figure>

Define the MQTT topic:

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2F7szWscihLn0Xg01hZThc%2Fimage.png?alt=media&amp;token=b891fec1-626b-4e88-8955-574b573b55db" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FOfYuJVr4sR6RURObcMqM%2Fimage.png?alt=media&amp;token=1ef3830d-280f-459f-b39d-8ae38d827700" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2Fg1arcnT54PThnd4nrP5F%2Fimage.png?alt=media&amp;token=af256a53-d027-4c1e-85f5-9736bb268337" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FVD4RstbDLnJeu1unu1Q2%2Fimage.png?alt=media&amp;token=ecf7f666-6357-4d6a-9d0c-cc6edfc8b369" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FF5iDG2L8dUE3RLkLv1oT%2Fimage.png?alt=media&amp;token=1d3481c1-6f67-45f3-83bb-1018a5dc036a" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FHU9dDk1B1jQFQKvreyku%2Fimage.png?alt=media&amp;token=caaf1a11-f8eb-44de-bd7a-bf0a43a14ad0" alt="" width="563"><figcaption></figcaption></figure>

{% stepper %}
{% step %}

### Add new widget

Open your dashboard and click on 'Add new widget'

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FM9fuzhUOs4Shz196d537%2Fimage.png?alt=media&amp;token=7974b42a-732e-4228-aa1a-a23514f99078" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Select 'Cards' in the widget bundle

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FuGu8XbvLzcqWvfJR4A48%2Fimage.png?alt=media&amp;token=ea604c19-4467-4892-83ab-5446f32a2b33" alt="" width="563"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Select Label & value card

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FHxPPCGyI1FvJIHKq2T6W%2Fimage.png?alt=media&amp;token=70de3c22-c529-4fd1-872a-9b45e286f2e5" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2Fw0aEpWGV8HbUjfqqwyDj%2Fimage.png?alt=media&amp;token=bffeb8e9-1363-4c71-9aa8-aa06d8b8a12c" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FcRdSfmKDm6t9oAEqqhvL%2Fimage.png?alt=media&amp;token=4cac7a53-73b7-4332-9bc1-e0284ce1bc23" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FN6eSDp8gVLhQBXDvqgRc%2Fimage.png?alt=media&amp;token=40b9e201-64d3-4023-91b4-938abeb99d95" 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="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FHj5Hpi56aoBpg8nfQuoo%2Fimage.png?alt=media&amp;token=3af78e2c-1eae-4053-af20-5009eeb34f4b" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2FP9Gn26Z3b1lJohSWxS5E%2Fimage.png?alt=media&amp;token=496a6b7f-30e7-4044-a70c-7522bb999886" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="https://1831238825-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLd2M9UNfMTnw9DjDdZJz%2Fuploads%2F202HjlwablvCI6XyJfcQ%2Fimage.png?alt=media&amp;token=553bb704-6f49-419f-a5e0-cc84587cbf8c" 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/)
