Thursday, 29 October 2026

AI-Powered IIoT Industrial Monitoring & Smart Alert System Using ESP32 & n8n Automation Voice Alerts

IIoT-Based Smart Industrial Monitoring and AI-Powered Alert System

Complete project documentation using ESP32, industrial sensors, n8n automation, an AI agent, Telegram voice alerts, Gmail, Google Sheets, and a live web dashboard.

Multi-Sensor IoT Safety Project Using ESP32
 
 
 
IoT-Based Environmental Monitoring System | project
 
 
 
에어릭스, 중대 재해 예방 위한 산업 현장 안전 플랫폼 출시 - 데이터넷
 
 
 

1. Project overview

The proposed system is an Internet of Things (IoT) and Industrial Internet of Things (IIoT) solution that continuously monitors environmental and equipment conditions using an ESP32 microcontroller. The ESP32 collects readings from connected sensors, evaluates safety thresholds, and sends the data to a cloud automation workflow.

The n8n workflow processes the sensor data, detects abnormal conditions, uses an AI agent to generate understandable alert messages, and distributes notifications through Telegram, Gmail, Google Sheets, and a web dashboard. A text-to-speech service can convert critical alert messages into audio files that are delivered through Telegram.

The project combines real-time monitoring, automated hazard detection, cloud data logging, remote supervision, and AI-assisted communication in one system.

File:ESP32 Espressif ESP-WROOM-32 Dev Board.jpg - Wikimedia Commons
 
 
 

1. ESP32 sensor acquisition

Reads temperature, smoke/gas, light intensity, flame detection, and equipment vibration data. It can also perform local threshold checks.

 
MQ-2 Gas Sensor Module
 
 
 

2. Industrial condition monitoring

Measures changes in the surrounding environment and machine vibration to identify potentially unsafe conditions.

 
Telegram Bot Development & n8n Automation | Best Choice Denmark
 
 
 

3. n8n automation and AI agent

Receives sensor data, validates readings, applies event-routing rules, and generates clear, context-aware alert descriptions.

 
Кияни можуть оперативно дізнатися про можливі відключення електроенергії у чат-боті Телеграм
 
 
 

4. Notifications and cloud logging

Sends Telegram text and voice alerts, emails Gmail recipients, records readings in Google Sheets, and updates a live dashboard.

Project objectives

  • Monitor industrial environmental conditions continuously.

  • Detect temperature, smoke/gas, flame, and vibration abnormalities.

  • Identify low-light or abnormal illumination conditions.

  • Notify operators remotely when configurable thresholds are exceeded.

  • Generate AI-assisted explanations of detected events.

  • Maintain timestamped sensor readings and event history.

  • Provide a web interface for monitoring current values and historical trends.

  • Reduce the delay between hazard detection and operator notification.

Important engineering note: This is a prototype and supervisory monitoring system, not a certified industrial fire alarm or safety instrumented system. Use independently certified detectors and hardwired protective circuits for actual industrial safety functions. AI and cloud automation must never be the only means of triggering emergency protection.

 

2. Complete list of project features

Feature

Implementation

Temperature monitoring

Digital temperature sensor, such as DS18B20

Smoke and gas monitoring

MQ-series sensor for prototype gas/smoke indication

Light intensity

LDR voltage-divider circuit

Fire detection

Digital flame sensor module, supplemented by a certified detector in real installations

Equipment vibration

SW-420 for simple vibration events or an accelerometer for quantitative measurements

ESP32 connectivity

Wi-Fi and HTTPS/HTTP requests

Threshold detection

ESP32 local rules and n8n event rules

AI-generated alerts

AI agent with structured sensor context

Telegram text alerts

Telegram Bot API

Telegram voice alerts

Text-to-speech service followed by Telegram audio delivery

Gmail notifications

Gmail integration in n8n

Google Sheets logging

Append timestamped readings and event records

ThingSpeak integration

Optional cloud time-series charts and channel logging

Web dashboard

ESP32-hosted page on the local network or a cloud-hosted dashboard

Automated event routing

n8n conditional branches

Historical analysis

Timestamped logs and charts

Remote monitoring

Dashboard and cloud notifications over the internet

 

3. System architecture

The system has five main layers:

  1. Sensing layer: sensors collect temperature, gas/smoke, illumination, flame, and vibration data.

  2. Edge processing layer: the ESP32 reads sensors, checks basic safety thresholds, and sends JSON data.

  3. Automation layer: n8n receives data, validates it, classifies events, and routes them to appropriate services.

  4. AI and notification layer: an AI agent prepares alert explanations; Telegram, Gmail, and text-to-speech services deliver notifications.

  5. Storage and visualization layer: Google Sheets, ThingSpeak, and the web dashboard display or retain measurements.

Overall system block diagram

Industrial Environment / Machine

Temperature · Smoke/Gas · LDR · Flame · Vibration

ESP32 Microcontroller

Sensor sampling · Local threshold checks · Wi-Fi · JSON payload

n8n Webhook and Automation

Validation · Event classification · Duplicate suppression · Routing

AI agent

Alert explanation

Notifications

Telegram · Gmail · Voice

Google Sheets

Event history

Dashboard

Webpage · ThingSpeak

n8n supports webhook-triggered workflows and integrations with services such as Telegram, Gmail, Google Sheets, and AI providers. See the official n8n documentation  and Webhook documentation .

n8n Docs
+1

Data flow diagram

mermaid

flowchart TD
    A[Industrial Sensors] --> B[ESP32 Acquisition]
    B --> C[Local Threshold Evaluation]
    C --> D[Build JSON Payload]
    D --> E[HTTPS POST to n8n]
    E --> F[Validate and Normalize]
    F --> G[Evaluate Event Severity]
    G --> H{Hazard Detected?}
    H -- No --> I[Log Normal Reading]
    H -- Yes --> J[Create Event Record]
    J --> K[AI Alert Message]
    K --> L[Telegram Text]
    K --> M[Gmail Notification]
    K --> N[Text to Speech]
    N --> O[Telegram Voice]
    I --> P[Google Sheets]
    J --> P
    I --> Q[Web Dashboard / ThingSpeak]
    J --> Q

Design principle: Do not wait for an AI response before raising a critical alarm. The ESP32 should identify known critical conditions locally, while n8n handles remote notifications. AI improves the explanation; it does not decide whether a dangerous condition is allowed to remain unreported.

 

4. Hardware components required

The following is a practical prototype bill of materials. You can substitute compatible sensors, but pin assignments and software must then be adjusted.

GitHub - TronixLab/DOIT_ESP32_DevKit-v1_30P · GitHub
 
 
 

ESP32 DevKit V1

Quantity: 1

Main controller, Wi-Fi communication, ADC measurements, and local threshold detection.

 
DS18B20 Waterproof Digital Temperature Sensor Probe - Thingbits India
 
 
 

DS18B20 temperature sensor

Quantity: 1

Digital temperature measurements. A 4.7 kΩ pull-up resistor is typically used between DATA and 3.3 V.

 
[TAR-MQ2] Módulo sensor de gas MQ-2 | Didácticas Electrónicas I+D
 
 
 

MQ-2 smoke/gas sensor module

Quantity: 1

Prototype gas/smoke response measurement. Requires warm-up and calibration; its analog output must be checked for ESP32-safe voltage.

 
5593_000ldr01_celula-fotoconductora-ldr-01
 
 
 

LDR and 10 kΩ resistor

Quantity: 1 each

Forms a voltage divider to measure relative light intensity.

 
IR Flame/Fire Sensor Module - Buy Fire Sensor Module at QuartzComponents.com
 
 
 

Flame sensor module

Quantity: 1

Demonstration-level infrared flame indication. Detection range and false-trigger susceptibility depend on the module and environment.

 
SW-420 Motion Sensor Module Vibration Switch Alarm Sensor Module
 
 
 

SW-420 vibration sensor

Quantity: 1

Detects vibration events through a digital output. For quantitative vibration monitoring, use an accelerometer such as an ADXL345 or an industrial vibration transmitter.

 
Buy Beginner’s Breadboard Electronics Kit – Build & Experiment with Power Supply Module Included
 
 
 

Supporting components

Breadboard or PCB, jumper wires, suitable power supply, pull-up resistor, LDR divider resistor, and optional buzzer/LED for local indication.

Additional software and services

  • Arduino IDE and ESP32 board support package.

  • DS18B20 libraries: OneWire and DallasTemperature.

  • An n8n instance, either hosted or self-hosted with a publicly reachable HTTPS endpoint.

  • Telegram bot and recipient chat ID.

  • Google Sheets and Gmail credentials configured in n8n.

  • An AI model provider supported by your n8n installation.

  • A text-to-speech provider or service that returns an audio file.

  • Optional ThingSpeak channel for cloud charts.

  • A local or hosted web dashboard.

 

5. Electrical schematic and connection table

The following is the proposed connection plan for an ESP32 DevKit V1. Confirm the exact pin labels on your board before wiring.

ESP32 sensor wiring schematic

Prototype-level connection diagram; use the detailed pin table below for exact connections.

text

                  ESP32 DEVKIT V1
              +----------------------+
  DS18B20 VDD | 3V3              GND |---- Common GND
  DS18B20 DQ  | GPIO 4                |
              |   |                  |
              |  4.7kΩ               |
              |   |                  |
              |  3V3                 |
              |                      |
  MQ-2 analog | GPIO 34 (ADC input)   |
  LDR divider | GPIO 35 (ADC input)   |
  Flame DO    | GPIO 27 (digital in)  |
  SW-420 DO   | GPIO 26 (digital in)  |
              +----------------------+

  LDR voltage divider:
  3V3 ---- LDR ----+---- GPIO 35
                   |
                  10kΩ
                   |
                  GND

  DS18B20 DATA pull-up:
  3V3 ---- 4.7kΩ ----+---- GPIO 4
                     |
                 DS18B20 DATA
  

Pin mapping

Device signal

ESP32 pin

Connection notes

DS18B20 DATA

GPIO 4

4.7 kΩ pull-up to 3.3 V

DS18B20 VDD

3V3

For normal three-wire operation

DS18B20 GND

GND

Common ground

MQ-2 AO

GPIO 34

ADC input only; ensure safe voltage

LDR divider midpoint

GPIO 35

ADC input only

Flame sensor DO

GPIO 27

Confirm output is 3.3 V safe

SW-420 DO

GPIO 26

Confirm output is 3.3 V safe

Optional LED

GPIO 2

Board-dependent; use a suitable resistor

 

Important electrical precautions

  1. Never connect 5 V directly to an ESP32 GPIO or ADC input. Some MQ-series modules are powered from 5 V and can output voltages higher than the ESP32 input limit. Use a properly designed divider or level-shifting circuit.

  2. All sensor signals must share an appropriate common ground with the ESP32 unless the interface is intentionally isolated.

  3. MQ-series sensors can consume significant heater current. Supply them according to the manufacturer's specifications rather than assuming the ESP32 3.3 V output can power them.

  4. Check flame and vibration module output levels before connecting their digital outputs.

  5. Do not connect the prototype directly to mains-voltage equipment, industrial motor terminals, or high-voltage control wiring.

  6. For industrial deployment, use isolated sensor interfaces, suitable enclosures, surge protection, and an engineered power supply.

The MQ-2 reading in this project is a raw relative sensor measurement. It is not a calibrated gas concentration in ppm and should not be represented as a certified gas alarm.

6. Step-by-step hardware assembly

Step 1 — Prepare the ESP32

  • Install Arduino IDE.

  • Open Preferences and add the Espressif ESP32 board package URL from the official ESP32 Arduino installation guide .

  • Open Boards Manager and install the ESP32 platform.

  • Select your ESP32 board and its USB serial port.

Step 2 — Connect the temperature sensor

Connect the DS18B20 in three-wire mode:

  • VDD to 3.3 V.

  • GND to GND.

  • DATA to GPIO 4.

  • Connect a 4.7 kΩ resistor between DATA and 3.3 V.

Install the OneWire and DallasTemperature libraries.

Step 3 — Connect the smoke/gas sensor

  • Power the MQ-2 module using its specified supply.

  • Connect its analog output through a suitable voltage divider or level shifter to GPIO 34.

  • Verify that the voltage at GPIO 34 never exceeds the ESP32 input limit.

  • Allow the sensor to warm up according to its datasheet before trusting readings.

Step 4 — Connect the LDR

  • Connect the LDR between 3.3 V and GPIO 35.

  • Connect a 10 kΩ resistor from GPIO 35 to GND.

  • Measure the ADC value under bright and dark conditions.

With this particular arrangement, a higher reading generally means more light. Calibration depends on the LDR and resistor values.

Step 5 — Connect the flame and vibration modules

  • Flame digital output to GPIO 27.

  • SW-420 digital output to GPIO 26.

  • Connect grounds appropriately.

  • Check whether each module's output is active-high or active-low. The example software assumes a LOW output means detection for both modules; change this if your modules behave differently.

Step 6 — Test sensors independently

Before connecting to n8n, verify that each sensor returns plausible readings. For the MQ-2, record baseline values and follow the required conditioning procedure. For vibration, test the sensor with gentle, repeatable vibration rather than potentially damaging equipment.

Step 7 — Enable Wi-Fi communication

Configure the ESP32 to connect to a Wi-Fi network and transmit JSON data to an HTTPS endpoint. Start with a test endpoint in n8n before enabling email, voice, and AI processing.

 

7. ESP32 firmware — complete starting implementation

This firmware combines all five sensor inputs, applies configurable threshold rules, sends measurements to an n8n webhook, and hosts a simple monitoring webpage on the ESP32's local network.

The code uses a practical polling model. It sends readings periodically and can transmit an additional event payload when a critical condition occurs. It is a prototype implementation; watchdogs, durable offline buffering, and robust delivery retries are recommended before deployment.

Step 7.1 — Install Arduino libraries

In Arduino IDE Library Manager, install:

  • OneWire

  • DallasTemperature

WiFi, HTTPClient, WebServer, WiFiClientSecure, and ArduinoJson functionality are provided by the ESP32 platform or installed separately as noted below. This example constructs JSON manually, so it does not require ArduinoJson.

Step 7.2 — Set the configuration

Replace the Wi-Fi name, password, and webhook URL. Keep the n8n endpoint private and use HTTPS in production.

cpp

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <WebServer.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// ---------- NETWORK CONFIGURATION ----------
const char* WIFI_SSID = "YOUR_WIFI_NAME";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";

// Use the production HTTPS URL from your n8n Webhook node.
const char* WEBHOOK_URL =
  "https://YOUR_N8N_HOST/webhook/industrial-sensors";

// Prototype example only.
// Set a trusted CA certificate in production; do not use insecure TLS.
const char* ROOT_CA = R"PEM(
-----BEGIN CERTIFICATE-----
PASTE_THE_TRUSTED_ROOT_CA_CERTIFICATE_HERE
-----END CERTIFICATE-----
)PEM";

// ---------- PIN ASSIGNMENTS ----------
constexpr int TEMP_PIN  = 4;
constexpr int GAS_PIN   = 34;
constexpr int LDR_PIN   = 35;
constexpr int FLAME_PIN = 27;
constexpr int VIB_PIN   = 26;
constexpr int LED_PIN   = 2;

// Set according to your modules.
constexpr int FLAME_ACTIVE = LOW;
constexpr int VIB_ACTIVE   = LOW;

// ---------- THRESHOLDS: CALIBRATE ----------
float TEMP_LIMIT_C = 50.0;
int GAS_LIMIT_ADC  = 1800;
int LIGHT_MIN_ADC  = 800;

// Sampling and reporting interval
const unsigned long SAMPLE_MS = 2000;
const unsigned long REPORT_MS = 10000;

// ---------- SENSOR OBJECTS ----------
OneWire oneWire(TEMP_PIN);
DallasTemperature tempSensor(&oneWire);
WebServer server(80);

// ---------- STATE ----------
float temperatureC = NAN;
int gasRaw = 0;
int lightRaw = 0;
bool flameDetected = false;
bool vibrationDetected = false;
bool hazard = false;

unsigned long lastSample = 0;
unsigned long lastReport = 0;
unsigned long lastEventReport = 0;

String deviceId = "ESP32-INDUSTRIAL-01";
String lastEvent = "NORMAL";

// JSON escaping for string fields.
String jsonEscape(const String& input) {
  String out;
  for (size_t i = 0; i < input.length(); i++) {
    char c = input[i];
    if (c == '"' || c == '\\') out += '\\';
    if (c == '\n') {
      out += "\\n";
    } else if (c == '\r') {
      out += "\\r";
    } else {
      out += c;
    }
  }
  return out;
}

String timestampPlaceholder() {
  // The server should assign its own trusted UTC receipt timestamp.
  // This device uptime is useful for debugging, not wall-clock time.
  return String(millis());
}

String createPayload() {
  String payload = "{";
  payload += "\"device_id\":\"" + jsonEscape(deviceId) + "\",";
  payload += "\"uptime_ms\":" + timestampPlaceholder() + ",";
  payload += "\"temperature_c\":";
  payload += isnan(temperatureC) ? "null" : String(temperatureC, 2);
  payload += ",";
  payload += "\"gas_raw\":" + String(gasRaw) + ",";
  payload += "\"light_raw\":" + String(lightRaw) + ",";
  payload += "\"flame_detected\":";
  payload += flameDetected ? "true" : "false";
  payload += ",";
  payload += "\"vibration_detected\":";
  payload += vibrationDetected ? "true" : "false";
  payload += ",";
  payload += "\"hazard_detected\":";
  payload += hazard ? "true" : "false";
  payload += ",";
  payload += "\"event\":\"" + jsonEscape(lastEvent) + "\"";
  payload += "}";
  return payload;
}

void sampleSensors() {
  tempSensor.requestTemperatures();
  float t = tempSensor.getTempCByIndex(0);

  if (t != DEVICE_DISCONNECTED_C &&
      t >= -55.0 && t <= 125.0) {
    temperatureC = t;
  } else {
    temperatureC = NAN;
  }

  gasRaw = analogRead(GAS_PIN);
  lightRaw = analogRead(LDR_PIN);

  flameDetected =
    digitalRead(FLAME_PIN) == FLAME_ACTIVE;
  vibrationDetected =
    digitalRead(VIB_PIN) == VIB_ACTIVE;

  bool previousHazard = hazard;

  // Basic demonstration rules.
  hazard =
    (!isnan(temperatureC) && temperatureC >= TEMP_LIMIT_C) ||
    gasRaw >= GAS_LIMIT_ADC ||
    flameDetected;

  // Vibration and low light are logged as conditions.
  // They are not automatically classified as emergencies.
  if (flameDetected) {
    lastEvent = "FLAME_DETECTED";
  } else if (gasRaw >= GAS_LIMIT_ADC) {
    lastEvent = "GAS_THRESHOLD";
  } else if (!isnan(temperatureC) &&
             temperatureC >= TEMP_LIMIT_C) {
    lastEvent = "HIGH_TEMPERATURE";
  } else if (vibrationDetected) {
    lastEvent = "VIBRATION_DETECTED";
  } else if (lightRaw < LIGHT_MIN_ADC) {
    lastEvent = "LOW_LIGHT";
  } else {
    lastEvent = "NORMAL";
  }

  digitalWrite(LED_PIN, hazard ? HIGH : LOW);

  if (hazard && !previousHazard) {
    Serial.println("NEW HAZARD: " + lastEvent);
  }

  Serial.println(createPayload());
}

bool sendToWebhook() {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Wi-Fi disconnected");
    return false;
  }

  WiFiClientSecure client;

  // Fail safely if the certificate is missing or invalid.
  if (String(ROOT_CA).indexOf("PASTE_THE_TRUSTED") >= 0) {
    Serial.println("Configure the trusted TLS root CA first");
    return false;
  }
  client.setCACert(ROOT_CA);

  HTTPClient http;
  if (!http.begin(client, WEBHOOK_URL)) {
    Serial.println("HTTPS connection initialization failed");
    return false;
  }

  http.setTimeout(5000);
  http.addHeader("Content-Type", "application/json");

  int status = http.POST(createPayload());

  Serial.printf("Webhook HTTP status: %d\n", status);
  String response = http.getString();

  if (status < 200 || status >= 300) {
    Serial.println(response);
  }

  http.end();
  return status >= 200 && status < 300;
}

void handleDashboard() {
  String page = R"HTML(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Industrial Monitor</title>
<style>
body{font-family:Arial;margin:24px;background:#101820;color:#f5f7fa}
.card{background:#202e3a;padding:16px;margin:10px 0;border-radius:10px}
.value{font-size:24px;font-weight:bold}
</style>
</head>
<body>
<h2>IIoT Industrial Monitoring</h2>
<div class="card">Temperature: <span id="t" class="value">--</span> °C</div>
<div class="card">Gas raw ADC: <span id="g" class="value">--</span></div>
<div class="card">Light ADC: <span id="l" class="value">--</span></div>
<div class="card">Flame: <span id="f" class="value">--</span></div>
<div class="card">Vibration: <span id="v" class="value">--</span></div>
<div class="card">Status: <span id="s" class="value">--</span></div>
<script>
async function refresh(){
  try{
    const r=await fetch('/data');
    const d=await r.json();
    document.getElementById('t').textContent=d.temperature_c ?? 'Sensor error';
    document.getElementById('g').textContent=d.gas_raw;
    document.getElementById('l').textContent=d.light_raw;
    document.getElementById('f').textContent=d.flame_detected;
    document.getElementById('v').textContent=d.vibration_detected;
    document.getElementById('s').textContent=d.event;
  }catch(e){}
}
refresh();
setInterval(refresh,2000);
</script>
</body>
</html>
)HTML";
  server.send(200, "text/html", page);
}

void handleData() {
  server.send(200, "application/json", createPayload());
}

void connectWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  Serial.print("Connecting to Wi-Fi");
  unsigned long start = millis();

  while (WiFi.status() != WL_CONNECTED &&
         millis() - start < 20000) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();

  if (WiFi.status() == WL_CONNECTED) {
    Serial.print("Dashboard: http://");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println("Wi-Fi unavailable; local sampling continues");
  }
}

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

  pinMode(FLAME_PIN, INPUT);
  pinMode(VIB_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);

  analogReadResolution(12);
  tempSensor.begin();

  connectWiFi();

  server.on("/", HTTP_GET, handleDashboard);
  server.on("/data", HTTP_GET, handleData);
  server.begin();

  lastSample = millis() - SAMPLE_MS;
  lastReport = millis();
}

void loop() {
  unsigned long now = millis();

  if (now - lastSample >= SAMPLE_MS) {
    lastSample = now;
    sampleSensors();
  }

  if (WiFi.status() == WL_CONNECTED) {
    server.handleClient();
  } else if (now % 30000 < 10) {
    WiFi.reconnect();
  }

  bool newHazardDue =
    hazard && (now - lastEventReport >= 10000);

  bool periodicReportDue =
    now - lastReport >= REPORT_MS;

  if (WiFi.status() == WL_CONNECTED &&
      (newHazardDue || periodicReportDue)) {
    bool success = sendToWebhook();

    if (success) {
      lastReport = now;
      if (newHazardDue) lastEventReport = now;
    }
  }

  delay(5);
}

Step 7.3 — What the firmware does

  • Samples sensors approximately every two seconds.

  • Evaluates temperature, gas, and flame conditions for hazards.

  • Records vibration and low-light events.

  • Sends a JSON payload to the n8n webhook.

  • Provides a local web dashboard at the ESP32's assigned IP address.

  • Uses HTTPS certificate validation for outbound requests.

  • Continues sampling when Wi-Fi is unavailable.

Limitations to fix before a production demonstration:

  • Configure a valid trusted root CA for your webhook's TLS certificate.

  • Add Wi-Fi reconnection backoff and persistent storage for missed events.

  • Implement time synchronization with NTP if the device itself must record wall-clock timestamps.

  • Add sensor fault flags instead of treating failed readings as normal.

  • Add hysteresis and time-based debounce to prevent repeated alarms from noisy sensors.

  • Replace the vibration digital switch with an accelerometer if you need vibration amplitude, RMS, frequency, or machine-health analysis.

  • The local webpage is unauthenticated and should be restricted to a trusted local network; do not expose it directly to the public internet.

Example JSON payload

json
{
  "device_id": "ESP32-INDUSTRIAL-01",
  "uptime_ms": 125000,
  "temperature_c": 52.6,
  "gas_raw": 1940,
  "light_raw": 2300,
  "flame_detected": false,
  "vibration_detected": true,
  "hazard_detected": true,
  "event": "GAS_THRESHOLD"
}

This payload is an illustrative example. Your actual sensor readings will vary with hardware and calibration.

 

8. n8n automation workflow — step by step

n8n is the central automation engine. It receives readings from the ESP32, classifies sensor conditions, records data, and distributes notifications. Its Webhook node can expose a test endpoint during development and a production endpoint when the workflow is activated.

GitHub
+1

Step 8.1 — Create an n8n instance

Choose either:

  • n8n Cloud for easier setup.

  • Self-hosted n8n using Docker or another supported deployment method.

For a self-hosted deployment, configure a public HTTPS endpoint or a secure tunnel appropriate for development. Do not expose the n8n editor or credentials to the public internet without authentication and appropriate network controls.

Step 8.2 — Create the main workflow

Create a workflow named:

IIoT Smart Industrial Monitoring and AI Alert System

Add these nodes in order:

01

Webhook

Receive ESP32 JSON payloads using POST.

 

02

Code

Validate the fields, classify events, and calculate severity.

 

03

Google Sheets

Append the reading and event record.

 

04

IF / Switch

Route normal, warning, and critical events.

 

05

AI Agent

Generate a concise explanation for the operator.

 

06

Telegram and Gmail

Send event notifications.

 

07

Text-to-Speech and Telegram

Generate an audio file and deliver it for important events.

Step 8.3 — Configure the Webhook node

Set the following properties:

Setting

Value

HTTP method

POST

Path

industrial-sensors

Response

Respond immediately with a success response, or use a Respond to Webhook node

Authentication

Prefer Header Auth or another supported authentication method

Expected content

JSON

 

During development, use the test URL while the node is listening for test events. Once the workflow is configured, activate it and copy the production URL into the ESP32 firmware.

For additional security, configure a secret header in the ESP32 and require the matching credential in n8n. Do not embed a privileged API key in a webpage or expose it in public source code.

Step 8.4 — Validate and classify the incoming readings

Insert a Code node after the Webhook node. The following example accepts a payload, assigns a severity, and creates an alert message. The thresholds must match the actual sensors and operating conditions.

javascript

const input = $json.body ?? $json;

const required = [
  "device_id",
  "gas_raw",
  "light_raw",
  "flame_detected",
  "vibration_detected"
];

for (const key of required) {
  if (input[key] === undefined || input[key] === null) {
    throw new Error(`Missing required field: ${key}`);
  }
}

const finiteNumber = (value, name) => {
  const n = Number(value);
  if (!Number.isFinite(n)) {
    throw new Error(`Invalid numeric field: ${name}`);
  }
  return n;
};

const gas = finiteNumber(input.gas_raw, "gas_raw");
const light = finiteNumber(input.light_raw, "light_raw");

const temp =
  input.temperature_c === null ||
  input.temperature_c === undefined
    ? null
    : finiteNumber(input.temperature_c, "temperature_c");

const flame = input.flame_detected === true;
const vibration = input.vibration_detected === true;

const LIMITS = {
  temperatureC: 50,
  gasRaw: 1800,
  lowLightAdc: 800
};

const reasons = [];

if (flame) reasons.push("FLAME_DETECTED");
if (gas >= LIMITS.gasRaw) reasons.push("GAS_THRESHOLD");
if (temp !== null && temp >= LIMITS.temperatureC) {
  reasons.push("HIGH_TEMPERATURE");
}
if (vibration) reasons.push("VIBRATION_DETECTED");
if (light < LIMITS.lowLightAdc) reasons.push("LOW_LIGHT");

const critical =
  flame ||
  gas >= LIMITS.gasRaw ||
  (temp !== null && temp >= LIMITS.temperatureC);

const warning = !critical && (vibration || light < LIMITS.lowLightAdc);

const severity = critical
  ? "CRITICAL"
  : warning
    ? "WARNING"
    : "NORMAL";

const now = new Date().toISOString();

return [{
  json: {
    device_id: String(input.device_id),
    timestamp_utc: now,
    temperature_c: temp,
    gas_raw: gas,
    light_raw: light,
    flame_detected: flame,
    vibration_detected: vibration,
    severity,
    event: reasons.length ? reasons.join(",") : "NORMAL",
    alert_required: critical || warning,
    alert_message: critical
      ? "CRITICAL: Immediate operator assessment required."
      : warning
        ? "WARNING: Abnormal condition detected; inspect the equipment."
        : "System operating within configured thresholds."
  }
}];

Important: A Webhook node may expose incoming data under body, depending on its settings and the incoming request. Check an actual execution and adjust the Code node's input path if required. Keep the webhook authentication configuration aligned with the ESP32 request headers.

The Code node's timestamp is the n8n server's receipt/processing time, not necessarily the sensor measurement time. For accurate event tracking, add a synchronized device timestamp and separately retain the server receipt timestamp.

Step 8.5 — Configure Google Sheets logging

Create a Google spreadsheet named IIoT_Industrial_Monitoring.

Create two tabs.

Tab 1: Sensor_Log

Column

Field

A

timestamp_utc

B

device_id

C

temperature_c

D

gas_raw

E

light_raw

F

flame_detected

G

vibration_detected

H

severity

I

event

 

Tab 2: Event_Log

Column

Field

A

timestamp_utc

B

device_id

C

severity

D

event

E

alert_message

F

notification_status

 

In n8n:

  1. Add a Google Sheets node.

  2. Connect your Google account through n8n credentials.

  3. Select the spreadsheet and Sensor_Log worksheet.

  4. Choose the append-row operation.

  5. Map each incoming field to its corresponding column.

  6. Add another append-row node to Event_Log on the alert branch.

  7. Execute the workflow with a test payload and verify the row values.

Log routine readings and events separately if you expect a high volume of sensor data. This reduces noise in the event history and makes incident review easier.

Step 8.6 — Configure conditional routing

Use an IF or Switch node based on severity.

  • CRITICAL: send Telegram immediately, send Gmail, and trigger the voice-alert branch.

  • WARNING: send a Telegram text message and log the event.

  • NORMAL: record the reading without generating an alarm every few seconds.

For critical events, send a short, deterministic alert first. Then run the AI explanation and supplemental notification steps. This avoids making the critical notification dependent on AI service availability.

 

9. AI agent configuration

The AI agent should convert structured sensor data into a readable alert, not invent measurements or independently make safety decisions.

Step 9.1 — Configure the AI node

In n8n, add an AI Agent node or the equivalent AI workflow nodes available in your version. Connect a supported chat model using stored credentials. Provide the normalized sensor fields as the agent's input.

Use this system prompt:

text

You are an industrial monitoring notification assistant.

Your role is to explain sensor events clearly and concisely.
Use only the sensor values and event classifications provided
in the input. Never invent measurements, causes, or actions
that have not been verified.

Rules:
1. Preserve the supplied severity classification.
2. Never downgrade a CRITICAL event.
3. For CRITICAL events, start with "CRITICAL ALERT".
4. State the device ID and available sensor readings.
5. State which configured threshold or sensor condition
   was triggered when that information is supplied.
6. Recommend following the site's established emergency
   procedure and having a qualified operator assess the area.
7. Do not claim that a fire, gas leak, or equipment failure
   is confirmed unless a suitable verified signal supports it.
8. Do not control machinery, silence alarms, or change
   thresholds.
9. Use simple English and keep the message under 100 words.
10. If the input is incomplete or contradictory, state that
    the reading needs verification.

Step 9.2 — Example AI-generated message

For a temperature of 52.6 °C and gas raw ADC of 1940, with a configured temperature limit of 50 °C and gas threshold of 1800:

CRITICAL ALERT — Device ESP32-INDUSTRIAL-01 reports a temperature of 52.6 °C and a gas sensor reading of 1940 ADC counts. Both readings exceed the configured prototype thresholds. Verify the sensor readings and follow the site's established safety procedure. Have a qualified operator assess the area immediately.

This message is an example generated from hypothetical readings, not a report of an actual incident.

Step 9.3 — Recommended AI design

  • Use a structured input rather than a free-form prompt assembled from arbitrary external text.

  • Keep threshold evaluation in deterministic code.

  • Keep the AI output short enough for SMS-style notifications.

  • Add a fallback template when the AI provider is unavailable.

  • Store the original sensor values alongside the generated message.

  • Avoid giving the AI agent permission to operate machinery or modify safety settings.

 

10. Telegram text alerts

Telegram provides a Bot API for sending text messages and audio files. Its sendMessage method sends text, and sendAudio or sendVoice can deliver audio in supported formats.

Telegram Core

Step 10.1 — Create a Telegram bot

  1. Open Telegram and search for the official @BotFather account.

  2. Create a new bot using /newbot.

  3. Copy the generated bot token and store it securely.

  4. Open the new bot's chat and press Start.

  5. Obtain your chat ID through a safe bot-update or integration method.

  6. Store the bot token and chat ID in n8n credentials or protected configuration.

Do not publish the token in a public Git repository, frontend webpage, or project report.

Step 10.2 — Send text messages

Add the Telegram node to the CRITICAL and WARNING branches.

Example message:

text
🚨 INDUSTRIAL SAFETY ALERT

Device: ESP32-INDUSTRIAL-01
Severity: CRITICAL
Temperature: 52.6 °C
Gas raw ADC: 1940
Flame: false
Vibration: true

Event: HIGH_TEMPERATURE, GAS_THRESHOLD

Action: Follow the site's emergency procedure
and have a qualified operator assess the condition.

Map these fields dynamically from the normalized n8n data. The message above is an example.

Step 10.3 — Prevent notification spam

Use event-based notification logic:

  • Send an immediate alert when a condition first becomes active.

  • Send a repeat notification only after a configured interval.

  • Send a recovery message when the condition clears.

  • Keep a persistent event ID or event state to avoid duplicate notifications after workflow retries.

Do not suppress repeated critical events indefinitely. The repeat policy must be configured to match the site's response requirements.

 

11. AI-generated voice alerts through Telegram

The voice-alert feature requires a text-to-speech service in addition to Telegram. n8n orchestrates the process, but the AI agent alone does not automatically produce a playable audio file.

Voice notification workflow

mermaid

flowchart TD
    A[Critical Sensor Event] --> B[Create Deterministic Alert]
    B --> C[AI Agent Creates Explanation]
    C --> D[Text-to-Speech API]
    D --> E[Receive Audio File]
    E --> F{Audio Valid?}
    F -- Yes --> G[Telegram sendVoice or sendAudio]
    F -- No --> H[Send Text Alert and Log Failure]
    G --> I[Log Notification Result]
    H --> I

Step 11.1 — Choose a text-to-speech provider

Use a service that accepts text and returns an audio file or binary response. Configure its API credentials within n8n.

A basic speech message might be:

Critical alert. High temperature and abnormal gas sensor readings detected on industrial device one. Follow the site safety procedure and inspect the area.

Keep the spoken message concise. Avoid long technical explanations that delay the operator's understanding.

Step 11.2 — Configure audio generation

  1. Pass the final alert text into the text-to-speech node or HTTP Request node.

  2. Request a supported audio format.

  3. Verify the response contains valid audio bytes, not JSON error text.

  4. Configure the next node to receive the file as binary data.

  5. Route the audio file to Telegram.

Step 11.3 — Deliver the audio file

  • Use sendVoice for a Telegram voice-note presentation when the audio is in a supported voice-note format.

  • Use sendAudio for supported MP3/M4A audio files presented as audio.

  • If the provider returns a different format, transcode it using an appropriate service or tool before uploading.

The official Telegram Bot API documents audio delivery requirements and accepted formats.

Telegram Core

If audio generation fails, the workflow must still deliver the text alert. Voice notification is an enhancement, not a dependency for critical notification.

 

12. Gmail automated email notifications

Gmail provides a detailed notification channel for supervisors and maintenance teams. It is useful for incident records, summaries, and follow-up actions.

Step-by-step configuration

  1. In n8n, create Gmail credentials using the supported Google authorization process.

  2. Add a Gmail node to the critical-event branch.

  3. Configure the recipient, subject, and message body.

  4. Map the device ID, timestamp, event severity, sensor values, and recommended next step.

  5. Add an error-handling branch to record unsuccessful email delivery.

Example email configuration:

SUBJECT

[CRITICAL] Industrial Monitoring Alert — ESP32-INDUSTRIAL-01

 

EMAIL BODY

Industrial monitoring system detected an abnormal condition.

  • Device: ESP32-INDUSTRIAL-01

  • Severity: CRITICAL

  • Temperature: 52.6 °C

  • Gas sensor: 1940 ADC counts

  • Flame sensor: Not detected

  • Event: HIGH_TEMPERATURE, GAS_THRESHOLD

Please verify the readings and follow the established site safety procedure. A qualified operator should assess the condition.

Illustrative email; values are examples.

Recommended email routing

  • Critical: immediate notification to the designated response team.

  • Warning: notification to the maintenance team according to site policy.

  • Normal: log the reading; avoid sending an email for every sample.

  • Recovery: send a separate message when the event clears, after verifying that the recovery conditions have remained stable.

 

13. Google Sheets event logging and reporting

Google Sheets serves as an accessible record of sensor data and incidents.

Recommended logging architecture

Sensor log

Periodic measurements, device identity, timestamps, and raw sensor readings.

 

Event log

Only warnings, critical conditions, recovery events, and notification outcomes.

 

Report and analysis

Maximum temperature, gas-reading trends, event counts, and equipment inspection history.

Example event-log row

Timestamp UTC

Device

Severity

Event

Notification

2026-10-29T11:05:00Z

ESP32-INDUSTRIAL-01

CRITICAL

GAS_THRESHOLD

Telegram sent

 

The row is illustrative. In the actual workflow, map the values from each execution.

Data quality and retention

  • Store timestamps in a consistent timezone, preferably UTC.

  • Keep sensor values and AI-generated text in separate fields.

  • Record notification failures instead of silently dropping them.

  • Protect the spreadsheet with appropriate access controls.

  • Consider a database or time-series platform for larger installations, as spreadsheet services are not designed to be the sole high-volume industrial historian.

 

14. ThingSpeak integration and cloud dashboard

ThingSpeak is an optional addition for storing numeric sensor data and viewing time-series charts. It can be used alongside Google Sheets rather than replacing it.

The ThingSpeak write API accepts HTTP requests containing a channel API key and fields. A channel supports up to eight fields and stores entries with timestamps. Free-tier update intervals may be restricted, so check the current account limits before selecting the sampling rate.

MATLAB
+2

Step 14.1 — Create a ThingSpeak channel

Create a channel called Industrial Monitoring.

Configure the fields as follows:

ThingSpeak field

Sensor value

Field 1

Temperature °C

Field 2

Gas raw ADC

Field 3

Light raw ADC

Field 4

Flame detection (0/1)

Field 5

Vibration detection (0/1)

Field 6

Hazard detection (0/1)

 

Copy the channel's Write API Key and store it securely.

Step 14.2 — Send data through n8n

Add an HTTP Request node after the normalization step:

  • Method: POST

  • URL: https://api.thingspeak.com/update

  • Content type: application/x-www-form-urlencoded

  • Body fields: api_key, field1, field2, through field6

Map the values to the corresponding fields.

A simplified request looks like this:

text
POST https://api.thingspeak.com/update

api_key=YOUR_WRITE_API_KEY
field1=52.6
field2=1940
field3=2300
field4=0
field5=1
field6=1

This is a configuration example, not a request that has been executed. Check the HTTP response: ThingSpeak returns an entry identifier on success and may return 0 when the update fails.

MATLAB

Step 14.3 — Configure charts

Create charts for:

  • Temperature trend.

  • Gas sensor raw readings.

  • Light intensity.

  • Flame and vibration states.

  • Hazard events over time.

Use ThingSpeak for time-series visualization and Google Sheets for convenient tabular incident review.

 

15. Web dashboard design

The project can have two complementary interfaces.

A. ESP32 local dashboard

The firmware above serves a basic webpage at the ESP32's local IP address. This works while your computer or phone can reach the ESP32 over the same network.

Advantages:

  • Simple setup.

  • Direct access to the latest sensor readings.

  • Does not require a separate web server.

Limitations:

  • Local-network access only unless additional infrastructure is configured.

  • No built-in authentication or historical database.

  • Sensor readings stop updating if the device or its network is unavailable.

B. Cloud dashboard

A more complete dashboard can read from ThingSpeak, a database, or an authenticated backend. It can display:

  • Live temperature and gas readings.

  • Flame and vibration status.

  • Current alert severity.

  • Historical charts.

  • Event timestamps.

  • Notification delivery status.

  • Device connectivity and last-seen time.

Dashboard4Ewon, data visualisation for Ewon Flexy | FOXON
 
 
 
DRi | Making Data Visible, Action Inevitable
 
 
 
Nditive
 
 
 

Suggested dashboard layout

Industrial Monitoring

Example layout

Temperature

52.6 °C

Example: above threshold

Gas raw ADC

1940

Example: threshold exceeded

Flame sensor

Not detected

Vibration sensor

Detected

Static illustrative values only; this is not connected to the ESP32 or a live data source.

For a polished deployment, keep the cloud dashboard behind authenticated access and retrieve sensor data through a controlled backend. Never place secret API keys in browser-side JavaScript.

 

16. Complete event-routing logic

A reliable system should distinguish a measurement, a warning, a critical event, and recovery.

mermaid

flowchart TD
    A[Receive Sensor Data] --> B{Payload Valid?}
    B -- No --> C[Log Invalid Payload]
    C --> D[Record Diagnostic / Retry]
    B -- Yes --> E[Evaluate Sensor Thresholds]
    E --> F{Flame or Critical Threshold?}
    F -- Yes --> G[CRITICAL]
    F -- No --> H{Abnormal Vibration or Low Light?}
    H -- Yes --> I[WARNING]
    H -- No --> J[NORMAL]
    G --> K[Immediate Text Alert]
    K --> L[AI Explanation and Voice]
    K --> M[Gmail Alert]
    G --> N[Write Event Log]
    I --> O[Warning Notification]
    O --> N
    J --> P[Write Sensor Log]
    L --> Q[Record Delivery Status]
    M --> Q
    N --> Q

Example threshold configuration

The values below are starting points for software testing only, not universal industrial limits.

Parameter

Demonstration threshold

Action

Temperature

50 °C

Critical alert

MQ-2 raw ADC

1800

Critical prototype alert

Flame sensor

Detection signal

Critical prototype alert

Vibration switch

Detection signal

Warning

Light ADC

Below 800

Warning

 

Actual thresholds must be based on the process, equipment specifications, sensor calibration, and risk assessment. A gas raw ADC threshold cannot be translated into a reliable gas concentration without appropriate calibration and sensor characterization.

Threshold hysteresis

For temperature, for example, use separate alarm and recovery thresholds:

  • Activate the alarm at or above 50 °C.

  • Clear it only after temperature remains below 47 °C for a defined period.

This prevents rapid alert switching near the threshold. Apply similar validated filtering and debounce rules to other sensor inputs where appropriate.

 

17. Step-by-step testing and commissioning

Test the system in stages instead of connecting all services at once.

Commissioning checklist

0 of 11 complete

 
ESP32 and serial outputVerify boot, sensor readings, and the expected JSON payload.
Temperature sensorCompare readings against a trusted thermometer over a safe temperature range.
MQ-2 gas sensorAllow the specified warm-up time and establish a baseline. Do not use dangerous gas releases as a test method.
LDR and flame inputVary light safely and test the digital input with a suitable controlled test stimulus.
Vibration inputApply repeatable, low-level vibration to the demonstration sensor.
Webhook receptionConfirm n8n receives valid JSON and returns the expected HTTP status.
Google SheetsConfirm that a sensor record and a test event are appended to the correct tabs.
Telegram and GmailVerify recipient IDs, message contents, and delivery outcomes.
Voice alertConfirm the TTS service returns valid audio and Telegram can play it.
Network interruptionDisconnect Wi-Fi, restore it, and check recovery and missing-event handling.
End-to-end testTrigger each simulated condition and verify the expected route, event log, and notification.

Expected test outcomes

Test scenario

Expected result

Normal readings

Sensor log updated, no emergency notification

High temperature

Critical classification, Telegram and Gmail notification

Gas threshold exceeded

Critical prototype event and logged reading

Flame input activated

Immediate critical event routing

Vibration detected

Warning notification according to policy

Low illumination

Warning if the rule is enabled

AI service unavailable

Deterministic alert still delivered

TTS service unavailable

Text alert still delivered

Wi-Fi lost

Local sampling continues; transmission resumes after reconnection

Invalid webhook payload

Validation failure is recorded and not treated as a normal reading

 

Use controlled simulation values or a test-mode input when verifying dangerous-event branches. Do not deliberately create a fire or expose personnel to hazardous gas to test a prototype.

 

18. Troubleshooting guide

Problem

Likely cause

Recommended fix

DS18B20 reports -127 °C

Wiring, missing pull-up, or sensor disconnected

Verify DATA wiring, pull-up, power, and ground

MQ-2 reading fluctuates

Warm-up, ambient conditions, power supply, or calibration

Allow conditioning time, stabilize power, and characterize baseline

LDR behaves backwards

Divider orientation or threshold assumption

Recheck wiring and calibrate the ADC threshold

Flame alert remains active

Module polarity or sensitivity setting

Check active-high/active-low behavior and module adjustment

Vibration alerts constantly

High sensitivity or unstable mounting

Adjust sensitivity and mount securely; use an accelerometer for real measurements

ESP32 cannot reach n8n

Wrong URL, firewall, DNS, Wi-Fi, or TLS certificate

Check HTTPS URL, network access, and trusted CA

Webhook receives no JSON

Wrong method/path or inactive workflow

Use POST, confirm the URL, and activate the production workflow

Google Sheets append fails

Incorrect account permissions or field mapping

Reauthorize credentials and verify spreadsheet/tab selection

Telegram returns an error

Incorrect token, chat ID, or missing bot access

Verify bot credentials and start the bot conversation

Voice alert fails

Incorrect audio format or binary-data mapping

Inspect the TTS response and convert it to a supported format

Repeated emails

Event branch executes for every reading

Add event-state tracking, debounce, and repeat-notification rules

Dashboard does not load remotely

Local-only server or network isolation

Use a secure backend or VPN; do not expose the unauthenticated page publicly

 
 

19. Security, reliability, and industrial safety

The following safeguards should be part of the final design rather than added only after testing.

Security

  • Use HTTPS and certificate validation for device-to-cloud traffic.

  • Require webhook authentication.

  • Store credentials in n8n's credential system or an equivalent secrets manager.

  • Restrict dashboard access and avoid publicly exposing the ESP32 web server.

  • Use least-privilege Google permissions.

  • Rotate compromised tokens and API keys.

  • Avoid including passwords, tokens, or sensitive network information in logs and screenshots.

Reliability

  • Use local threshold evaluation for immediate known conditions.

  • Add event persistence and retry handling for network failures.

  • Use debouncing and hysteresis to reduce nuisance alarms.

  • Record notification success or failure for each important event.

  • Add device heartbeat and last-seen monitoring.

  • Provide fallback notification text when the AI or TTS provider is unavailable.

  • Test restart behavior and recovery from loss of power or Wi-Fi.

Industrial safety

  • Do not use a generic MQ sensor or low-cost flame module as the sole certified detector.

  • Do not rely on cloud connectivity to activate a protective interlock.

  • Do not use the AI agent as a safety controller.

  • Use suitable certified detectors, engineered isolation, and independently designed protective controls for real machinery.

  • Ensure that threshold settings and response procedures are approved by qualified personnel.

IIoT-Based Smart Industrial Monitoring and AI-Powered Alert System

This project uses an ESP32 to monitor temperature, smoke/gas, light, fire, and machine vibration. It displays readings on a local webpage, sends events to n8n for logging and notifications, and can use an AI service to turn validated sensor events into clear alert messages. Similar monitoring systems combine microcontroller-connected sensors with condition-based alerts; this version adds web, cloud, and automation components.[backend.kab.ac][github]

Safety note: Treat this as an educational monitoring prototype—not a certified fire, gas, or machine-safety system. Use appropriately rated, certified detectors and independent safety controls in any real facility. Do not let an AI model decide whether an alarm is real or whether machinery should be shut down.

1. System overview

Temperature ─┐
Smoke/gas ───┤
Flame ────────┤
Light (LDR) ──┼──> ESP32 ──> Local webpage
Vibration ────┘      │
                     └──HTTPS/JSON──> n8n webhook
                                      ├── Validate and classify event
                                      ├── Log to Google Sheets
                                      ├── Send Gmail notification
                                      ├── Send Telegram text alert
                                      └── Optional: generate audio alert

The ESP32 samples sensors, applies basic threshold checks, and publishes timestamped readings. n8n handles routing, logging, and notifications. The local webpage is useful on the same network; remote access requires a properly secured network or cloud endpoint.

2. Hardware

Part Purpose
ESP32 development board Sensor reading, Wi-Fi, webpage, webhook requests
Temperature sensor, e.g. DS18B20 or a suitable industrial probe Temperature measurement
Gas/smoke sensor module, selected for the target gas Relative change detection; not a certified gas alarm
Flame sensor module Prototype flame indication
LDR and fixed resistor Relative light-level measurement
Vibration sensor or accelerometer Machine vibration indication or measurement
Breadboard/prototype PCB, wires, enclosure Assembly
Optional buzzer and indicator LEDs Local prototype alerts

Electrical cautions: ESP32 GPIO and ADC inputs are not 5 V tolerant. Verify each sensor’s output voltage; use a suitable divider or level shifter where needed. Some gas modules have heaters and need a separate, adequately rated supply. Do not power motors or industrial loads from ESP32 pins.

3. Example wiring

These are example pins only; check your board and sensor datasheets before wiring.

Sensor signal ESP32 example pin Notes
Analog gas output GPIO 34 ADC input; ensure voltage stays within ESP32 limits
LDR divider midpoint GPIO 35 LDR and resistor form a voltage divider
Vibration digital output GPIO 27 Set threshold on module; basic event-only reading
Flame digital output GPIO 26 Confirm whether the module is active-high or active-low
DS18B20 data GPIO 4 Add the pull-up resistor recommended by the sensor documentation
Buzzer (optional) GPIO 25 Use a transistor driver if the buzzer current exceeds GPIO limits
Sensor ground GND Connect grounds as appropriate for the prototype
3.3 V ── LDR ──┬── GPIO35 (ADC)
                └── fixed resistor ── GND

Sensor output ───── ESP32 input (check voltage first)
Sensor GND ──────── ESP32 GND

Avoid connecting unknown sensor outputs directly to the ESP32. For industrial probes or long cable runs, use appropriate signal conditioning, isolation, and surge protection.

4. Data and event format

Send one JSON object per reading:

{
  "device_id": "plant-demo-01",
  "timestamp": "2026-10-29T16:35:00+05:30",
  "temperature_c": 31.4,
  "gas_raw": 820,
  "light_raw": 1440,
  "flame_detected": false,
  "vibration_detected": true,
  "status": "WARNING"
}

Raw ADC values are not calibrated gas concentration or lux measurements. Establish safe limits using the sensor’s documentation and a suitable calibration process. For this prototype, choose conservative demonstration thresholds and label them clearly as examples.

5. ESP32 Arduino example

Install the ESP32 board package and the OneWire and DallasTemperature libraries. Set Wi-Fi credentials, the n8n webhook URL, and thresholds before uploading. This example uses a DS18B20, analog gas and LDR inputs, and digital flame/vibration inputs.

#include <WiFi.h>
#include <HTTPClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASSWORD = "YOUR_PASSWORD";
const char* WEBHOOK_URL = "https://YOUR_N8N_HOST/webhook/industrial";

constexpr int PIN_TEMP = 4;
constexpr int PIN_GAS = 34;
constexpr int PIN_LDR = 35;
constexpr int PIN_VIBRATION = 27;
constexpr int PIN_FLAME = 26;

constexpr int GAS_LIMIT = 2500;     // Example only; calibrate for your setup
constexpr int TEMP_LIMIT_C = 50;    // Example only
constexpr int LDR_LIMIT = 3000;     // Example only

OneWire oneWire(PIN_TEMP);
DallasTemperature tempSensor(&oneWire);

unsigned long lastPost = 0;
const unsigned long POST_INTERVAL_MS = 5000;

void connectWiFi() {
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(PIN_VIBRATION, INPUT);
  pinMode(PIN_FLAME, INPUT);
  analogReadResolution(12);
  tempSensor.begin();
  connectWiFi();
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) connectWiFi();

  if (millis() - lastPost < POST_INTERVAL_MS) {
    delay(50);
    return;
  }
  lastPost = millis();

  tempSensor.requestTemperatures();
  float temperatureC = tempSensor.getTempCByIndex(0);
  int gasRaw = analogRead(PIN_GAS);
  int lightRaw = analogRead(PIN_LDR);
  bool vibration = digitalRead(PIN_VIBRATION);
  bool flame = digitalRead(PIN_FLAME); // Invert if your module is active-low.

  bool tempAlarm = temperatureC > TEMP_LIMIT_C;
  bool gasAlarm = gasRaw > GAS_LIMIT;
  bool lightAlarm = lightRaw > LDR_LIMIT;
  bool alarm = tempAlarm || gasAlarm || flame || vibration || lightAlarm;

  String status = alarm ? "ALERT" : "NORMAL";

  String payload = "{";
  payload += "\"device_id\":\"plant-demo-01\",";
  payload += "\"temperature_c\":" + String(temperatureC, 1) + ",";
  payload += "\"gas_raw\":" + String(gasRaw) + ",";
  payload += "\"light_raw\":" + String(lightRaw) + ",";
  payload += "\"flame_detected\":" + String(flame ? "true" : "false") + ",";
  payload += "\"vibration_detected\":" + String(vibration ? "true" : "false") + ",";
  payload += "\"status\":\"" + status + "\"";
  payload += "}";

  Serial.println(payload);

  HTTPClient http;
  http.begin(WEBHOOK_URL);
  http.addHeader("Content-Type", "application/json");
  http.setTimeout(4000);
  int code = http.POST(payload);
  Serial.printf("Webhook HTTP status: %d\n", code);
  http.end();
}

For a real deployment, add a device key or signed request, TLS certificate validation, reconnect backoff, sensor-failure detection, and a monotonic event ID. Avoid putting secrets in public firmware repositories.

6. n8n workflow

Create a workflow with these nodes:

Webhook (POST)
   ↓
Validate fields / reject malformed payloads
   ↓
Set timestamp and derive event severity
   ↓
Google Sheets: append row
   ↓
IF status is ALERT
   ├── Gmail: send email
   ├── Telegram: send text message
   └── Optional AI message → text-to-speech → Telegram audio
  1. Webhook: Create a POST webhook and copy its production URL into the ESP32 sketch.
  2. Validation: Check that required fields exist and are within plausible ranges. Reject malformed or oversized requests.
  3. Classification: Use deterministic rules for alarm status. Keep the thresholds in the workflow or firmware and document their units.
  4. Google Sheets: Append timestamp, device ID, sensor readings, status, and event ID to a sheet.
  5. Gmail: Send an email only for relevant events; include device, time, measured value, and recommended human verification.
  6. Telegram: Send a concise alert through a Telegram bot. Store the bot token in n8n credentials, not in the webpage or public code.
  7. Optional voice: Pass a short, fixed-format alert to a text-to-speech service and send its audio file using Telegram. Make this a secondary notification channel.
  8. Reliability: Configure retries and error handling; prevent duplicate alerts using event IDs or a cooldown period.

The AI agent may rewrite a validated event into readable language, but it should not invent measurements, set thresholds, suppress alarms, or control equipment. Include the original sensor values in every alert.

7. Local webpage

A simple local dashboard can display current values and status. Serve it from the ESP32 or from a separate local host. For a prototype, show readings, last update time, and Wi-Fi status. Protect any control endpoints; preferably make the dashboard read-only. Do not expose an unauthenticated ESP32 web server directly to the public internet.

8. Build and test steps

  1. Assemble the ESP32 and one sensor at a time; verify voltage levels and common ground.
  2. Upload a sensor-only test sketch and check serial readings.
  3. Confirm sensor polarity and response using safe, controlled tests.
  4. Configure Wi-Fi and the n8n webhook; verify a test JSON arrives.
  5. Add validation and Google Sheets logging, then check timestamps and column order.
  6. Add Gmail and Telegram notifications; test with a harmless test event.
  7. Add the optional AI wording and voice path only after deterministic alerts work.
  8. Test network loss, sensor disconnection, duplicate events, and n8n failure.
  9. Record the final wiring, pin mapping, thresholds, calibration notes, and known limitations.

9. Suggested project documentation

Include the project objective, block diagram, circuit and pin table, component list, firmware, n8n workflow export, Google Sheet column definitions, test cases, threshold rationale, security notes, and limitations. The prototype can demonstrate remote monitoring and event notifications, but sensor readings and thresholds must be validated for the actual environment before any safety use.

No comments:

Post a Comment