inhabitat:kaunas:day03
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| inhabitat:kaunas:day03 [2026/05/27 12:38] – created jan.sonntag | inhabitat:kaunas:day03 [2026/05/29 10:08] (current) – jan.sonntag | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Day 3 - IoT Systems - Open Source Cloud Solutions ====== | ====== Day 3 - IoT Systems - Open Source Cloud Solutions ====== | ||
| + | This workshop walks you through using the **NIG stack** — Node-RED, InfluxDB and Grafana — to collect, store and visualise data. By the end you will have published numbers to your **own** MQTT broker, subscribed to them, cleaned them up, stored them in a time series database, and plotted them on a dashboard. | ||
| + | |||
| + | You don't need any hardware. We'll generate test values inside Node-RED itself. Once the pattern is clear, swap the test source for a real sensor and the rest of the flow stays the same. | ||
| + | |||
| + | <WRAP center round info 80%> | ||
| + | Your instructor has already started an instance for you and will hand you the URLs and login. This page is only about //using// the three tools together. | ||
| + | </ | ||
| + | |||
| + | ===== The three tools, briefly ===== | ||
| + | |||
| + | * **[[https:// | ||
| + | * **[[https:// | ||
| + | * **[[https:// | ||
| + | |||
| + | This combination — sometimes called the **NIG stack** — is one of the standard ways to do IoT data processing. | ||
| + | |||
| + | ===== What you'll build ===== | ||
| + | |||
| + | A complete data pipeline: | ||
| + | |||
| + | < | ||
| + | [inject node]──►[mqtt out]──┐ | ||
| + | │ test/value | ||
| + | [aedes broker]◄─────────────┤ | ||
| + | │ test/value | ||
| + | [mqtt in]──►[clean payload]─┴──►[influxdb out]──►[ Grafana panel ] | ||
| + | </ | ||
| + | |||
| + | * **inject** — a button you click to fire a test number into the flow. | ||
| + | * **mqtt out** — publishes that number to a topic on your broker. | ||
| + | * **aedes broker** — your own MQTT broker, running inside your Node-RED. | ||
| + | * **mqtt in** — subscribes to the same topic. | ||
| + | * **clean payload** — ensures the data is stored as a number, not a string. | ||
| + | * **influxdb out** — writes it to InfluxDB. | ||
| + | * **Grafana** — reads it back and plots it. | ||
| + | |||
| + | This round-trip (publish → subscribe → store) is artificial for the workshop, but it's exactly the shape of a real IoT pipeline: a sensor publishes to MQTT, Node-RED subscribes, transforms and stores, Grafana visualises. | ||
| + | |||
| + | ===== Your URLs and credentials ===== | ||
| + | |||
| + | Your instructor will give you: | ||
| + | |||
| + | * A **username** and **password** (the same for Node-RED and Grafana). | ||
| + | * Your personal **Node-RED URL** and **Grafana URL**. | ||
| + | * A **host: | ||
| + | |||
| + | ===== 1. Node-RED basics ===== | ||
| + | |||
| + | Open the Node-RED URL and log in. You'll see: | ||
| + | |||
| + | * **Editor canvas (middle)** — where you drag nodes and wire them up. | ||
| + | * **Palette (left)** — searchable list of every node type available to you. | ||
| + | * **Sidebar (right)** — tabs for //debug// messages, //help// for the selected node, //context// data, and more. The bug icon at the top opens the debug log; you'll live in this tab. | ||
| + | * **Deploy button (top right)** — //nothing happens until you press Deploy.// Changes you make are pending until then. This is the single most common "why isn't it working?" | ||
| + | |||
| + | The message object is called '' | ||
| + | |||
| + | <WRAP center round tip 80%> | ||
| + | **Try it before continuing: | ||
| + | </ | ||
| + | |||
| + | ===== 2. Install the extra nodes ===== | ||
| + | |||
| + | The base Node-RED installation doesn' | ||
| + | |||
| + | - Open the burger menu (top right) → **Manage palette**. | ||
| + | - Switch to the **Install** tab. | ||
| + | - Search for '' | ||
| + | - Search for '' | ||
| + | - Close the palette manager. | ||
| + | |||
| + | You should now see new nodes in the palette: an **aedes broker** node (under " | ||
| + | |||
| + | ===== 3. Host your own MQTT broker with Aedes ===== | ||
| + | |||
| + | [[https:// | ||
| + | |||
| + | - Drag an **aedes broker** node onto the canvas. | ||
| + | - Double-click it. Set: | ||
| + | * **MQTT Port:** '' | ||
| + | * Leave the rest at defaults (no auth — fine for the workshop, **not** for production). | ||
| + | - Click **Done**. | ||
| + | - Hit **Deploy**. The node should show a green " | ||
| + | |||
| + | Your broker is now reachable in two ways: | ||
| + | |||
| + | * **From inside your Node-RED** (the '' | ||
| + | * **From outside** (your laptop, an ESP32, a phone app like //MQTT Explorer//) — at the **host: | ||
| + | |||
| + | Since the broker has no authentication, | ||
| + | |||
| + | ===== 4. Publish a test value with an inject node ===== | ||
| + | |||
| + | We'll generate fake " | ||
| + | |||
| + | - Drag an **inject** node onto the canvas. | ||
| + | - Double-click it. Set: | ||
| + | * **msg.payload: | ||
| + | * **Repeat:** // | ||
| + | - Click **Done**. | ||
| + | - Drag an **mqtt out** node onto the canvas. | ||
| + | - Double-click it. Set: | ||
| + | * **Server:** click the pencil icon to add a new broker config. | ||
| + | * **Server:** '' | ||
| + | * **Port:** '' | ||
| + | * Leave the rest at defaults. Click **Add**. | ||
| + | * **Topic:** '' | ||
| + | * **QoS:** '' | ||
| + | * **Retain:** //false// | ||
| + | - Click **Done**. | ||
| + | - Wire the inject node's output to the mqtt out node's input. | ||
| + | - Hit **Deploy**. | ||
| + | |||
| + | Click the inject node's button (or wait for the 5-second interval). The mqtt out node should show " | ||
| + | |||
| + | ===== 5. Subscribe with mqtt in and debug ===== | ||
| + | |||
| + | Publishing without subscribing is shouting into the void. Let's listen. | ||
| + | |||
| + | - Drag an **mqtt in** node onto the canvas. | ||
| + | - Double-click it. Set: | ||
| + | * **Server:** select the broker config you just created ('' | ||
| + | * **Topic:** '' | ||
| + | * **QoS:** '' | ||
| + | * **Output:** // | ||
| + | - Click **Done**. | ||
| + | - Drag a **debug** node onto the canvas. Leave it at defaults (it'll show '' | ||
| + | - Wire '' | ||
| + | - Hit **Deploy**. | ||
| + | - Open the debug sidebar (the bug icon on the right). Within five seconds you should see '' | ||
| + | |||
| + | Congratulations — you've just sent a message through your own broker and received it back. The MQTT layer works. | ||
| + | |||
| + | <WRAP center round tip 80%> | ||
| + | If nothing shows up, check (in this order): (1) is the debug node enabled? (the small green dot next to it should be lit), (2) is the mqtt in node " | ||
| + | </ | ||
| + | |||
| + | ===== 6. Clean the payload so it stores as a number ===== | ||
| + | |||
| + | This step looks fussy but it's important. InfluxDB cares about //types//: a value stored as the string ''" | ||
| + | |||
| + | When the mqtt in node is set to // | ||
| + | |||
| + | - Drag a **change** node onto the canvas (it's in the " | ||
| + | - Double-click it. Add a rule: | ||
| + | * **Set** '' | ||
| + | * Set the type to **expression** (the //J:// dropdown), not //string//. | ||
| + | - Click **Done**. | ||
| + | - Wire '' | ||
| + | - Deploy and check the debug sidebar. The value should still appear, but now look at the small grey label next to it — it should say '' | ||
| + | |||
| + | The '' | ||
| + | |||
| + | <WRAP center round note 80%> | ||
| + | **For real sensor data with multiple fields** — e.g. a payload like '' | ||
| + | msg.payload = { | ||
| + | temperature: | ||
| + | humidity: Number(msg.payload.humidity) | ||
| + | }; | ||
| + | return msg; | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | ===== 7. Save it to InfluxDB ===== | ||
| + | |||
| + | The '' | ||
| + | |||
| + | You're connecting to **InfluxDB 1.x**, which is much simpler to configure than 2.x or 3.x — no tokens, no organisations, | ||
| + | |||
| + | - Drag an **influxdb out** node onto the canvas. | ||
| + | - Double-click it. Set: | ||
| + | * **Server:** click the pencil icon to add a new server config. | ||
| + | * **Version: | ||
| + | * **Host:** '' | ||
| + | * **Port:** '' | ||
| + | * **Database: | ||
| + | * **Username: | ||
| + | * **Password: | ||
| + | * Click **Add**. | ||
| + | * **Measurement: | ||
| + | - Click **Done**. | ||
| + | - Wire '' | ||
| + | [mqtt in]──►[change: | ||
| + | | ||
| + | </ | ||
| + | - Deploy. | ||
| + | |||
| + | The influxdb out node should show " | ||
| + | |||
| + | <WRAP center round important 80%> | ||
| + | **Why is the host '' | ||
| + | InfluxDB doesn' | ||
| + | </ | ||
| + | |||
| + | ==== A quick word on InfluxDB ==== | ||
| + | |||
| + | You won't interact with InfluxDB' | ||
| + | |||
| + | * Data is organised into **measurements** (≈ tables). Each measurement has **fields** (the actual numbers, like '' | ||
| + | * In your case, the influxdb out node sent a single number — so InfluxDB stored it as a field called '' | ||
| + | |||
| + | <WRAP center round important 80%> | ||
| + | **InfluxDB 1.x is end-of-life.** We use it here because it's the simplest version to configure for a teaching environment. For anything you build after this workshop, **use [[https:// | ||
| + | \\ | ||
| + | TimescaleDB is PostgreSQL with a time-series extension — if you already know SQL, you already know it. InfluxDB 3.x is a complete rewrite with a different query model again (SQL via Flight SQL); it's faster and actively maintained, but migrating 1.x dashboards/ | ||
| + | </ | ||
| + | |||
| + | ===== 8. Visualise it in Grafana ===== | ||
| + | |||
| + | Open your Grafana URL and log in with the same credentials as Node-RED. | ||
| + | |||
| + | ==== 8.1 The data source ==== | ||
| + | |||
| + | A data source tells Grafana //where// to read data from. Yours may already be set up — if so, walk through this section anyway, because adding a data source is a skill you'll use on every Grafana instance you ever touch. | ||
| + | |||
| + | - Burger menu (top left) → **Connections** → **Data sources**. | ||
| + | - If " | ||
| + | - Settings: | ||
| + | * **Query language:** '' | ||
| + | * **HTTP – URL:** '' | ||
| + | * **InfluxDB Details – Database:** '' | ||
| + | * **User:** //your workshop username// | ||
| + | * **Password: | ||
| + | * **HTTP Method:** '' | ||
| + | - Scroll down and click **Save & test**. You should get a green " | ||
| + | |||
| + | ==== 8.2 Create a dashboard ==== | ||
| + | |||
| + | - Burger menu → **Dashboards** → **New** → **New dashboard**. | ||
| + | - Click **+ Add visualization**. | ||
| + | - Pick your **InfluxDB** data source. | ||
| + | |||
| + | You're now in the panel editor. The graph fills the top; the bottom half has tabs for the **query**, with panel **options** on the right. | ||
| + | |||
| + | ==== 8.3 Build the query ==== | ||
| + | |||
| + | For InfluxQL the query builder is point-and-click: | ||
| + | |||
| + | - **FROM:** '' | ||
| + | - **SELECT:** '' | ||
| + | - **GROUP BY:** '' | ||
| + | |||
| + | The graph should immediately show your injected values, one point every few seconds. | ||
| + | |||
| + | If you used multiple fields (the '' | ||
| + | |||
| + | ==== 8.4 Tidy up the panel ==== | ||
| + | |||
| + | On the right side panel, useful starting points: | ||
| + | |||
| + | * **Title** — give it a name like " | ||
| + | * **Visualization** — //Time series// is the default; //Stat// is nice for a single big-number readout, //Gauge// for a dial. | ||
| + | * **Standard options → Unit** — pick the right unit (°C, %, kWh, …). Grafana will format axes and tooltips automatically. | ||
| + | * **Standard options → Min/Max** — fix the Y-axis range if you have known sensor bounds. | ||
| + | * **Thresholds** — add coloured bands (e.g. red above 30) that show on the graph and in stat/gauge visualisations. | ||
| + | |||
| + | Click **Apply** (top right) to drop the panel onto the dashboard, then **Save dashboard** to persist it. Give it a name. | ||
| + | |||
| + | ==== 8.5 Time range ==== | ||
| + | |||
| + | Top right of the dashboard, you can change the visible range (//Last 5 minutes//, //Last 24 hours//, …) and the auto-refresh interval. For a live demo of inject → MQTT → InfluxDB, "Last 5 minutes" | ||
| + | |||
| + | ===== Where to go from here ===== | ||
| + | |||
| + | You now have a working end-to-end pipeline. The natural next steps: | ||
| + | |||
| + | * **Replace the inject node with a real sensor.** Anything that can publish MQTT works: an ESP32 with [[https:// | ||
| + | * **Add more topics.** One broker can carry hundreds of topics, organised hierarchically ('' | ||
| + | * **Use the function node** for transformations more complex than '' | ||
| + | * **Alerting in Grafana.** Add an //alert rule// to a panel — Grafana can email, post to Slack, or hit a webhook when a threshold is crossed. | ||
| + | * **Export your flows.** Burger menu → //Export// in Node-RED gives you a JSON file. Keep it somewhere safe; it's your own offline copy if you ever want to recreate the flow elsewhere. | ||
| + | |||
| + | ===== Further reading ===== | ||
| + | |||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | |||
| + | ===== Hosting it for your own experiments ===== | ||
| + | |||
| + | Here you can find more information: | ||
| [[inhabitat: | [[inhabitat: | ||
| + | |||
inhabitat/kaunas/day03.1779878285.txt.gz · Last modified: 2026/05/27 12:38 by jan.sonntag