Saturday, 22 August 2026

AI Intelligent Helmet for Mining Industry with Accident Prediction

AI Intelligent Helmet for Mining Industry — Complete Project Documentation

This project can be implemented as an ESP32-based intelligent mining helmet that continuously monitors environmental and worker-condition parameters, detects abnormal patterns, estimates an accident-risk score, sends data to the cloud, and uses n8n + an AI agent + Telegram for intelligent notifications and voice alerts.

Important engineering note: this should be treated as a prototype/research safety system, not as the sole life-safety system in a real mine. Gas thresholds, sensor selection, enclosure, intrinsic-safety certification, radio operation, battery protection, and alarm behavior must be validated against the mine's applicable safety standards before deployment.

ESP32 is suitable for this type of prototype because it provides Wi-Fi, Bluetooth, GPIO, ADC, I²C and other peripherals. Espressif also documents ADC/GPIO restrictions; in particular, classic ESP32 ADC2 conflicts with Wi-Fi, so analog sensors should preferably be connected to ADC1 pins when Wi-Fi is active.


1. Project Title

AI Intelligent Helmet for Mining Industry with Accident Prediction, IoT Cloud Monitoring, n8n Automation, AI Agent and Telegram Voice Alerts

Short title

AI Mining Safety Helmet using ESP32 + IoT + AI Agent + n8n


2. Abstract

The proposed system is an intelligent wearable safety helmet designed to improve situational awareness for underground mining workers.

The helmet contains an ESP32 controller connected to environmental and motion sensors. The system measures parameters such as:

  • Temperature
  • Humidity
  • Methane/gas level
  • Carbon monoxide/gas level
  • Worker motion
  • Sudden impact
  • Helmet orientation
  • Optional heart-rate/SpO₂
  • GPS/location where GPS reception is available
  • Emergency/SOS button
  • Battery voltage

The ESP32 processes the sensor information locally and transmits measurements through Wi-Fi to an n8n automation server.

n8n acts as the orchestration layer:

ESP32
   ↓
HTTP/Webhook
   ↓
n8n
   ↓
AI Agent
   ↓
Risk Assessment
   ├── Normal → Log data
   ├── Warning → Telegram text
   ├── High Risk → Telegram + voice alert
   └── Emergency → Immediate emergency notification
          ↓
Google Sheets
          ↓
ThingSpeak Dashboard

The AI component does not simply look at one sensor threshold. It can evaluate multiple measurements and their trends together.

For example:

Methane increasing
       +
Temperature increasing
       +
Worker motion abnormal
       +
Sudden acceleration
       ↓
AI Risk Analysis
       ↓
HIGH RISK

The system can then automatically generate a message such as:

HIGH RISK ALERT — Helmet H001
Methane level is increasing and abnormal motion was detected.
Risk score: 87/100.
Worker should move to a safer area and supervisor should investigate immediately.

The Telegram Bot API supports sending playable voice messages through sendVoice; current Telegram documentation specifies supported voice formats including OGG/Opus, MP3 and M4A.


3. Main Objectives

The project has seven major objectives.

Objective 1 — Environmental monitoring

Continuously monitor hazardous environmental conditions.

Objective 2 — Worker monitoring

Detect:

  • Sudden fall
  • Impact
  • Unusual inactivity
  • Abnormal movement
  • Helmet removal, if a strap sensor is added

Objective 3 — Accident-risk prediction

Calculate a risk score based on:

Sensor values
+
Sensor trends
+
Motion patterns
+
Emergency button
+
Historical information

Objective 4 — Intelligent decision making

Use an n8n AI Agent to interpret the incoming information.

Objective 5 — Automated communication

Automatically notify supervisors through Telegram.

Objective 6 — Cloud data storage

Store measurements in:

  • Google Sheets
  • ThingSpeak

Objective 7 — Web dashboard

Provide a browser-based monitoring dashboard.


4. Complete System Architecture

                    ┌─────────────────────────────┐
                    │       MINING WORKER         │
                    │                             │
                    │       AI SMART HELMET       │
                    └──────────────┬──────────────┘
                                   │
                                   ▼
                    ┌─────────────────────────────┐
                    │            ESP32             │
                    │                             │
                    │ Sensor acquisition           │
                    │ Local filtering              │
                    │ Fall detection               │
                    │ Emergency detection          │
                    │ Risk pre-processing           │
                    │ Wi-Fi communication           │
                    └──────────────┬──────────────┘
                                   │
                              HTTPS/HTTP
                                   │
                                   ▼
                    ┌─────────────────────────────┐
                    │        n8n WEBHOOK           │
                    └──────────────┬──────────────┘
                                   │
                ┌──────────────────┼──────────────────┐
                │                  │                  │
                ▼                  ▼                  ▼
        ┌──────────────┐   ┌──────────────┐   ┌──────────────┐
        │ AI AGENT     │   │ Google Sheets│   │ ThingSpeak   │
        │              │   │              │   │              │
        │ Risk Score   │   │ Historical   │   │ Live Charts  │
        │ Reasoning    │   │ Records      │   │ Cloud Data   │
        │ Decision     │   │              │   │              │
        └──────┬───────┘   └──────────────┘   └──────────────┘
               │
               ▼
        ┌────────────────┐
        │ Risk Decision  │
        └───────┬────────┘
                │
       ┌────────┼───────────┐
       │        │           │
       ▼        ▼           ▼
    NORMAL   WARNING     CRITICAL
       │        │           │
       │        ▼           ▼
       │    Telegram      Telegram
       │      Text       Text + Voice
       │                    │
       └────────┬───────────┘
                ▼
          Supervisor

5. Proposed Hardware

5.1 Controller

ESP32 DevKit

ESP32 provides Wi-Fi and Bluetooth connectivity and a large set of peripherals appropriate for an IoT prototype.

5.2 Sensors

A practical prototype can use:

Component Purpose
ESP32 Main controller
MPU6050 Accelerometer + gyroscope
MQ-4 Methane indication
MQ-7 Carbon monoxide indication
BME280 Temperature + humidity + pressure
NEO-6M GPS Location outdoors/surface
Push button Emergency/SOS
Buzzer Local alarm
Red LED Critical warning
Green LED Normal status
Vibration motor Wearer alert
Battery voltage divider Battery monitoring
Optional MAX30102 Heart rate/SpO₂ prototype
Optional strap switch Helmet-wear detection

Important gas-sensor note

MQ-series sensors are useful for educational prototypes but should not be treated as certified mine gas detectors. Real mining applications require appropriate certified gas-sensing equipment.


6. Hardware Block Diagram

                    ┌─────────────────┐
                    │   Li-ion Battery│
                    └────────┬────────┘
                             │
                       Power Regulation
                             │
                             ▼
                    ┌─────────────────┐
                    │      ESP32      │
                    └───────┬─────────┘
                            │
       ┌────────────────────┼─────────────────────┐
       │                    │                     │
       ▼                    ▼                     ▼
   MPU6050                BME280              GPS Module
 Accel/Gyro            Temp/Humidity          NEO-6M
       │                    │                     │
       └──────────────┬─────┴──────────────┬──────┘
                      │                    │
                      ▼                    ▼
                  I²C Bus              UART GPS
                      │
       ┌──────────────┼───────────────┐
       │              │               │
       ▼              ▼               ▼
     MQ-4            MQ-7          SOS Button
   Methane            CO
       │              │
       └───────┬──────┘
               ▼
             ESP32
               │
      ┌────────┼─────────┐
      │        │         │
      ▼        ▼         ▼
    Buzzer     LED    Vibration
      │
      ▼
   Wi-Fi
      │
      ▼
     n8n

7. Example ESP32 Pin Assignment

For a classic ESP32 DevKit:

Device ESP32 pin
MPU6050 SDA GPIO 21
MPU6050 SCL GPIO 22
BME280 SDA GPIO 21
BME280 SCL GPIO 22
MQ-4 analog GPIO 34
MQ-7 analog GPIO 35
SOS button GPIO 27
Buzzer GPIO 26
Red LED GPIO 25
Green LED GPIO 33
Vibration motor driver GPIO 32
GPS RX/TX GPIO 16/17
Battery ADC GPIO 36

GPIO34–39 on the classic ESP32 are input-only, which makes them useful for analog measurements. Espressif also notes that ADC2 cannot be used normally for ADC reads while Wi-Fi is operating, so the example deliberately uses ADC1-capable pins such as GPIO34/35/36.


8. Schematic-Level Connection

                         ESP32
                   ┌────────────────┐
                   │                │
       3.3V ───────┤3V3             │
       GND ────────┤GND             │
                   │                │
 MPU6050 SDA ──────┤GPIO21          │
 MPU6050 SCL ──────┤GPIO22          │
                   │                │
 BME280 SDA ───────┤GPIO21          │
 BME280 SCL ───────┤GPIO22          │
                   │                │
 MQ4 AO ───────────┤GPIO34          │
 MQ7 AO ───────────┤GPIO35          │
 Battery divider ──┤GPIO36          │
                   │                │
 SOS ──────────────┤GPIO27          │
 Buzzer Driver ────┤GPIO26          │
 Red LED ──────────┤GPIO25          │
 Green LED ────────┤GPIO33          │
 Vibration Driver ─┤GPIO32          │
                   │                │
 GPS TX ───────────┤GPIO16 (RX2)    │
 GPS RX ───────────┤GPIO17 (TX2)    │
                   └────────────────┘

Motor/buzzer driver

Do not drive a high-current vibration motor directly from an ESP32 GPIO.

Use:

ESP32 GPIO
    │
    R
    │
    ▼
 MOSFET
    │
    ├──── Motor
    │
   GND

Flyback diode across inductive load where appropriate.

The same principle applies to a larger external buzzer.


9. Operating Principle

The helmet operates in several stages.

Stage 1 — Sensor acquisition

ESP32 reads the sensors periodically.

Example:

Every 1 second:

Temperature
Humidity
Methane
CO
Acceleration
Gyroscope
Battery
GPS
SOS

Stage 2 — Filtering

Raw readings are noisy.

Therefore:

Raw data
   ↓
Moving average
   ↓
Median/filter
   ↓
Validated data

Stage 3 — Local event detection

ESP32 immediately detects conditions that should not wait for an AI response.

Examples:

SOS button pressed
       ↓
Immediate emergency

Large acceleration spike
       ↓
Possible impact

No motion after impact
       ↓
Possible fall

Very high sensor reading
       ↓
Immediate local alarm

Stage 4 — Cloud transmission

ESP32 creates JSON:

{
  "helmet_id": "H001",
  "temperature": 32.4,
  "humidity": 67.2,
  "methane": 415,
  "co": 82,
  "accel": 1.24,
  "gyro": 13.8,
  "fall": false,
  "sos": false,
  "battery": 3.91,
  "risk": 23
}

It sends the data to n8n.


10. Accident Prediction Concept

The term prediction should be implemented carefully.

Instead of claiming:

"The AI knows an accident will happen."

the system should calculate:

"The current sensor pattern indicates elevated accident risk."

This is much more technically defensible.


11. Risk Score

A simple prototype can use a 0–100 risk score.

Example:

Risk =
    Gas Risk
  + Temperature Risk
  + Motion Risk
  + Fall Risk
  + Inactivity Risk
  + SOS Risk

Example weighting:

Gas             30%
Motion          25%
Fall            25%
Temperature     10%
Inactivity       5%
SOS              5%

But an actual deployed system should derive the weights from validated field data rather than arbitrary numbers.


12. Example Risk Levels

Risk Level Action
0–20 NORMAL Store data
21–40 LOW Monitor
41–60 WARNING Telegram notification
61–80 HIGH Telegram + supervisor alert
81–100 CRITICAL Local alarm + Telegram voice alert

Example:

Risk = 18
NORMAL
Risk = 55
WARNING
Risk = 73
HIGH
Risk = 94
CRITICAL

13. Accident Detection Logic

One useful prototype algorithm is:

Acceleration > impact threshold
             ↓
       Possible impact
             ↓
     Start 10-second timer
             ↓
       Motion detected?
       /             \
     YES              NO
      │                │
      ▼                ▼
 Cancel alarm      Possible fall
                       │
                       ▼
                 Increase risk
                       │
                       ▼
                  n8n / AI Agent

For example:

Before event:
acceleration ≈ 1 g

Impact:
acceleration = 5.8 g

After impact:
acceleration ≈ 1 g
+
worker remains almost stationary

This could be classified as a possible fall/impact event.

The threshold must be experimentally calibrated for the actual helmet, mounting position and worker activity.


14. AI Agent Architecture

The AI Agent sits in n8n.

                  n8n
                   │
                   ▼
            ┌───────────────┐
            │ Normalize Data│
            └───────┬───────┘
                    │
                    ▼
             ┌────────────┐
             │ AI Agent   │
             └─────┬──────┘
                   │
        ┌──────────┼───────────┐
        │          │           │
        ▼          ▼           ▼
   Sensor data  History     Rules
        │          │           │
        └──────────┼───────────┘
                   ▼
             Risk Analysis
                   │
                   ▼
            Structured JSON
                   │
                   ▼
             Decision node

15. AI Agent Prompt

Use a structured prompt similar to:

You are a mining safety monitoring AI assistant.

You receive sensor information from an intelligent mining helmet.

Your task is to evaluate the current safety condition.

Do not claim that an accident is certain.

Classify the situation as:

NORMAL
LOW
WARNING
HIGH
CRITICAL

Consider:

1. Gas concentration and trend
2. Temperature
3. Worker movement
4. Sudden acceleration
5. Possible fall
6. Inactivity
7. SOS button
8. Battery condition
9. Previous sensor readings

Return JSON only:

{
  "risk_score": 0,
  "risk_level": "NORMAL",
  "event": "NONE",
  "reason": "Short explanation",
  "recommended_action": "Recommended action",
  "telegram_message": "Short alert message",
  "voice_message": "Short spoken alert"
}

Do not invent sensor measurements.
If a measurement is missing, say so.
Treat this system as an advisory prototype and never state that it replaces certified mine safety equipment.

16. n8n Workflow

n8n provides built-in Telegram integration for automating Telegram operations.

The main workflow can be:

┌──────────────┐
│ Webhook      │
│ ESP32 DATA   │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│ JSON Validate│
└──────┬───────┘
       │
       ▼
┌──────────────┐
│ Set / Code   │
│ Normalize    │
└──────┬───────┘
       │
       ├──────────────────┐
       │                  │
       ▼                  ▼
 Google Sheets       ThingSpeak
       │                  │
       └────────┬─────────┘
                ▼
          ┌─────────────┐
          │ AI Agent    │
          └──────┬──────┘
                 │
                 ▼
         Structured Output
                 │
                 ▼
          ┌─────────────┐
          │ IF / Switch │
          └──────┬──────┘
                 │
       ┌─────────┼───────────┐
       │         │           │
       ▼         ▼           ▼
    NORMAL    WARNING     CRITICAL
       │         │           │
       │         ▼           ▼
       │      Telegram     Telegram
       │       Text       Text + Voice
       │                     │
       └─────────┬───────────┘
                 ▼
             Log event

17. n8n Node-by-Node Configuration

Node 1 — Webhook

Create:

Method: POST
Path: mining-helmet

The resulting endpoint is conceptually:

https://YOUR-N8N-SERVER/webhook/mining-helmet

ESP32 sends JSON to this endpoint.


18. Node 2 — Data Validation

Validate:

helmet_id
temperature
humidity
methane
co
accel
gyro
fall
sos
battery
timestamp

Reject malformed packets.


19. Node 3 — Data Normalization

Convert everything into a standard structure:

{
  "helmet_id": "H001",
  "timestamp": "2026-08-22T22:25:00+05:30",
  "temperature": 32.4,
  "humidity": 67.2,
  "methane": 415,
  "co": 82,
  "accel": 1.24,
  "gyro": 13.8,
  "fall": false,
  "sos": false,
  "battery": 3.91
}

20. Node 4 — Google Sheets

Create columns:

Timestamp
Helmet ID
Temperature
Humidity
Methane
CO
Acceleration
Gyroscope
Fall
SOS
Battery
Risk Score
Risk Level
AI Reason
Action

Example:

Timestamp Helmet Temp CH4 CO Fall Risk
22:25 H001 32.4 415 82 No 23
22:26 H001 32.6 460 91 No 38
22:27 H001 33.1 580 103 Yes 82

This historical data can later become training data for a real machine-learning model.


21. Node 5 — ThingSpeak

ThingSpeak can provide charts and cloud visualization of sensor fields. Existing ThingSpeak channels expose field charts and feeds through the service.

Suggested channel:

Field 1 = Temperature
Field 2 = Humidity
Field 3 = Methane
Field 4 = CO
Field 5 = Acceleration
Field 6 = Risk Score
Field 7 = Battery
Field 8 = Fall/SOS status

The update concept is:

https://api.thingspeak.com/update

with parameters such as:

api_key
field1
field2
field3
...

Do not place a real ThingSpeak write API key in a public webpage or public GitHub repository.


22. Node 6 — AI Agent

Input:

{
  "helmet_id": "H001",
  "temperature": 33.1,
  "humidity": 68,
  "methane": 580,
  "co": 103,
  "accel": 7.2,
  "fall": true,
  "sos": false
}

AI returns:

{
  "risk_score": 86,
  "risk_level": "CRITICAL",
  "event": "POSSIBLE_FALL",
  "reason": "Sudden impact followed by abnormal motion combined with elevated gas readings.",
  "recommended_action": "Notify supervisor and check worker condition immediately.",
  "telegram_message": "CRITICAL: H001 possible fall with elevated gas readings.",
  "voice_message": "Critical alert. Helmet H001 detected a possible fall and elevated hazardous gas readings. Check the worker immediately."
}

23. Node 7 — Switch/IF

Conditions:

risk_score < 40
       ↓
NORMAL

40–60
       ↓
WARNING

61–80
       ↓
HIGH

>80
       ↓
CRITICAL

For a real deployment, gas alarm logic should also include independent hard thresholds, rather than relying exclusively on an LLM.


24. Telegram Alert

For normal conditions:

No Telegram alert.

For warning:

⚠️ MINING HELMET WARNING

Helmet: H001
Risk: 55/100

Methane trend increasing.
Temperature: 33.1°C

Please monitor worker condition.

For critical:

🚨 CRITICAL MINING SAFETY ALERT

Helmet: H001

Possible fall detected.
Hazardous gas readings elevated.

Risk Score: 86/100

Immediate supervisor investigation required.

25. Telegram Voice Alert

The architecture is:

AI Agent
    │
    ▼
Voice message text
    │
    ▼
TTS service
    │
    ▼
OGG/Opus audio
    │
    ▼
Telegram Bot API
    │
    ▼
Supervisor's Telegram

Telegram's sendVoice API is specifically intended for playable voice messages.

Example voice text:

Critical mining safety alert.

Helmet H001 has detected a possible worker fall and elevated hazardous gas readings.

Please check the worker immediately.

26. n8n Telegram Voice Workflow

AI Agent
   │
   ▼
Extract voice_message
   │
   ▼
HTTP Request — TTS
   │
   ▼
Binary audio
   │
   ▼
Telegram sendVoice
   │
   ▼
Supervisor

If the selected TTS service returns a format unsuitable for Telegram voice messages, convert it to an appropriate supported format before sending. Telegram documents supported voice-message formats and file constraints.


27. ESP32 Arduino Software

The following is a prototype reference implementation, not production-certified safety firmware.

Install these Arduino libraries:

WiFi
HTTPClient
Wire
ArduinoJson
Adafruit MPU6050
Adafruit BME280
TinyGPSPlus

Example firmware:

#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <ArduinoJson.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <TinyGPSPlus.h>

// -----------------------------
// Wi-Fi
// -----------------------------
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASSWORD = "YOUR_PASSWORD";

// n8n webhook
const char* N8N_URL =
    "https://YOUR-N8N-SERVER/webhook/mining-helmet";

// -----------------------------
// Helmet ID
// -----------------------------
const char* HELMET_ID = "H001";

// -----------------------------
// Pins
// -----------------------------
#define MQ4_PIN       34
#define MQ7_PIN       35
#define BATTERY_PIN   36

#define SOS_PIN       27
#define BUZZER_PIN    26
#define RED_LED_PIN   25
#define GREEN_LED_PIN 33
#define VIBRATION_PIN 32

// GPS
#define GPS_RX 16
#define GPS_TX 17

// -----------------------------
// Sensors
// -----------------------------
Adafruit_MPU6050 mpu;
Adafruit_BME280 bme;
TinyGPSPlus gps;
HardwareSerial GPSSerial(2);

// -----------------------------
// Timing
// -----------------------------
unsigned long lastSend = 0;
const unsigned long SEND_INTERVAL = 5000;

// -----------------------------
// Fall detection
// -----------------------------
bool possibleFall = false;
unsigned long impactTime = 0;

const float IMPACT_THRESHOLD_G = 4.0;
const float INACTIVITY_THRESHOLD_G = 0.25;

// -----------------------------
// Read acceleration magnitude
// -----------------------------
float readAccelerationG() {

  sensors_event_t accel;
  sensors_event_t gyro;
  sensors_event_t temp;

  mpu.getEvent(&accel, &gyro, &temp);

  float ax = accel.acceleration.x;
  float ay = accel.acceleration.y;
  float az = accel.acceleration.z;

  float magnitude =
      sqrt(ax * ax + ay * ay + az * az);

  return magnitude / 9.80665;
}

// -----------------------------
// Detect possible fall
// -----------------------------
void updateFallDetection(float accelG) {

  if (accelG >= IMPACT_THRESHOLD_G) {

    possibleFall = true;
    impactTime = millis();

    digitalWrite(BUZZER_PIN, HIGH);
    digitalWrite(VIBRATION_PIN, HIGH);
    digitalWrite(RED_LED_PIN, HIGH);
  }

  // If possible fall remains active for 10 sec,
  // the system continues reporting it.
  if (possibleFall &&
      millis() - impactTime > 10000) {

    digitalWrite(BUZZER_PIN, LOW);
    digitalWrite(VIBRATION_PIN, LOW);
  }
}

// -----------------------------
// Battery voltage
// -----------------------------
float readBatteryVoltage() {

  int raw = analogRead(BATTERY_PIN);

  float voltage =
      ((float)raw / 4095.0) * 3.3;

  // Example 100k/100k divider.
  voltage *= 2.0;

  return voltage;
}

// -----------------------------
// Simple prototype risk score
// -----------------------------
int calculateRisk(
    int methane,
    int co,
    float temperature,
    float accelG,
    bool fall,
    bool sos
) {

  int risk = 0;

  // These are prototype/example values.
  // They MUST NOT be treated as certified
  // mine alarm limits.

  if (methane > 300)
    risk += 15;

  if (methane > 500)
    risk += 20;

  if (co > 100)
    risk += 15;

  if (co > 200)
    risk += 20;

  if (temperature > 35)
    risk += 10;

  if (temperature > 40)
    risk += 10;

  if (accelG > 4)
    risk += 25;

  if (fall)
    risk += 30;

  if (sos)
    risk += 50;

  if (risk > 100)
    risk = 100;

  return risk;
}

// -----------------------------
// Send data to n8n
// -----------------------------
void sendToN8N() {

  sensors_event_t accel;
  sensors_event_t gyro;
  sensors_event_t tempEvent;

  mpu.getEvent(
      &accel,
      &gyro,
      &tempEvent
  );

  float ax = accel.acceleration.x;
  float ay = accel.acceleration.y;
  float az = accel.acceleration.z;

  float accelG =
      sqrt(
          ax * ax +
          ay * ay +
          az * az
      ) / 9.80665;

  float temperature =
      bme.readTemperature();

  float humidity =
      bme.readHumidity();

  int methane =
      analogRead(MQ4_PIN);

  int co =
      analogRead(MQ7_PIN);

  bool sos =
      digitalRead(SOS_PIN) == LOW;

  float battery =
      readBatteryVoltage();

  updateFallDetection(accelG);

  int risk = calculateRisk(
      methane,
      co,
      temperature,
      accelG,
      possibleFall,
      sos
  );

  StaticJsonDocument<1024> doc;

  doc["helmet_id"] = HELMET_ID;

  doc["temperature"] = temperature;
  doc["humidity"] = humidity;

  doc["methane_raw"] = methane;
  doc["co_raw"] = co;

  doc["acceleration_g"] = accelG;

  doc["gyro_x"] = gyro.gyro.x;
  doc["gyro_y"] = gyro.gyro.y;
  doc["gyro_z"] = gyro.gyro.z;

  doc["fall"] = possibleFall;
  doc["sos"] = sos;

  doc["battery"] = battery;
  doc["risk_score"] = risk;

  if (gps.location.isValid()) {

    doc["latitude"] =
        gps.location.lat();

    doc["longitude"] =
        gps.location.lng();
  }

  String json;

  serializeJson(doc, json);

  Serial.println(json);

  if (WiFi.status() == WL_CONNECTED) {

    HTTPClient http;

    http.begin(N8N_URL);

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

    int responseCode =
        http.POST(json);

    Serial.print("n8n response: ");
    Serial.println(responseCode);

    http.end();
  }

  // Local alarm
  if (risk >= 70 || sos) {

    digitalWrite(
        RED_LED_PIN,
        HIGH
    );

    digitalWrite(
        BUZZER_PIN,
        HIGH
    );

    digitalWrite(
        VIBRATION_PIN,
        HIGH
    );

  } else {

    digitalWrite(
        RED_LED_PIN,
        LOW
    );

    digitalWrite(
        BUZZER_PIN,
        LOW
    );

    digitalWrite(
        VIBRATION_PIN,
        LOW
    );
  }
}

// -----------------------------
// Setup
// -----------------------------
void setup() {

  Serial.begin(115200);

  pinMode(
      SOS_PIN,
      INPUT_PULLUP
  );

  pinMode(
      BUZZER_PIN,
      OUTPUT
  );

  pinMode(
      RED_LED_PIN,
      OUTPUT
  );

  pinMode(
      GREEN_LED_PIN,
      OUTPUT
  );

  pinMode(
      VIBRATION_PIN,
      OUTPUT
  );

  Wire.begin(
      21,
      22
  );

  // MPU6050
  if (!mpu.begin()) {

    Serial.println(
        "MPU6050 not found"
    );

    while (1) {
      delay(1000);
    }
  }

  // BME280
  if (!bme.begin(0x76)) {

    Serial.println(
        "BME280 not found"
    );

    while (1) {
      delay(1000);
    }
  }

  // GPS
  GPSSerial.begin(
      9600,
      SERIAL_8N1,
      GPS_RX,
      GPS_TX
  );

  // Wi-Fi
  WiFi.begin(
      WIFI_SSID,
      WIFI_PASSWORD
  );

  Serial.print(
      "Connecting to Wi-Fi"
  );

  while (
      WiFi.status() != WL_CONNECTED
  ) {

    delay(500);

    Serial.print(".");
  }

  Serial.println();

  Serial.println(
      "Wi-Fi connected"
  );

  digitalWrite(
      GREEN_LED_PIN,
      HIGH
  );
}

// -----------------------------
// Main loop
// -----------------------------
void loop() {

  // Read GPS continuously
  while (GPSSerial.available()) {

    gps.encode(
        GPSSerial.read()
    );
  }

  if (
      millis() - lastSend
      >= SEND_INTERVAL
  ) {

    lastSend = millis();

    sendToN8N();
  }

  delay(10);
}

28. Important Improvement to the ESP32 Code

The MQ values in the example are intentionally named:

methane_raw
co_raw

rather than:

methane_ppm
co_ppm

because a raw ESP32 ADC value is not automatically a gas concentration in ppm.

For a serious prototype, you need:

Sensor calibration
        ↓
ADC voltage
        ↓
Sensor resistance
        ↓
Calibration curve
        ↓
Estimated concentration

And for a real mine:

Certified sensor
+
Certified electronics
+
Calibration procedure
+
Safety certification

29. Better Accident-Prediction Algorithm

The next version should not depend solely on fixed thresholds.

Collect historical data:

Timestamp
Acceleration
Gyroscope
Gas
Temperature
Humidity
Worker activity
Fall event
SOS
Outcome

Then construct a dataset:

                  INPUT
                     │
      ┌──────────────┼──────────────┐
      │              │              │
      ▼              ▼              ▼
    Gas          Motion        Environment
      │              │              │
      └──────────────┼──────────────┘
                     ▼
                ML MODEL
                     │
                     ▼
              Accident Risk
                0–100%

Possible models:

Logistic Regression
Random Forest
XGBoost
SVM
LSTM
1D CNN
Isolation Forest

For a student project, I recommend beginning with:

Random Forest + anomaly detection

rather than immediately implementing an LSTM.


30. Two-Level AI Architecture

A stronger design is:

                 ESP32
                   │
                   ▼
          Immediate Safety Logic
                   │
       ┌───────────┴────────────┐
       │                        │
       ▼                        ▼
   Local Alarm             n8n Cloud
                                │
                                ▼
                           AI Agent
                                │
                                ▼
                        Historical Context
                                │
                                ▼
                         Risk Assessment

This is important because the ESP32 should not have to wait for:

Wi-Fi
   ↓
Internet
   ↓
n8n
   ↓
AI model
   ↓
response

before sounding a local emergency alarm.


31. IoT Web Dashboard

The web dashboard can show:

┌───────────────────────────────────────────┐
│       AI MINING HELMET MONITOR            │
├───────────────────────────────────────────┤
│                                           │
│ Helmet: H001          Status: 🟢 NORMAL   │
│                                           │
│ Temperature       32.4 °C                 │
│ Humidity          67.2 %                  │
│ Methane           415                     │
│ CO                 82                     │
│ Battery            3.91 V                │
│ Risk               23 / 100               │
│                                           │
├───────────────────────────────────────────┤
│             SENSOR GRAPHS                 │
│                                           │
│ Temperature  ─────────╮                  │
│                       ╰──────            │
│ Methane      ────╮                       │
│                  ╰────────               │
│                                           │
├───────────────────────────────────────────┤
│ AI STATUS                                 │
│ NORMAL                                    │
│ No abnormal event detected.              │
└───────────────────────────────────────────┘

32. Example Webpage

For a public ThingSpeak channel, the dashboard can read the channel's JSON feed.

<!DOCTYPE html>
<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport"
      content="width=device-width, initial-scale=1.0">

<title>AI Mining Helmet Dashboard</title>

<style>

body {
    margin: 0;
    font-family: Arial, sans-serif;
    background: #101820;
    color: white;
}

header {
    background: #182b3a;
    padding: 20px;
    text-align: center;
}

.dashboard {
    display: grid;
    grid-template-columns:
        repeat(auto-fit, minmax(200px, 1fr));

    gap: 20px;
    padding: 25px;
}

.card {
    background: #1d303f;
    padding: 20px;
    border-radius: 15px;
    box-shadow: 0 5px 20px #0005;
}

.value {
    font-size: 32px;
    font-weight: bold;
}

.normal {
    color: #00ff88;
}

.warning {
    color: #ffcc00;
}

.critical {
    color: #ff3333;
}

canvas {
    max-width: 100%;
}

</style>

</head>

<body>

<header>

<h1>⛑ AI Mining Helmet</h1>

<p>ESP32 + n8n + AI Agent + ThingSpeak</p>

</header>

<div class="dashboard">

<div class="card">

<h3>Temperature</h3>

<div id="temperature"
     class="value">--</div>

</div>

<div class="card">

<h3>Humidity</h3>

<div id="humidity"
     class="value">--</div>

</div>

<div class="card">

<h3>Methane</h3>

<div id="methane"
     class="value">--</div>

</div>

<div class="card">

<h3>CO</h3>

<div id="co"
     class="value">--</div>

</div>

<div class="card">

<h3>Risk Score</h3>

<div id="risk"
     class="value">--</div>

</div>

<div class="card">

<h3>System Status</h3>

<div id="status"
     class="value normal">

NORMAL

</div>

</div>

</div>

<script>

const CHANNEL_ID = "YOUR_CHANNEL_ID";

async function updateDashboard() {

    const url =
        `https://api.thingspeak.com/channels/` +
        `${CHANNEL_ID}/feeds.json?results=1`;

    try {

        const response =
            await fetch(url);

        const data =
            await response.json();

        const feed =
            data.feeds[0];

        document.getElementById(
            "temperature"
        ).textContent =
            feed.field1 ?? "--";

        document.getElementById(
            "humidity"
        ).textContent =
            feed.field2 ?? "--";

        document.getElementById(
            "methane"
        ).textContent =
            feed.field3 ?? "--";

        document.getElementById(
            "co"
        ).textContent =
            feed.field4 ?? "--";

        const risk =
            Number(feed.field6 || 0);

        document.getElementById(
            "risk"
        ).textContent =
            risk + " / 100";

        const status =
            document.getElementById(
                "status"
            );

        if (risk >= 80) {

            status.textContent =
                "CRITICAL";

            status.className =
                "value critical";

        } else if (risk >= 40) {

            status.textContent =
                "WARNING";

            status.className =
                "value warning";

        } else {

            status.textContent =
                "NORMAL";

            status.className =
                "value normal";
        }

    } catch (error) {

        console.error(error);

    }
}

updateDashboard();

setInterval(
    updateDashboard,
    15000
);

</script>

</body>

</html>

33. Dashboard Data Flow

ESP32
  │
  ▼
n8n
  │
  ├───────────────► Google Sheets
  │
  └───────────────► ThingSpeak
                          │
                          ▼
                    Web Dashboard
                          │
                          ▼
                    Supervisor

34. Google Sheets Data Flow

ESP32
  │
  ▼
n8n Webhook
  │
  ▼
Data validation
  │
  ▼
Google Sheets node
  │
  ▼
Spreadsheet

Example spreadsheet:

+----------+------+-------+------+-----+------+------+
| Time     | ID   | Temp  | CH4  | CO  | Fall | Risk |
+----------+------+-------+------+-----+------+------+
| 10:00:01 | H001 | 31.2  | 320  | 60  | No   | 12   |
| 10:00:06 | H001 | 31.4  | 340  | 65  | No   | 16   |
| 10:00:11 | H001 | 32.0  | 410  | 72  | No   | 28   |
| 10:00:16 | H001 | 33.1  | 580  | 103 | Yes  | 86   |
+----------+------+-------+------+-----+------+------+

35. Complete n8n Automation

A practical workflow can contain:

01 Webhook
      ↓
02 Code / Validate JSON
      ↓
03 Set Helmet ID
      ↓
04 Google Sheets — Log raw data
      ↓
05 HTTP Request — ThingSpeak
      ↓
06 AI Agent
      ↓
07 Structured Output Parser
      ↓
08 Switch Risk Level
      │
      ├── NORMAL
      │      ↓
      │   Log only
      │
      ├── WARNING
      │      ↓
      │   Telegram message
      │
      ├── HIGH
      │      ↓
      │   Telegram message
      │      ↓
      │   Google Sheets event log
      │
      └── CRITICAL
             ↓
          Telegram message
             ↓
          TTS API
             ↓
          Telegram Voice
             ↓
          Google Sheets
             ↓
          Supervisor

36. Agentic IoT Concept

The important difference between ordinary IoT and agentic IoT is that the cloud system can interpret the data and select actions.

Conventional IoT

Sensor
  ↓
Cloud
  ↓
Dashboard

Agentic IoT

Sensor
  ↓
Cloud
  ↓
AI Agent
  ↓
Understand
  ↓
Reason
  ↓
Choose action
  ↓
Execute action
  ↓
Verify/log result

For this project:

ESP32
 ↓
"CH4 increasing + impact + inactivity"
 ↓
AI Agent
 ↓
"Possible serious event"
 ↓
Telegram text
 ↓
TTS
 ↓
Telegram voice
 ↓
Google Sheets event record

37. Example Emergency Scenario

Suppose the worker is operating underground.

At:

10:20:01

the system measures:

Methane = normal
Acceleration = 1.02 g
Temperature = 31°C

Risk:

12/100

At:

10:20:06

methane begins increasing.

Methane = 410

Risk:

28/100

At:

10:20:11

the helmet detects:

Acceleration = 5.9 g

The ESP32 locally identifies a possible impact.

At:

10:20:16

the worker remains nearly motionless.

The ESP32 sends:

{
  "helmet_id": "H001",
  "methane": 580,
  "co": 103,
  "acceleration": 5.9,
  "fall": true,
  "sos": false,
  "temperature": 33.1
}

n8n receives it.

The AI Agent evaluates:

Gas increasing
+
High acceleration
+
Possible fall
+
Abnormal motion

and returns:

CRITICAL
Risk = 86

Then:

                 CRITICAL
                     │
          ┌──────────┴──────────┐
          ▼                     ▼
     Telegram text         Voice generation
                                  │
                                  ▼
                           Telegram voice

Supervisor receives:

🚨 CRITICAL ALERT

Helmet H001

Possible worker fall detected.

Elevated hazardous gas readings
were also detected.

Risk: 86/100.

Check worker immediately.

38. Local Emergency Path

The most important safety architecture is:

                   SENSOR
                     │
                     ▼
                  ESP32
                     │
          ┌──────────┴───────────┐
          │                      │
          ▼                      ▼
     LOCAL ALARM              INTERNET
          │                      │
          ▼                      ▼
       Worker                  n8n
                                 │
                                 ▼
                              AI Agent
                                 │
                                 ▼
                            Supervisor

Even if:

Wi-Fi fails

the local alarm can still operate.


39. Offline Mode

Mining environments may have unreliable connectivity.

Therefore implement:

Wi-Fi connected?
       │
   ┌───┴────┐
  YES       NO
   │         │
   ▼         ▼
n8n       Local alarm
   │         │
   ▼         ▼
Cloud     SD/Flash buffer

When Wi-Fi returns:

Stored records
      ↓
Upload old data
      ↓
Cloud

An optional microSD module can be added for local event storage.


40. Watchdog

The firmware should include a watchdog.

ESP32 running
     │
     ▼
Sensor loop
     │
     ▼
Communication
     │
     ▼
Watchdog reset if firmware hangs

This is important for long-duration operation.


41. Heartbeat

Send a heartbeat packet every few seconds:

{
  "helmet_id": "H001",
  "device_status": "ONLINE",
  "battery": 3.91,
  "firmware": "1.0.0",
  "timestamp": "..."
}

n8n can detect:

No heartbeat for 30 seconds
        ↓
DEVICE OFFLINE
        ↓
Supervisor notification

42. Battery Monitoring

Use a voltage divider:

Battery +
   │
 100k
   │
   ├──────── ESP32 ADC
   │
 100k
   │
  GND

For example:

Battery = 4.2 V
ADC ≈ 2.1 V

The actual divider and ADC calibration must be designed for the selected ESP32 variant and battery.


43. SOS Button

The SOS button should be treated as a high-priority event.

Worker presses SOS
       ↓
ESP32
       ↓
Local buzzer
       ↓
JSON event
       ↓
n8n
       ↓
Bypass normal AI delay
       ↓
Telegram emergency
       ↓
Voice alert

A good architecture is to have n8n immediately route:

SOS = TRUE

to the emergency branch.

Do not make an LLM decide whether an explicitly pressed emergency button constitutes an emergency.


44. Security

Do not hard-code sensitive credentials into public source code.

Bad:

const char* PASSWORD = "myPassword123";

for code that will be uploaded to GitHub.

Use:

Environment variables
Secret manager
n8n credentials
Secure provisioning

At minimum:

ESP32
   │
 HTTPS
   │
   ▼
n8n

and authenticate the webhook with a secret/token.


45. Recommended Webhook Security

Instead of:

POST /webhook/mining-helmet

use a secret header:

X-Helmet-Key: YOUR_SECRET

n8n checks:

Header correct?
   │
 ┌─┴──┐
YES   NO
 │     │
 ▼     ▼
Process Reject

46. MQTT Alternative

For a larger deployment, consider MQTT:

ESP32
  ↓
MQTT
  ↓
MQTT Broker
  ↓
n8n

Topics:

mine/helmet/H001/sensors
mine/helmet/H001/status
mine/helmet/H001/alert
mine/helmet/H001/command

This is more scalable than sending independent HTTP requests when many helmets are involved.

For the first prototype, however:

ESP32 → HTTP → n8n

is simpler.


47. Multi-Helmet Architecture

For 100 workers:

Helmet H001 ─┐
Helmet H002 ─┤
Helmet H003 ─┤
Helmet H004 ─┤
Helmet H005 ─┤
             │
             ▼
        MQTT / HTTP
             │
             ▼
            n8n
             │
      ┌──────┼──────┐
      ▼      ▼      ▼
   Database Sheets ThingSpeak
      │
      ▼
    AI Agent
      │
      ▼
 Supervisor Dashboard

Each helmet must have a unique:

helmet_id

48. AI Risk Dashboard

The dashboard should display:

┌─────────────────────────────────────────┐
│             MINE CONTROL ROOM           │
├─────────────────────────────────────────┤
│                                         │
│ H001  🟢 NORMAL       Risk: 18          │
│ H002  🟡 WARNING      Risk: 52          │
│ H003  🔴 CRITICAL     Risk: 91          │
│ H004  🟢 NORMAL       Risk: 12          │
│ H005  🟠 HIGH         Risk: 72          │
│                                         │
└─────────────────────────────────────────┘

Selecting H003:

Helmet H003

Temperature: 34.2°C
Humidity: 71%
Methane: HIGH
CO: HIGH
Acceleration: abnormal
Fall: POSSIBLE

AI Risk: 91/100

Recommendation:
Immediate worker verification.

49. Project Software Stack

┌──────────────────────────────────┐
│             FRONTEND              │
│ HTML + CSS + JavaScript          │
└────────────────┬─────────────────┘
                 │
                 ▼
┌──────────────────────────────────┐
│          CLOUD DASHBOARD          │
│          ThingSpeak               │
└────────────────┬─────────────────┘
                 │
                 │
┌────────────────▼─────────────────┐
│               n8n                 │
│                                  │
│ Webhook                          │
│ Data processing                  │
│ AI Agent                         │
│ Google Sheets                    │
│ Telegram                         │
│ TTS                              │
└────────────────┬─────────────────┘
                 │
                 ▼
┌──────────────────────────────────┐
│              ESP32               │
│                                  │
│ Sensors                          │
│ Local safety logic               │
│ Wi-Fi                            │
│ JSON                             │
└──────────────────────────────────┘

50. Development Procedure

Phase 1 — ESP32 setup

Install:

Arduino IDE
ESP32 board package
Required libraries

Espressif provides official Arduino-ESP32 setup documentation.

Test:

Blink LED
 ↓
Wi-Fi
 ↓
Serial monitor

Phase 2 — MPU6050

Test:

Acceleration X
Acceleration Y
Acceleration Z
Gyroscope X
Gyroscope Y
Gyroscope Z

Verify that the helmet reports approximately:

1 g

when stationary due to gravity.


Phase 3 — BME280

Display:

Temperature
Humidity
Pressure

Phase 4 — Gas sensors

Allow the sensors to warm up according to their datasheets.

Then:

Raw ADC
 ↓
Calibration
 ↓
Baseline
 ↓
Abnormal detection

Do not use arbitrary raw ADC thresholds as certified gas limits.


Phase 5 — Fall detection

Collect data for:

Walking
Running
Sitting
Bending
Helmet movement
Safe controlled impact simulation

Then tune:

impact threshold
inactivity period
orientation threshold

Never test dangerous falls on people.


51. Phase 6 — n8n

Build:

Webhook
 ↓
JSON
 ↓
Google Sheets

First confirm that the data reaches the spreadsheet.

Then add:

ThingSpeak

Then:

AI Agent

Then:

Telegram

Finally:

TTS + Telegram Voice

This staged approach makes debugging much easier.


52. Phase 7 — AI

Start with a rule-based model:

Risk = rule engine

Then add AI:

Rule engine
+
AI interpretation

Finally, when enough labeled data exists:

Machine-learning model
+
AI Agent

This is much better than immediately asking an LLM to "predict accidents" from arbitrary sensor values.


53. Testing Matrix

Test Expected result
ESP32 boot Device starts
Wi-Fi Connected
BME280 Valid readings
MPU6050 Valid readings
MQ sensors ADC values change
SOS Immediate local alarm
Impact simulation Possible fall
n8n webhook JSON received
Google Sheets Row inserted
ThingSpeak Chart updated
AI Agent JSON risk result
Telegram Text alert
TTS Audio generated
Telegram voice Voice received
Wi-Fi failure Local safety logic continues
Device restart Firmware recovers

54. Example Test Case

Test 1 — Normal operation

Input:

Temperature = 30°C
Gas = normal
Acceleration = 1.0g
Fall = false
SOS = false

Expected:

Risk = LOW
No emergency alert
Dashboard = GREEN

Test 2 — Gas warning

Gas = increasing
Temperature = normal
Motion = normal

Expected:

Risk = WARNING
Telegram text alert

Test 3 — Possible fall

Acceleration = 5g+
Fall = true
Inactivity = true

Expected:

Risk = HIGH/CRITICAL
Local alarm
Telegram
Voice alert

Test 4 — SOS

SOS = true

Expected:

Immediate local alarm
Immediate Telegram alert
Voice alert
Event stored

55. Project Folder Structure

AI-Mining-Helmet/
│
├── firmware/
│   ├── mining_helmet.ino
│   ├── config.h
│   ├── sensors.cpp
│   ├── sensors.h
│   ├── fall_detection.cpp
│   └── fall_detection.h
│
├── n8n/
│   ├── workflow-design.md
│   ├── ai-prompt.txt
│   └── sample-payload.json
│
├── dashboard/
│   ├── index.html
│   ├── style.css
│   └── dashboard.js
│
├── documentation/
│   ├── project-report.md
│   ├── architecture.md
│   ├── testing.md
│   └── calibration.md
│
└── README.md

56. Final System Flow Diagram

                         ┌─────────────────┐
                         │     WORKER      │
                         │   MINING HELMET │
                         └────────┬────────┘
                                  │
                                  ▼
                    ┌────────────────────────┐
                    │         ESP32          │
                    │                        │
                    │ Temp/Humidity          │
                    │ Gas                   │
                    │ Accelerometer         │
                    │ Gyroscope             │
                    │ GPS                   │
                    │ Battery               │
                    │ SOS                   │
                    └───────────┬────────────┘
                                │
                    Local safety│logic
                                │
                    ┌───────────┴────────────┐
                    │                        │
                    ▼                        ▼
              Local Alarm                 Wi-Fi
                                             │
                                             ▼
                                    ┌─────────────────┐
                                    │      n8n        │
                                    │                 │
                                    │ Webhook         │
                                    │ Automation      │
                                    │ AI Agent        │
                                    └───────┬─────────┘
                                            │
                ┌───────────────────────────┼─────────────────────┐
                │                           │                     │
                ▼                           ▼                     ▼
        ┌──────────────┐            ┌─────────────┐       ┌─────────────┐
        │Google Sheets │            │ ThingSpeak  │       │ AI Decision │
        │              │            │             │       │             │
        │Historical    │            │ Dashboard   │       │ Risk Score  │
        │Data          │            │ Graphs      │       │             │
        └──────────────┘            └─────────────┘       └──────┬──────┘
                                                                  │
                                                   ┌──────────────┼───────────┐
                                                   │              │           │
                                                   ▼              ▼           ▼
                                                NORMAL         WARNING     CRITICAL
                                                   │              │           │
                                                   │              ▼           ▼
                                                   │           Telegram    Telegram
                                                   │                         │
                                                   │                         ▼
                                                   │                    TTS Engine
                                                   │                         │
                                                   │                         ▼
                                                   │                  Telegram Voice
                                                   │                         │
                                                   └─────────────┬───────────┘
                                                                 ▼
                                                          ┌──────────────┐
                                                          │ SUPERVISOR   │
                                                          │ PHONE / PC   │
                                                          └──────────────┘

57. Final Project Workflow in One Sentence

ESP32 sensors continuously monitor the miner and environment → ESP32 performs immediate local safety detection → data is sent to n8n → n8n stores it in Google Sheets and ThingSpeak → an AI Agent analyzes the current state and history → risk is classified → n8n automatically sends Telegram text and, for serious events, a Telegram voice alert → the supervisor monitors the situation through the web/cloud dashboard.


58. Recommended Final-Year Project Features

To make this a strong academic/engineering project, implement the following in stages:

  1. ESP32 sensor acquisition
  2. MPU6050 fall/impact detection
  3. Gas/environment monitoring
  4. SOS emergency button
  5. Local buzzer + vibration alarm
  6. Wi-Fi JSON communication
  7. n8n webhook
  8. Google Sheets logging
  9. ThingSpeak cloud dashboard
  10. n8n AI Agent
  11. Risk-score engine
  12. Telegram text notifications
  13. TTS-generated Telegram voice notifications
  14. Browser dashboard
  15. Offline data buffering
  16. Device heartbeat
  17. Battery monitoring
  18. Historical-data-based ML model
  19. Multi-helmet support
  20. Security/authentication

The ESP32 platform has the necessary networking/peripheral capabilities for this prototype, while n8n's Telegram integration and Telegram's Bot API provide the automation/notification path.

For the next engineering iteration, the most valuable upgrade is to replace the illustrative gas thresholds with calibrated sensor measurements and validated alarm limits, and replace the initial rule-based "accident prediction" with a model trained on experimentally collected and labeled helmet-motion/environment data.

No comments:

Post a Comment