AI Battery State-of-Charge Estimation & Agentic IoT System
Below is a complete reference design for an ESP32-based AI Battery State-of-Charge (SOC) monitoring system integrating:
-
ESP32
-
Battery voltage/current/temperature sensing
-
SOC estimation
-
Optional AI/ML SOC correction
-
Local ESP32 IoT webpage
-
n8n automation
-
n8n AI Agent
-
Telegram text + voice alerts
-
Google Sheets data logging
-
ThingSpeak cloud dashboard
-
Fault/anomaly detection
-
Historical analysis
-
Remote monitoring
The architecture is deliberately designed so that the ESP32 remains capable of measuring and estimating SOC locally, while n8n acts as the cloud automation and AI-agent layer.
n8n is suitable for this because it provides workflow automation, integrations and AI functionality. n8n Documentation
1. Project Title
AI-Powered Battery State-of-Charge Estimation and Agentic IoT Monitoring System Using ESP32, n8n, Telegram Voice Alerts, Google Sheets and ThingSpeak
2. Abstract
This project implements an intelligent battery-monitoring system using an ESP32 microcontroller.
The ESP32 continuously measures:
-
Battery voltage
-
Battery current
-
Battery temperature
-
Estimated State of Charge (SOC)
-
Charging/discharging status
-
Battery power
-
Energy consumed
-
Energy returned during charging
The measurements are processed locally by the ESP32 using a hybrid SOC estimation algorithm based on:
-
Battery voltage
-
Coulomb counting
-
Battery current
-
Temperature compensation
-
Optional AI/ML correction
The ESP32 publishes the measurements through Wi-Fi to an n8n automation server.
n8n acts as the central Agentic IoT orchestration layer.
The n8n workflow can:
-
Receive ESP32 measurements
-
Validate sensor data
-
Calculate additional battery parameters
-
Store measurements in Google Sheets
-
Update ThingSpeak
-
Send Telegram notifications
-
Generate Telegram voice alerts
-
Invoke an AI Agent
-
Detect abnormal battery behavior
-
Explain the reason for an alert
-
Recommend an action
-
Maintain alert history
-
Respond to Telegram commands
The result is an end-to-end IoT architecture:
Battery → Sensors → ESP32 → Wi-Fi → n8n → AI Agent → Cloud/Telegram/Dashboard
3. Main Objectives
The system has the following objectives.
Primary objectives
-
Measure battery voltage accurately.
-
Measure charge/discharge current.
-
Measure battery temperature.
-
Estimate battery SOC.
-
Display real-time battery information.
-
Store historical measurements.
-
Detect abnormal battery conditions.
-
Automatically notify the user.
-
Provide voice alerts.
-
Provide cloud visualization.
-
Use an AI Agent for intelligent interpretation.
Secondary objectives
The system can also:
-
Estimate remaining energy.
-
Detect unusually high current.
-
Detect rapid SOC loss.
-
Detect overheating.
-
Detect sensor failures.
-
Detect battery disconnection.
-
Detect charging problems.
-
Generate maintenance recommendations.
4. Important Design Principle
The AI Agent should not be the only source of battery safety decisions.
A robust architecture is:
┌──────────────────────────────┐
│ HARD REAL-TIME LAYER │
│ │
Battery ────────►│ ESP32 + Sensors │
│ │
│ Voltage │
│ Current │
│ Temperature │
│ SOC estimator │
│ Safety thresholds │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ CLOUD/AI LAYER │
│ │
│ n8n │
│ AI Agent │
│ Historical analysis │
│ Recommendations │
└──────────────┬───────────────┘
│
┌─────────────────┼──────────────────┐
▼ ▼ ▼
Telegram Google Sheets ThingSpeak
Text/Voice Data Logging Dashboard
The ESP32 should therefore continue to protect the system using deterministic thresholds even if:
5. Recommended Battery Configuration
For the reference implementation, use:
4S Li-ion battery pack
Nominal voltage:
4 × 3.7 V = 14.8 V
Typical voltage range:
Fully charged ≈ 16.8 V
Nominal ≈ 14.8 V
Discharged region ≈ 12 V
Use a proper 4S BMS.
Do not connect an unprotected lithium battery pack to the experimental circuit.
The same architecture can be adapted for:
However, the voltage/SOC lookup curve must be changed according to the chemistry.
6. System Block Diagram
BATTERY PACK
┌────────────────────┐
│ │
│ 4S Li-ion + BMS │
│ │
└───────┬───────┬────┘
│ │
│ │
Voltage Current
Sensor Sensor
│ │
▼ ▼
┌─────────────────────┐
│ ESP32 │
│ │
│ ADC │
│ INA219/INA226 │
│ DS18B20 │
│ │
│ SOC Algorithm │
│ Energy Calculation │
│ Fault Detection │
└──────────┬──────────┘
│
Wi-Fi
│
▼
┌─────────────────────┐
│ n8n │
│ │
│ Webhook │
│ Validation │
│ AI Agent │
│ Rules Engine │
│ Automation │
└─────┬──────┬────────┘
│ │
┌───────────┘ └─────────────┐
▼ ▼
Google Sheets ThingSpeak
Historical Data Cloud Charts
│
▼
AI Analysis
│
▼
Telegram Bot
┌──────────────┐
│ Text Alert │
│ Voice Alert │
└──────────────┘
7. Hardware Architecture
7.1 Main components
Recommended components:
| Component |
Purpose |
| ESP32 DevKit |
Main controller |
| INA219 or INA226 |
Current/voltage monitoring |
| Voltage divider |
Battery voltage measurement |
| DS18B20 |
Battery temperature |
| 4S BMS |
Battery protection |
| 12 V/5 V buck converter |
ESP32 power |
| Battery |
Device under test |
| Resistors |
Voltage divider |
| Capacitors |
ADC filtering |
| LEDs |
Local status |
| Push button |
Optional reset/configuration |
| OLED |
Optional local display |
8. Recommended Sensor Arrangement
A practical arrangement is:
Battery +
│
│
▼
BMS
│
│
├──────────────► Voltage measurement
│
▼
INA219 / INA226
│
│
▼
Load +
Temperature sensor:
DS18B20
│
└──── attached thermally to battery pack
ESP32:
┌──────────────────┐
Voltage ────►│ │
Current ────►│ ESP32 │──── Wi-Fi
Temperature ►│ │
└──────────────────┘
9. Schematic Diagram
A simplified electrical schematic is:
4S BATTERY
┌───────────────┐
│ │
BAT+ ───────────┤ + - ├───────────────┐
│ │ │
└───────────────┘ │
│ │
│ │
▼ │
┌─────────┐ │
│ 4S BMS │ │
└────┬────┘ │
│ │
PACK+ │ │ PACK-
│ │
▼ │
INA219/226 │
┌────────────┐ │
│ │ │
│ VIN+ VIN- │ │
│ │ │
└─────┬──────┘ │
│ │
▼ │
LOAD+ │
│
LOAD- ──────────────────────┘
INA219/226
│
├── VCC ───── ESP32 3.3 V
├── GND ───── ESP32 GND
├── SDA ───── GPIO 21
└── SCL ───── GPIO 22
Battery voltage divider:
Battery +
│
│
R1
│
├──────────── GPIO34 / ADC
│
R2
│
GND
DS18B20:
ESP32 GPIO 4 ───── DATA
│
4.7k
│
3.3V
DS18B20:
VCC ─────────────── 3.3V
GND ─────────────── GND
DATA ────────────── GPIO4
10. Voltage Divider Calculation
ESP32 ADC input must remain within the allowed ADC range.
For a maximum battery voltage of approximately:
Vbattery(max) = 16.8 V
A suitable divider is:
R1 = 100 kΩ
R2 = 22 kΩ
Output voltage:
Vadc = Vbattery × R2 / (R1 + R2)
Therefore:
Vadc = 16.8 × 22 / 122
approximately:
Vadc ≈ 3.03 V
This provides reasonable headroom for a 3.3 V ADC system.
For production hardware, verify the actual ESP32 ADC characteristics and calibrate the divider using a precision multimeter.
11. Current Measurement
INA219/INA226 can be used for current monitoring.
Example:
Battery → Current Sensor → Load
The sensor measures:
Voltage
Current
Power
Power is:
P = V × I
For example:
V = 15.2 V
I = 2.0 A
P = 15.2 × 2
P = 30.4 W
12. Temperature Measurement
Use a DS18B20 temperature sensor.
The temperature is important because battery behavior depends strongly on temperature.
The ESP32 records:
temperature = 31.5 °C
The AI layer can detect:
Temperature increasing rapidly
rather than only:
Temperature > fixed limit
That makes the system more intelligent.
13. What Is SOC?
SOC means:
State of Charge
It represents the estimated remaining usable battery capacity.
For example:
SOC = 100 %
means approximately full.
SOC = 50 %
means approximately half of the usable capacity remains.
SOC = 10 %
means the battery is nearly depleted.
SOC is an estimate, not a direct physical measurement.
14. SOC Estimation Methods
Three methods are useful.
Method 1 — Voltage-based SOC
The battery voltage is mapped to a SOC curve.
Example:
Voltage SOC
16.8 V 100 %
16.4 V 90 %
16.0 V 80 %
15.6 V 65 %
15.2 V 50 %
14.8 V 35 %
14.4 V 20 %
13.2 V 10 %
12.0 V 0 %
These numbers are illustrative only and must be replaced with a curve appropriate to the actual battery.
Voltage-only SOC is simple but inaccurate when the battery is under load.
15. Coulomb Counting
Coulomb counting tracks current over time.
The basic equation is:
SOCnew = SOCold - I × Δt / Capacity
where:
I = battery current
Δt = elapsed time
Capacity = battery capacity in Ah
For a 10 Ah battery:
I = 2 A
Δt = 1 hour
Consumed capacity = 2 Ah
SOC decrease = 2 / 10 × 100
SOC decrease = 20 %
Coulomb counting provides good short-term tracking but accumulates error over time.
16. Hybrid SOC Algorithm
The recommended algorithm combines:
Voltage
+
Current
+
Temperature
+
Coulomb counting
Conceptually:
Voltage
│
▼
┌───────────────┐
Current ─► Coulomb │
│ Counter │
└───────┬───────┘
│
Temperature ───►│
│
▼
┌────────────────┐
│ Hybrid SOC │
│ Estimator │
└───────┬────────┘
│
▼
SOC %
17. AI Enhancement
The AI Agent should not simply receive:
SOC = 32 %
and guess.
Instead, provide it with a structured observation:
{
"battery_voltage": 14.82,
"battery_current": 3.42,
"temperature": 36.8,
"soc": 31.7,
"power": 50.7,
"charging": false,
"soc_change_5min": -4.2,
"temperature_change_5min": 3.5,
"device": "BATTERY-01"
}
The AI Agent can then reason about:
18. AI Agent Role
The AI Agent can receive battery telemetry and produce:
{
"severity": "WARNING",
"alert": true,
"reason": "Battery SOC is falling rapidly while current remains high.",
"recommendation": "Reduce the load and inspect the battery.",
"voice_message": "Warning. Battery charge is falling rapidly. Please reduce the load."
}
The AI Agent is therefore an interpretation and orchestration layer, not the primary electrical protection mechanism.
19. Complete Data Flow
┌───────────┐
│ Battery │
└─────┬─────┘
│
▼
┌───────────────────────┐
│ Voltage/current/temp │
│ Sensors │
└──────────┬────────────┘
│
▼
┌───────────────────────┐
│ ESP32 │
│ │
│ Sensor acquisition │
│ Filtering │
│ SOC calculation │
│ Energy calculation │
│ Local safety rules │
└──────────┬────────────┘
│ JSON/HTTPS
▼
┌───────────────────────┐
│ n8n Webhook │
└──────────┬────────────┘
│
▼
┌───────────────────────┐
│ Data validation │
└──────────┬────────────┘
│
├───────────────► Google Sheets
│
├───────────────► ThingSpeak
│
▼
┌───────────────────────┐
│ AI Agent │
│ │
│ Analyze telemetry │
│ Detect anomalies │
│ Classify severity │
│ Recommend action │
└──────────┬────────────┘
│
▼
┌────┴─────┐
│ Alert? │
└────┬─────┘
│
YES │
▼
┌───────────────────────┐
│ Telegram │
│ │
│ Text alert │
│ Voice alert │
└───────────────────────┘
20. ESP32 Software Architecture
The ESP32 firmware contains these modules:
main.cpp
│
├── Wi-Fi Manager
│
├── Battery Sensor
│ ├── INA219/INA226
│ ├── Voltage ADC
│ └── DS18B20
│
├── SOC Estimator
│
├── Energy Counter
│
├── Fault Detector
│
├── HTTP Client
│
└── Local Web Server
21. ESP32 JSON Telemetry
The ESP32 sends:
{
"device_id": "BATTERY-01",
"voltage": 15.72,
"current": 2.31,
"temperature": 32.4,
"soc": 72.5,
"power": 36.31,
"energy_wh": 142.6,
"charging": false,
"wifi_rssi": -57,
"uptime": 8421
}
22. ESP32 Arduino Code
Install these Arduino libraries:
WiFi
WebServer
HTTPClient
ArduinoJson
Wire
Adafruit INA219
OneWire
DallasTemperature
Example firmware:
#include <WiFi.h>
#include <WebServer.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <Adafruit_INA219.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// --------------------------------------------------
// Wi-Fi
// --------------------------------------------------
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASSWORD = "YOUR_PASSWORD";
// n8n webhook
const char* N8N_URL =
"https://YOUR_N8N_DOMAIN/webhook/battery";
// --------------------------------------------------
// Pins
// --------------------------------------------------
#define BATTERY_ADC_PIN 34
#define TEMP_PIN 4
// Voltage divider
const float R1 = 100000.0;
const float R2 = 22000.0;
// Battery capacity
const float BATTERY_CAPACITY_AH = 10.0;
// --------------------------------------------------
// Objects
// --------------------------------------------------
WebServer server(80);
Adafruit_INA219 ina219;
OneWire oneWire(TEMP_PIN);
DallasTemperature tempSensor(&oneWire);
// --------------------------------------------------
// Battery state
// --------------------------------------------------
float batteryVoltage = 0.0;
float batteryCurrent = 0.0;
float batteryTemperature = 0.0;
float batteryPower = 0.0;
float soc = 100.0;
float energyWh = 0.0;
unsigned long lastMeasurement = 0;
unsigned long lastUpload = 0;
// --------------------------------------------------
// Read battery voltage
// --------------------------------------------------
float readBatteryVoltage()
{
int raw = analogRead(BATTERY_ADC_PIN);
float adcVoltage =
((float)raw / 4095.0) * 3.3;
float battery =
adcVoltage * (R1 + R2) / R2;
return battery;
}
// --------------------------------------------------
// Voltage based SOC
// --------------------------------------------------
float voltageSOC(float voltage)
{
// Example curve for demonstration.
// Replace with experimentally measured
// curve for your battery.
if (voltage >= 16.8) return 100.0;
if (voltage >= 16.4) return 90.0;
if (voltage >= 16.0) return 80.0;
if (voltage >= 15.6) return 65.0;
if (voltage >= 15.2) return 50.0;
if (voltage >= 14.8) return 35.0;
if (voltage >= 14.4) return 20.0;
if (voltage >= 13.2) return 10.0;
return 0.0;
}
// --------------------------------------------------
// Hybrid SOC
// --------------------------------------------------
float calculateSOC(float voltage,
float current,
float dtHours)
{
// Coulomb counting
float deltaSOC =
(current * dtHours /
BATTERY_CAPACITY_AH) * 100.0;
// Positive current = discharge
soc -= deltaSOC;
soc = constrain(soc, 0.0, 100.0);
// Voltage correction.
//
// Stronger correction when current is low,
// because loaded battery voltage is less
// representative of open-circuit voltage.
if (fabs(current) < 0.3)
{
float voltageSOCValue =
voltageSOC(voltage);
soc =
0.85 * soc +
0.15 * voltageSOCValue;
}
return soc;
}
// --------------------------------------------------
// Read sensors
// --------------------------------------------------
void readSensors()
{
batteryVoltage =
readBatteryVoltage();
batteryCurrent =
ina219.getCurrent_mA() / 1000.0;
batteryPower =
batteryVoltage *
batteryCurrent;
tempSensor.requestTemperatures();
batteryTemperature =
tempSensor.getTempCByIndex(0);
}
// --------------------------------------------------
// Local fault detection
// --------------------------------------------------
String detectFault()
{
if (batteryTemperature >= 55.0)
return "OVER_TEMPERATURE";
if (batteryVoltage < 12.0)
return "LOW_VOLTAGE";
if (batteryCurrent > 10.0)
return "OVER_CURRENT";
if (soc < 10.0)
return "LOW_SOC";
return "NORMAL";
}
// --------------------------------------------------
// Send data to n8n
// --------------------------------------------------
void sendToN8N()
{
if (WiFi.status() != WL_CONNECTED)
return;
HTTPClient http;
http.begin(N8N_URL);
http.addHeader(
"Content-Type",
"application/json");
StaticJsonDocument<512> doc;
doc["device_id"] = "BATTERY-01";
doc["voltage"] = batteryVoltage;
doc["current"] = batteryCurrent;
doc["temperature"] = batteryTemperature;
doc["soc"] = soc;
doc["power"] = batteryPower;
doc["energy_wh"] = energyWh;
doc["charging"] =
batteryCurrent < -0.1;
doc["fault"] =
detectFault();
doc["wifi_rssi"] =
WiFi.RSSI();
doc["uptime"] =
millis() / 1000;
String payload;
serializeJson(doc, payload);
int response =
http.POST(payload);
Serial.print("n8n HTTP response: ");
Serial.println(response);
http.end();
}
// --------------------------------------------------
// Webpage
// --------------------------------------------------
String htmlPage()
{
String html = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport"
content="width=device-width, initial-scale=1">
<title>AI Battery Monitor</title>
<style>
body {
font-family: Arial;
background:#101820;
color:white;
text-align:center;
}
.card {
background:#1d2b36;
margin:15px;
padding:20px;
border-radius:15px;
}
.value {
font-size:32px;
color:#00e5ff;
}
.warning {
color:#ffcc00;
}
.danger {
color:#ff4444;
}
</style>
</head>
<body>
<h1>AI Battery Monitor</h1>
<div class="card">
<h2>Battery Voltage</h2>
<div class="value">
)rawliteral";
html += String(batteryVoltage, 2);
html += R"rawliteral(
V
</div>
</div>
<div class="card">
<h2>Current</h2>
<div class="value">
)rawliteral";
html += String(batteryCurrent, 2);
html += R"rawliteral(
A
</div>
</div>
<div class="card">
<h2>Temperature</h2>
<div class="value">
)rawliteral";
html += String(batteryTemperature, 1);
html += R"rawliteral(
°C
</div>
</div>
<div class="card">
<h2>State of Charge</h2>
<div class="value">
)rawliteral";
html += String(soc, 1);
html += R"rawliteral(
%
</div>
</div>
<div class="card">
<h2>Status</h2>
<div class="value">
)rawliteral";
html += detectFault();
html += R"rawliteral(
</div>
</div>
</body>
</html>
)rawliteral";
return html;
}
// --------------------------------------------------
// Web server
// --------------------------------------------------
void handleRoot()
{
server.send(
200,
"text/html",
htmlPage());
}
// --------------------------------------------------
// Setup
// --------------------------------------------------
void setup()
{
Serial.begin(115200);
Wire.begin();
ina219.begin();
tempSensor.begin();
analogReadResolution(12);
WiFi.begin(
WIFI_SSID,
WIFI_PASSWORD);
Serial.print("Connecting WiFi");
while (
WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("ESP32 IP: ");
Serial.println(WiFi.localIP());
server.on(
"/",
handleRoot);
server.begin();
lastMeasurement = millis();
lastUpload = millis();
}
// --------------------------------------------------
// Main loop
// --------------------------------------------------
void loop()
{
server.handleClient();
unsigned long now = millis();
if (now - lastMeasurement >= 1000)
{
float dtHours =
(now - lastMeasurement)
/ 3600000.0;
lastMeasurement = now;
readSensors();
soc =
calculateSOC(
batteryVoltage,
batteryCurrent,
dtHours);
energyWh +=
batteryPower * dtHours;
Serial.println("--------------------");
Serial.print("Voltage: ");
Serial.println(batteryVoltage);
Serial.print("Current: ");
Serial.println(batteryCurrent);
Serial.print("Temperature: ");
Serial.println(batteryTemperature);
Serial.print("SOC: ");
Serial.println(soc);
Serial.print("Fault: ");
Serial.println(detectFault());
}
if (now - lastUpload >= 15000)
{
lastUpload = now;
sendToN8N();
}
}
23. Important ESP32 Code Note
The example voltage/SOC table is deliberately a starting point.
Do not use it as a battery-management safety curve.
For an actual product, characterize the battery experimentally.
Measure:
Voltage
Current
Temperature
Discharged Ah
over several discharge cycles.
Then generate a battery-specific SOC curve.
24. Local IoT Webpage
The ESP32 creates a webpage such as:
http://192.168.1.50/
The page displays:
┌──────────────────────────────────┐
│ AI BATTERY MONITOR │
├──────────────────────────────────┤
│ │
│ Voltage 15.72 V │
│ │
│ Current 2.31 A │
│ │
│ Temperature 32.4 °C │
│ │
│ SOC 72.5 % │
│ │
│ Power 36.3 W │
│ │
│ Status NORMAL │
│ │
└──────────────────────────────────┘
25. Improved Web Dashboard
For a more professional dashboard, use JavaScript polling:
ESP32
│
▼
/api/status
│
▼
JavaScript
│
├── Voltage gauge
├── Current gauge
├── SOC gauge
├── Temperature
└── Status indicator
Example API response:
{
"voltage": 15.72,
"current": 2.31,
"temperature": 32.4,
"soc": 72.5,
"power": 36.3,
"status": "NORMAL"
}
26. n8n Architecture
The n8n workflow should be divided into logical stages.
Webhook
│
▼
Validate Data
│
▼
Normalize Data
│
├──────────────► Google Sheets
│
├──────────────► ThingSpeak
│
▼
Rule Engine
│
▼
AI Agent
│
▼
Decision
│
├── NORMAL → Log only
│
├── WARNING → Telegram
│
└── CRITICAL → Telegram + Voice
n8n's Telegram integration provides Telegram automation capabilities, while unsupported operations can also be accessed through HTTP/API calls. n8n Documentation
27. n8n Workflow Nodes
Create the following nodes.
Node 1
Webhook
Name:
Battery Telemetry Webhook
HTTP method:
POST
Path:
battery
Your ESP32 sends:
POST /webhook/battery
Node 2
Code / Function
Name:
Validate Telemetry
Example:
const d = $json;
const required = [
"device_id",
"voltage",
"current",
"temperature",
"soc"
];
for (const key of required) {
if (d[key] === undefined) {
throw new Error(`Missing field: ${key}`);
}
}
if (d.voltage < 0 || d.voltage > 100) {
throw new Error("Invalid voltage");
}
if (d.soc < 0 || d.soc > 100) {
throw new Error("Invalid SOC");
}
return [{
json: {
...d,
timestamp: new Date().toISOString(),
valid: true
}
}];
28. Data Normalization Node
Calculate:
power
SOC category
temperature status
battery status
Example:
const d = $json;
const power =
Number(d.voltage) *
Number(d.current);
let socStatus = "NORMAL";
if (d.soc <= 10) {
socStatus = "CRITICAL";
}
else if (d.soc <= 20) {
socStatus = "WARNING";
}
let temperatureStatus = "NORMAL";
if (d.temperature >= 55) {
temperatureStatus = "CRITICAL";
}
else if (d.temperature >= 45) {
temperatureStatus = "WARNING";
}
return [{
json: {
...d,
power,
socStatus,
temperatureStatus
}
}];
29. Google Sheets
Create a spreadsheet:
AI Battery Monitoring
Worksheet:
Telemetry
Columns:
Timestamp
Device ID
Voltage
Current
Temperature
SOC
Power
Energy Wh
Charging
Fault
WiFi RSSI
AI Severity
AI Recommendation
Example:
2026-10-06 06:00
BATTERY-01
15.72
2.31
32.4
72.5
36.3
142.6
FALSE
NORMAL
-57
NORMAL
No action required
This creates a simple historical database.
30. ThingSpeak Integration
ThingSpeak can store numerical IoT data and provide charts.
ThingSpeak supports REST APIs for writing channel data. MathWorks+1
Create a channel called:
AI Battery Monitor
Configure:
Field 1 = Battery Voltage
Field 2 = Current
Field 3 = Temperature
Field 4 = SOC
Field 5 = Power
Field 6 = Energy
Field 7 = Battery Status
The ThingSpeak REST endpoint can be updated using HTTP POST/GET. MathWorks
31. ThingSpeak n8n HTTP Request
Create an n8n:
HTTP Request
Method:
POST
URL:
https://api.thingspeak.com/update.json
Parameters:
api_key = YOUR_WRITE_API_KEY
field1 = {{$json.voltage}}
field2 = {{$json.current}}
field3 = {{$json.temperature}}
field4 = {{$json.soc}}
field5 = {{$json.power}}
field6 = {{$json.energy_wh}}
ThingSpeak returns the created entry information when the update succeeds; a failed update returns 0. MathWorks
32. ThingSpeak Dashboard
The cloud dashboard can contain:
┌────────────────────────────────────┐
│ AI BATTERY CLOUD │
├────────────────────────────────────┤
│ │
│ SOC │
│ ███████████████████░░░ 72 % │
│ │
│ Voltage │
│ ────────────────╮ │
│ ╰──────── │
│ │
│ Current │
│ ────────────╮ │
│ ╰──────── │
│ │
│ Temperature │
│ ──────────────── │
│ │
└────────────────────────────────────┘
ThingSpeak supports both REST and MQTT approaches for channel updates; REST is particularly useful when you need HTTP request/response behavior. MathWorks
33. AI Agent
The n8n AI Agent receives the normalized battery data.
Example prompt:
You are an intelligent battery monitoring agent.
Analyze the battery telemetry.
Your responsibilities are:
1. Determine whether the battery is NORMAL,
WARNING, or CRITICAL.
2. Look for:
- Low SOC
- Rapid SOC decrease
- High temperature
- Excessive current
- Abnormal voltage
- Voltage sag
- Sensor failure
- Charging anomalies
3. Do not invent sensor values.
4. Do not claim that a battery is safe when
sensor information is insufficient.
5. Return valid JSON only.
Return:
{
"severity": "NORMAL|WARNING|CRITICAL",
"alert": true/false,
"reason": "...",
"recommendation": "...",
"voice_message": "..."
}
34. Example AI Input
{
"device_id": "BATTERY-01",
"voltage": 13.4,
"current": 5.8,
"temperature": 48.2,
"soc": 14.3,
"power": 77.72,
"charging": false,
"soc_change_5min": -11.4
}
35. Example AI Output
{
"severity": "WARNING",
"alert": true,
"reason": "SOC is low and decreasing rapidly while the battery is supplying a high load.",
"recommendation": "Reduce the load and recharge the battery.",
"voice_message": "Warning. Battery charge is low and decreasing rapidly. Please reduce the load and recharge the battery."
}
36. AI Agent Decision Flow
Battery Data
│
▼
┌───────────────┐
│ AI Agent │
└───────┬───────┘
│
┌──────────┼───────────┐
│ │ │
▼ ▼ ▼
NORMAL WARNING CRITICAL
│ │ │
▼ ▼ ▼
Log only Telegram Telegram
message message
│
▼
Voice Alert
37. Rule Engine
The AI should work together with deterministic rules.
Example:
SOC < 20%
↓
WARNING
SOC < 10%
↓
CRITICAL
Temperature > 45°C
↓
WARNING
Temperature > 55°C
↓
CRITICAL
Current > configured maximum
↓
CRITICAL
The exact thresholds must be configured for the particular battery, BMS and load.
38. Rapid SOC Drop Detection
One of the useful AI features is detecting:
SOC = 80%
followed shortly by:
SOC = 65%
while the current is normal.
The AI Agent can investigate:
Possible causes:
- incorrect SOC calibration
- battery degradation
- sensor error
- unexpected load
- voltage sag
39. Telegram Integration
Create a Telegram bot using BotFather.
The bot receives:
/battery
/status
/soc
/temperature
/history
/help
The Telegram Bot API supports sending voice messages using sendVoice. Telegram Core
40. Telegram Text Alert
Example:
🔋 BATTERY ALERT
Device: BATTERY-01
SOC: 14.3%
Voltage: 13.40 V
Current: 5.80 A
Temperature: 48.2 °C
Severity: WARNING
Reason:
SOC is low and decreasing rapidly.
Recommendation:
Reduce the load and recharge the battery.
41. Telegram Voice Alert
The n8n workflow can generate speech from:
voice_message
For example:
Warning. Battery charge is low and decreasing rapidly.
Please reduce the load and recharge the battery.
The generated audio is then passed to Telegram as a voice message.
Telegram's API specifically distinguishes voice messages from ordinary audio files. Telegram Core
42. Voice Alert Architecture
AI Agent
│
▼
voice_message
│
▼
Text-to-Speech
│
▼
MP3/OGG audio
│
▼
n8n Binary Data
│
▼
Telegram Send Voice
│
▼
User's phone
A TTS provider can be connected through an n8n integration or HTTP Request node.
43. Telegram Example Conversation
USER:
/battery
BOT:
🔋 Battery Status
SOC: 72.5%
Voltage: 15.72 V
Current: 2.31 A
Temperature: 32.4°C
Power: 36.3 W
Status: NORMAL
Then:
USER:
/temperature
BOT:
🌡 Battery Temperature
Current: 32.4°C
Status: NORMAL
44. AI Telegram Conversation
A more advanced system can allow natural-language questions.
USER:
Why is my battery draining quickly?
The AI Agent can receive recent telemetry and answer:
The battery has dropped approximately
11% in the last 5 minutes.
The current load is 5.8 A and the
temperature is 48.2°C.
The most likely reason is high load
combined with low remaining capacity.
Recommendation:
Reduce the load and recharge the battery.
45. Complete n8n Workflow
Recommended workflow:
┌──────────────┐
│ ESP32 │
└──────┬───────┘
│
▼
┌───────────────┐
│ Webhook │
└──────┬────────┘
│
▼
┌───────────────┐
│ Validate │
└──────┬────────┘
│
▼
┌───────────────┐
│ Normalize │
└──────┬────────┘
│
┌────────────┼──────────────┐
│ │ │
▼ ▼ ▼
Google Sheets ThingSpeak Database
│ │ │
└────────────┼──────────────┘
│
▼
┌───────────────┐
│ Rule Engine │
└──────┬────────┘
│
▼
┌───────────────┐
│ AI Agent │
└──────┬────────┘
│
▼
┌───────────────┐
│ Parse JSON │
└──────┬────────┘
│
▼
┌────────────┐
│ Alert? │
└─────┬──────┘
│
┌────────┴────────┐
│ │
NO YES
│ │
▼ ▼
Finish Telegram Text
│
▼
TTS Engine
│
▼
Telegram Voice
46. Recommended n8n Nodes
A practical workflow can contain:
1. Webhook
2. Code – Validate Data
3. Code – Calculate Derived Values
4. Google Sheets – Append Row
5. HTTP Request – ThingSpeak
6. IF – Safety Threshold
7. AI Agent
8. Structured Output Parser
9. IF – Alert Required
10. Telegram – Send Message
11. HTTP Request/TTS
12. Telegram – Send Voice
13. Respond to Webhook
47. AI Agent Tools
The AI Agent can be given tools such as:
Tool 1:
Get latest battery status
Tool 2:
Get recent historical data
Tool 3:
Get Google Sheets history
Tool 4:
Send Telegram notification
Tool 5:
Update device configuration
Tool 6:
Get ThingSpeak data
This is what makes the architecture more agentic rather than simply a fixed automation workflow.
48. Agentic IoT Architecture
Traditional IoT:
Sensor
↓
Cloud
↓
Dashboard
Agentic IoT:
Sensor
↓
ESP32
↓
Telemetry
↓
AI Agent
↓
Observe
↓
Reason
↓
Decide
↓
Act
↓
Notify / Log / Recommend
For example:
OBSERVE:
SOC = 12%
Temperature = 49°C
Current = 6A
REASON:
Low SOC + high temperature + high load
DECIDE:
WARNING
ACT:
Send Telegram notification
Generate voice alert
Record event
49. Battery Fault Classification
The system can classify:
NORMAL
LOW_SOC
HIGH_TEMPERATURE
OVER_CURRENT
LOW_VOLTAGE
RAPID_SOC_DROP
SENSOR_ERROR
COMMUNICATION_ERROR
POSSIBLE_BATTERY_DEGRADATION
50. Sensor Failure Detection
Suppose:
Voltage = 15.7 V
Current = 0 A
Temperature = -127°C
The ESP32/AI layer should recognize:
Temperature sensor failure
instead of reporting:
Battery temperature = -127°C
Similarly:
Voltage = 0 V
Current = 0 A
could indicate:
Battery disconnected
rather than necessarily meaning:
Battery is empty
51. Battery Degradation Detection
Over multiple cycles, record:
Cycle number
Maximum capacity
Minimum voltage
Temperature
Internal resistance estimate
SOC error
Suppose:
Cycle 1 → 10.0 Ah
Cycle 50 → 9.2 Ah
Cycle 100 → 8.4 Ah
Cycle 150 → 7.8 Ah
The AI Agent can identify:
Capacity is decreasing over time.
Possible battery degradation.
52. Internal Resistance Estimation
If load current changes rapidly:
ΔV
───
ΔI
can provide an approximate resistance:
R ≈ ΔV / ΔI
For example:
Before load:
V1 = 15.8 V
After load:
V2 = 15.2 V
Current change:
ΔI = 5 A
R ≈ 0.6 / 5
R ≈ 0.12 Ω
This should be treated as an estimate because wiring resistance, sensor delay, battery temperature and dynamic battery behavior also influence the measurement.
53. AI Anomaly Detection
Historical features can include:
SOC
Voltage
Current
Temperature
Power
Voltage sag
SOC derivative
Temperature derivative
Estimated resistance
The AI layer can detect patterns such as:
Normal:
SOC slowly decreases
Temperature stable
Voltage stable
versus:
Abnormal:
SOC rapidly decreases
Temperature rises rapidly
Voltage sag increases
54. Optional Machine-Learning SOC Model
For a more advanced academic/project implementation, collect thousands of samples.
Dataset:
timestamp
voltage
current
temperature
power
previous_soc
time_delta
measured_capacity
true_soc
Train a regression model:
Inputs:
Voltage
Current
Temperature
Power
Time
Previous SOC
↓
ML Model
↓
Estimated SOC
55. ML Training Pipeline
Battery Test
│
▼
Data Logger
│
▼
CSV Dataset
│
▼
Python
│
▼
Data Cleaning
│
▼
Feature Engineering
│
▼
ML Training
│
▼
Validation
│
▼
Model
│
├── ESP32 TinyML
│
└── n8n/cloud inference
56. Example Python Training Code
A simple prototype can use Random Forest regression:
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error
import joblib
# Load dataset
df = pd.read_csv("battery_dataset.csv")
features = [
"voltage",
"current",
"temperature",
"power"
]
X = df[features]
y = df["true_soc"]
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)
model = RandomForestRegressor(
n_estimators=200,
random_state=42
)
model.fit(X_train, y_train)
prediction = model.predict(X_test)
mae = mean_absolute_error(
y_test,
prediction
)
print("MAE:", mae)
joblib.dump(
model,
"battery_soc_model.pkl"
)
The result can be evaluated using:
MAE
RMSE
R²
57. AI SOC Architecture
An advanced system can combine:
Coulomb SOC
│
├─────────┐
│ │
Voltage SOC │
│ │
└────┬────┘
│
▼
ML Correction
│
▼
Final SOC
For example:
Coulomb SOC = 67%
Voltage SOC = 63%
ML estimate = 65%
Final SOC = 65%
The exact fusion algorithm should be validated against experimentally measured capacity.
58. Why Hybrid SOC Is Better
Voltage-only:
Simple
but load-sensitive
Coulomb-only:
Good short-term tracking
but accumulates error
AI-only:
Can model nonlinear behavior
but requires good training data
Hybrid:
Voltage
+
Coulomb counting
+
Temperature
+
ML correction
provides a much stronger engineering approach.
59. Complete Communication Architecture
BATTERY
│
▼
ESP32
│
HTTPS / JSON
│
▼
n8n
│
┌──────────┼────────────┐
│ │ │
▼ ▼ ▼
Google ThingSpeak AI
Sheets Agent
│
┌────┴─────┐
│ │
▼ ▼
Telegram TTS
│ │
└────┬─────┘
▼
Voice Alert
60. Security
Do not hard-code production secrets into publicly shared firmware.
Avoid:
const char* API_KEY = "my-real-key";
in code that will be uploaded to GitHub.
Use:
Environment variables
Secret manager
n8n credentials
Device-specific credentials
At minimum:
HTTPS
Webhook authentication
Telegram bot token protection
ThingSpeak API key protection
Wi-Fi credentials protection
61. ESP32 → n8n Authentication
A better approach than an open webhook is:
ESP32
│
│ Authorization: Bearer DEVICE_SECRET
▼
n8n
The ESP32 sends:
Authorization: Bearer YOUR_DEVICE_SECRET
Content-Type: application/json
n8n verifies the secret before accepting telemetry.
62. Example ESP32 Authentication
Add:
http.addHeader(
"Authorization",
"Bearer YOUR_DEVICE_SECRET"
);
Then n8n validates it.
For production systems, use device-specific credentials rather than one global token.
63. Telegram Security
Only allow authorized users.
The workflow should verify:
Telegram chat_id
against an allowlist.
Example:
AUTHORIZED_CHAT_ID_1
AUTHORIZED_CHAT_ID_2
If an unknown user sends:
/status
the bot should respond:
Unauthorized user.
64. Google Sheets Security
Do not make the spreadsheet public unless the project specifically requires it.
Recommended:
Private Sheet
↓
n8n authenticated account
↓
Append telemetry
65. ThingSpeak Security
Keep the Write API Key private.
Use:
ESP32 → n8n → ThingSpeak
rather than exposing the ThingSpeak write key unnecessarily on the ESP32.
ThingSpeak provides separate channel/API mechanisms for reading and writing channel data. MathWorks
66. Testing Procedure
Test 1 — ESP32 boot
Expected:
ESP32 starts
Wi-Fi connects
IP address displayed
Test 2 — Voltage
Use a multimeter.
Compare:
Multimeter = 15.72 V
ESP32 = 15.70 V
Calculate error:
Error =
|15.72 - 15.70| / 15.72 × 100
Test 3 — Current
Use a calibrated current meter.
Compare:
Reference = 2.30 A
ESP32 = 2.31 A
67. Temperature Test
Place the sensor on the battery.
Compare against a trusted thermometer.
Test:
Room temperature
Warm battery
High-load condition
68. SOC Calibration Test
Start from a known full battery.
Record:
100%
Then discharge using a controlled load.
Record:
95%
90%
85%
...
10%
5%
Calculate actual consumed Ah.
Generate the battery-specific SOC curve.
69. n8n Testing
Send test JSON manually:
{
"device_id": "TEST-01",
"voltage": 13.2,
"current": 5.5,
"temperature": 49,
"soc": 12,
"power": 72.6,
"energy_wh": 120,
"charging": false
}
Expected:
Webhook
↓
Validation
↓
Google Sheets
↓
ThingSpeak
↓
AI Agent
↓
WARNING
↓
Telegram
70. Critical Alert Test
Send:
{
"device_id": "TEST-01",
"voltage": 11.8,
"current": 8.2,
"temperature": 58,
"soc": 5
}
Expected:
Severity = CRITICAL
Then:
Telegram text
+
Telegram voice
should be generated.
71. Network Failure Test
Turn off Wi-Fi.
Expected:
ESP32 continues measuring
ESP32 continues calculating SOC
Local webpage may remain available if local network is available
Cloud upload fails
The firmware should not crash because the cloud service is unavailable.
72. n8n Failure Test
Stop n8n.
Expected:
ESP32 continues operating
When n8n returns:
ESP32 reconnects
Telemetry resumes
A production version can add local buffering in ESP32 flash/SD card.
73. Recommended Offline Buffer
Advanced ESP32 architecture:
Sensor
↓
SOC
↓
RAM buffer
↓
Wi-Fi available?
├── YES → Upload
└── NO → Store locally
Then:
Wi-Fi returns
↓
Upload buffered records
74. Final Project Flowchart
START
│
▼
Initialize ESP32
│
▼
Connect to Wi-Fi
│
▼
Initialize Sensors
│
▼
Read Battery Voltage
│
▼
Read Battery Current
│
▼
Read Temperature
│
▼
Calculate Battery Power
│
▼
Calculate SOC
│
▼
Check Local Faults
│
▼
Update Webpage
│
▼
Send Telemetry to n8n
│
▼
n8n Validates Data
│
▼
Store Google Sheets
│
▼
Update ThingSpeak
│
▼
AI Agent
│
▼
Analyze Condition
│
▼
┌───────┴────────┐
│ │
NORMAL ALERT
│ │
▼ ▼
Log Telegram Text
│
▼
TTS
│
▼
Telegram Voice
│
▼
END
75. Complete Hardware BOM
Recommended prototype BOM:
1 × ESP32 DevKit
1 × INA219 or INA226 module
1 × DS18B20 temperature sensor
1 × 4S Li-ion battery pack
1 × 4S BMS
1 × 100 kΩ resistor
1 × 22 kΩ resistor
1 × 4.7 kΩ resistor
1 × DC-DC buck converter
1 × Fuse
1 × Prototype PCB
1 × OLED display (optional)
1 × enclosure
For high-current batteries, use a properly rated current sensor, wiring, connector, fuse and protection hardware. Do not route high battery current through a small breadboard.
76. Software BOM
Arduino IDE
ESP32 Arduino Core
Libraries:
- WiFi
- WebServer
- HTTPClient
- ArduinoJson
- Wire
- Adafruit INA219
- OneWire
- DallasTemperature
Cloud:
- n8n
- Google Sheets
- ThingSpeak
- Telegram Bot
Optional:
- AI model/API
- TTS provider
- Python
- scikit-learn
- joblib
77. Final System Architecture
┌────────────────────┐
│ 4S BATTERY/BMS │
└─────────┬──────────┘
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
Voltage Current Temperature
Sensor Sensor DS18B20
│ │ │
└──────────────┼──────────────┘
▼
┌──────────────────┐
│ ESP32 │
│ │
│ Sensor Reading │
│ SOC Estimation │
│ Energy │
│ Fault Detection │
│ Web Server │
└────────┬─────────┘
│
HTTPS
│
▼
┌──────────────────┐
│ n8n │
│ │
│ Webhook │
│ Validation │
│ Automation │
│ AI Agent │
└───────┬──────────┘
│
┌───────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌──────────────┐
│Google Sheets│ │ ThingSpeak │ │ AI Agent │
│ │ │ │ │ │
│History │ │Cloud Charts │ │Reasoning │
│Data Logger │ │Telemetry │ │Anomaly │
└─────────────┘ └─────────────┘ └──────┬───────┘
│
▼
┌─────────────┐
│ Decision │
└──────┬──────┘
│
┌────────┴────────┐
│ │
NORMAL ALERT
│ │
▼ ▼
LOG Telegram Text
│
▼
TTS Engine
│
▼
Telegram Voice
78. Expected Final Output
When the system is operating normally:
ESP32
│
├─ Voltage: 15.72 V
├─ Current: 2.31 A
├─ Temperature: 32.4 °C
├─ SOC: 72.5 %
└─ Power: 36.3 W
↓
n8n
↓
Google Sheets ✓
ThingSpeak ✓
AI Agent ✓
Telegram: No alert
When a problem occurs:
ESP32
│
├─ Voltage: 13.4 V
├─ Current: 5.8 A
├─ Temperature: 48.2 °C
└─ SOC: 14.3 %
↓
n8n
↓
AI Agent
↓
WARNING
↓
Telegram Text
+
Telegram Voice
↓
"Warning. Battery charge is low
and decreasing rapidly. Please
reduce the load and recharge
the battery."
79. Project Advantages
This architecture combines five different technologies:
Embedded system
ESP32 measures and processes the physical battery.
IoT
Wi-Fi transfers telemetry to the cloud.
Automation
n8n connects all services.
Artificial intelligence
The AI Agent interprets telemetry and historical behavior.
Voice notification
Telegram delivers the warning as both text and voice.
Therefore, the project is more than a conventional battery monitor.
It is an:
AI-powered Agentic IoT Battery Monitoring and Decision-Support System.
80. Suggested Project/Thesis Chapter Structure
For an academic project report, use:
Chapter 1
Introduction
Chapter 2
Literature Survey
Chapter 3
System Requirements
Chapter 4
Hardware Design
Chapter 5
Battery SOC Estimation
Chapter 6
ESP32 Firmware
Chapter 7
IoT Web Interface
Chapter 8
n8n Automation
Chapter 9
AI Agent Design
Chapter 10
Telegram Voice Alert System
Chapter 11
Google Sheets Integration
Chapter 12
ThingSpeak Cloud Dashboard
Chapter 13
Testing and Results
Chapter 14
Performance Analysis
Chapter 15
Limitations
Chapter 16
Future Scope
Chapter 17
Conclusion
81. Future Enhancements
The project can be upgraded with:
✓ TinyML SOC estimation
✓ LSTM battery prediction
✓ Remaining Useful Life (RUL)
✓ Battery State of Health (SOH)
✓ Internal resistance estimation
✓ Cell-level monitoring
✓ CAN bus BMS integration
✓ MQTT
✓ OTA ESP32 firmware updates
✓ Mobile application
✓ Voice commands
✓ AI-generated maintenance reports
✓ Predictive failure detection
✓ Solar charging integration
✓ EV battery monitoring
✓ Multi-battery monitoring
For example:
Battery SOC
+
Battery SOH
+
Temperature
+
Current
+
Historical cycles
↓
AI Predictive Model
↓
Remaining Useful Life
82. Important Engineering Limitation
This project is suitable for:
It should not replace the battery manufacturer's BMS or certified protection circuitry.
The BMS remains responsible for electrical protection such as:
Overcharge
Over-discharge
Overcurrent
Short circuit
Cell imbalance
Temperature protection
The ESP32/n8n/AI system should be considered a monitoring and decision-support system, unless the entire protection architecture is engineered and certified for the intended application.
83. Final One-Line Architecture
The complete project can be summarized as:
BATTERY
↓
V/I/T SENSORS
↓
ESP32
↓
HYBRID SOC ESTIMATION
↓
Wi-Fi / HTTPS
↓
n8n
↓
AI AGENT
↓
┌────────────┬─────────────┬───────────────┐
│ │ │ │
Google ThingSpeak Telegram AI
Sheets Dashboard Text/Voice Analysis
This gives you a complete ESP32 + AI + Agentic IoT + n8n + Telegram Voice + Google Sheets + ThingSpeak battery SOC platform.
Current implementation notes
A few pieces are worth treating as production-hardening steps rather than copy/paste defaults:
-
The SOC lookup table in the firmware must be calibrated for your exact battery chemistry, capacity and discharge conditions.
-
For lithium batteries, keep the physical BMS independent of the ESP32/software layer.
-
ThingSpeak's REST API supports channel writes and historical reads, so it works well as the cloud visualization/history layer. MathWorks+1
-
Telegram's current Bot API supports sendVoice, which is the appropriate mechanism for Telegram-style voice messages. Telegram Core
-
n8n has a native Telegram integration, while HTTP Request nodes can be used for services that don't have a dedicated node. n8n Documentation
If you want to turn this into a fully buildable project, the next useful step is to define the exact battery—e.g. 12 V lead-acid, 4S Li-ion 14.8 V/16.8 V, or 4S LiFePO4—because that determines the correct SOC curve, sensor range, thresholds and calibration procedure.
Project Summary
AI-Powered Battery State-of-Charge (SOC) Estimation & Agentic IoT System is an ESP32-based smart battery-monitoring
platform that combines embedded sensing, AI, cloud dashboards and automated notifications.
Core workflow
Battery
↓
Voltage + Current + Temperature Sensors
↓
ESP32
↓
Hybrid SOC Estimation
↓
Wi-Fi / HTTPS
↓
n8n Automation
↓
AI Agent
↓
┌──────────────┬──────────────┬──────────────┐
Google Sheets ThingSpeak Telegram
Data Logging Dashboard Text + Voice
Main functions
-
ESP32 measures battery voltage, current and temperature.
-
SOC algorithm combines voltage and coulomb counting, with optional ML correction.
-
Local IoT webpage displays real-time voltage, current, temperature, SOC, power and status.
-
n8n receives telemetry and automates the complete workflow.
-
AI Agent analyzes battery conditions and identifies anomalies such as low SOC, rapid discharge, overheating and abnormal voltage.
-
Google Sheets stores historical battery data.
-
ThingSpeak provides cloud visualization and historical graphs.
-
Telegram sends automatic text alerts.
-
Text-to-Speech + Telegram provides voice warnings.
-
Local ESP32 safety rules continue operating even if Wi-Fi, n8n or AI services fail.
Example alert
🔋 BATTERY ALERT
SOC: 14.3%
Voltage: 13.40 V
Current: 5.80 A
Temperature: 48.2 °C
Severity: WARNING
Reason:
Battery SOC is low and decreasing rapidly.
Recommendation:
Reduce the load and recharge the battery.
Advanced capabilities
The project can later be expanded to:
-
AI/ML SOC prediction
-
State of Health (SOH)
-
Remaining Useful Life (RUL)
-
Battery degradation detection
-
Internal-resistance estimation
-
Cell-level monitoring
-
Predictive failure detection
-
CAN-BMS integration
-
OTA ESP32 updates
-
Voice commands
-
Multi-battery monitoring
In short: the project transforms a conventional ESP32 battery monitor into an AI-powered Agentic IoT battery-management and notification system, with real-time monitoring, historical data, intelligent analysis and automated Telegram voice alerts.