AI Solar Panel Cooling & Efficiency Optimization System
Complete Project Documentation: ESP32 + IoT + AI Agent + n8n + Telegram + Google Sheets + ThingSpeak
This project is an AI-powered solar panel monitoring, cooling, and efficiency optimization system. It uses an ESP32 microcontroller, temperature and environmental sensors, an automated cooling mechanism, cloud dashboards, and an AI agent orchestrated through n8n to monitor solar panel conditions, improve operating efficiency, and send Telegram voice alerts when abnormal conditions occur.
The project combines embedded hardware, IoT communication, AI-assisted decision-making, automation workflows, data logging, and a web dashboard into one integrated system.
The documentation below covers the project concept, objectives, hardware, wiring, circuit schematic, software architecture, flowcharts, ESP32 firmware, n8n automation, AI-agent logic, Telegram alerts, Google Sheets logging, ThingSpeak visualization, and testing.
Project at a glance
ESP32 — monitoring and control
Reads sensors, controls cooling hardware, calculates basic metrics, and sends telemetry to the cloud.
Smart cooling system
Uses temperature thresholds and hysteresis to operate a fan or pump automatically.
n8n + AI agent
Analyzes telemetry, generates recommendations, records events, and routes alerts.
Web and cloud dashboard
Displays sensor readings and trends using ThingSpeak, with Google Sheets for historical records.
1. Abstract
Solar photovoltaic (PV) panels convert sunlight into electrical energy. Their output depends on solar irradiance, cell temperature, shading, dust, electrical loading, and panel condition. As PV cell temperature rises, the voltage and maximum power output generally decrease.
The proposed system continuously monitors the solar panel's temperature, ambient temperature, and electrical output. An ESP32 processes sensor readings and activates a cooling fan or, in an appropriately designed prototype, a water-cooling pump when the panel exceeds a configured temperature threshold.
The ESP32 publishes telemetry to an IoT service. An n8n workflow receives or retrieves the data, checks operating conditions, and invokes an AI agent to explain abnormal readings and recommend appropriate actions. The workflow records readings in Google Sheets, updates monitoring dashboards through ThingSpeak, and sends Telegram text or generated voice alerts to the operator.
The system uses a hybrid control strategy: local temperature-based control on the ESP32 for fast, dependable operation, and cloud-based AI for analysis, recommendations, and supervisory optimization. This ensures the cooling system can continue operating even when the internet or AI service is unavailable.
2. Objectives
-
Monitor solar panel temperature, ambient temperature, voltage, current, and power.
-
Automatically control cooling based on measured panel temperature.
-
Estimate the relationship between panel temperature and electrical performance.
-
Display live and historical telemetry on an IoT dashboard.
-
Use an AI agent to interpret readings and suggest corrective actions.
-
Automate notifications using n8n and Telegram.
-
Send voice alerts for critical temperature or performance conditions.
-
Store data in Google Sheets for analysis and project reporting.
-
Evaluate whether cooling improves energy output enough to justify its energy and water consumption.
3. Proposed system features
|
Feature |
Implementation |
|---|---|
|
Controller |
ESP32 development board |
|
Temperature monitoring |
DS18B20 contact sensor or suitable calibrated temperature sensor |
|
Electrical measurements |
Voltage divider and current sensor |
|
Cooling |
DC fan; optional water pump and spray/mist system |
|
Communication |
Wi-Fi and HTTP/MQTT |
|
IoT dashboard |
ThingSpeak |
|
Automation |
n8n |
|
AI analysis |
LLM-backed AI Agent node in n8n |
|
Historical data |
Google Sheets |
|
Alerts |
Telegram Bot API, text and generated audio |
|
Web interface |
Responsive dashboard reading ThingSpeak data and/or an n8n API |
|
Safety |
Local control, sensor validation, actuator timeout, alert cooldown |
4. Complete system architecture
The design separates the system into four layers: sensing, local control, cloud intelligence, and user interaction.
LAYER 1 — SOLAR PANEL & SENSORS
PV panel · Panel temperature · Ambient temperature · Voltage · Current
LAYER 2 — ESP32 EDGE CONTROLLER
Sensor acquisition · Power calculations · Threshold logic · Fan/pump control · Wi-Fi
LAYER 3 — CLOUD & AGENTIC AUTOMATION
ThingSpeak · n8n Webhook · AI Agent · Rules engine · Google Sheets
LAYER 4 — USER INTERFACE
Web dashboard · Telegram text · Voice alerts · Historical reports
4.1 Data flow
-
The temperature sensor measures the panel's rear-surface temperature.
-
The ESP32 measures ambient temperature and electrical parameters.
-
The controller validates the readings and calculates electrical power.
-
If the panel is too hot, the ESP32 activates the configured cooling actuator.
-
The ESP32 uploads telemetry to ThingSpeak and/or an n8n webhook.
-
n8n validates the payload, checks thresholds, and passes relevant information to an AI Agent.
-
n8n writes the measurements and events to Google Sheets.
-
When an alert condition occurs, n8n sends a Telegram message and optionally a generated voice recording.
-
The web dashboard displays the current measurements and historical trends.
-
Subsequent measurements verify whether the cooling action reduced temperature and improved output.
Important: ThingSpeak and n8n have separate roles. ThingSpeak stores time-series data and provides charts; n8n orchestrates actions. Sending telemetry to one service does not automatically send it to the other. The firmware must explicitly send to both, or n8n must retrieve data from ThingSpeak.
5. Hardware requirements
The following is a practical prototype bill of materials. The exact component ratings should be selected after deciding the solar panel voltage, current, and cooling method.
Illustrative component references
ESP32 DevKit
Main controller with Wi-Fi
DS18B20 probe
Panel temperature measurement
INA219 or suitable power sensor
Voltage/current measurement within its ratings
DC cooling fan
Panel cooling actuator
MOSFET driver
Switches fan or pump power
Regulated power supply
Provides appropriate supply voltages
5.1 Bill of materials
|
Component |
Quantity |
Purpose |
|---|---|---|
|
ESP32 DevKit |
1 |
Main controller |
|
DS18B20 temperature probes |
2 |
Panel and ambient temperature |
|
4.7 kΩ resistor |
1 |
OneWire data pull-up |
|
Voltage measurement circuit or rated sensor |
1 |
PV voltage |
|
Current sensor, e.g. INA219 |
1 |
PV current within sensor limits |
|
DC fan and compatible MOSFET driver |
1 |
Cooling |
|
Optional DC pump and water circuit |
1 |
Alternative liquid cooling |
|
Appropriate fuse and DC-rated wiring |
As needed |
Electrical protection |
|
DC supply/buck converter |
As needed |
Power regulation |
|
Breadboard or terminal blocks |
As needed |
Low-voltage prototyping |
|
Wi-Fi network |
1 |
Cloud connectivity |
|
ThingSpeak account |
1 |
IoT storage and charts |
|
n8n instance |
1 |
Automation workflows |
|
Telegram bot |
1 |
Notifications |
|
Google account |
1 |
Sheets logging |
|
AI model API or compatible service |
1 |
Agent reasoning |
The INA219 is not suitable for every panel. Its voltage and current limits must be checked against the actual circuit. For a larger panel, use a correctly rated isolated measurement device or a suitably designed voltage-divider and current-sensing circuit.
5.2 Suggested GPIO assignment
These pin assignments are examples for a common ESP32 DevKit V1; verify the board's pinout before wiring.
|
Signal |
ESP32 GPIO |
Notes |
|---|---|---|
|
DS18B20 data |
GPIO 4 |
Add 4.7 kΩ pull-up to 3.3 V |
|
I²C SDA |
GPIO 21 |
Power monitor data |
|
I²C SCL |
GPIO 22 |
Power monitor clock |
|
Fan MOSFET control |
GPIO 26 |
Drives a logic-level MOSFET gate/driver input |
|
Pump control (optional) |
GPIO 27 |
Separate driver and protection |
|
Status LED (optional) |
GPIO 2 |
Board-dependent |
Never connect a fan, pump, or solar panel power output directly to an ESP32 GPIO. GPIO pins are logic signals, not power outputs.
6. Circuit schematic
The schematic below illustrates the low-voltage prototype. It is a functional wiring reference, not a production-ready PCB or a complete solar power design.
6.1 Text schematic
SMALL PV PANEL / TEST SOURCE
+PV -PV
| |
| +--------------------+
| |
+-----+-------+ COMMON DC RETURN*
| | |
Voltage sensor Current sensor |
| | |
+------ I2C --+ |
SDA/SCL |
+----------+ |
| ESP32 | |
| | |
DS18B20 #1 --------| GPIO 4 | |
DS18B20 #2 --------| GPIO 4* | |
Fan driver input --| GPIO 26 | |
Pump driver input -| GPIO 27 | |
| | |
| Wi-Fi | |
+----+-----+ |
| |
Wi-Fi router |
| |
ThingSpeak / n8n |
| |
AI / Sheets / Telegram |
|
Fan supply (+) -------------------- +12 V (example) |
Fan supply (-) ---- MOSFET drain |
MOSFET source -------------------- common return -------------+
MOSFET gate <--------------------- GPIO 26 via gate resistor
* For two DS18B20 probes, they can share one OneWire data bus if each has a unique address. Connect both data wires to GPIO 4 and use one 4.7 kΩ pull-up resistor to 3.3 V.
* The common-return arrangement is only valid for a compatible, non-isolated low-voltage circuit. Do not assume that the PV negative, ESP32 ground, and sensor terminals may always be tied together. Follow the current sensor's datasheet and the system's isolation requirements.
6.2 Sensor wiring
DS18B20
|
DS18B20 connection |
ESP32 connection |
|---|---|
|
VDD |
3.3 V |
|
GND |
GND |
|
DATA |
GPIO 4 |
|
Pull-up |
4.7 kΩ from DATA to 3.3 V |
Mount the panel sensor firmly on the rear surface of the PV module, preferably with thermal contact material and insulation over the probe where appropriate. The probe measures the surface at its mounting point, not the exact internal cell temperature.
INA219
|
INA219 pin |
ESP32 connection |
|---|---|
|
VCC |
Supply specified by breakout manufacturer |
|
GND |
Compatible logic ground |
|
SDA |
GPIO 21 |
|
SCL |
GPIO 22 |
The INA219 is a low-side/high-side measurement device depending on how it is installed. Use the correct terminal orientation and observe the board's voltage, current, shunt, and power limits. It must be wired in series with the measured current path, not simply placed across the panel.
For larger or higher-voltage PV systems, select appropriately rated transducers, fuses, wiring, and isolation. Do not experiment with exposed mains or high-voltage PV strings.
6.3 Fan driver circuit
For a suitable low-voltage DC fan using a logic-level N-channel MOSFET:
+12 V (fan supply)
|
[FUSE]
|
[FAN +]
[FAN -]--------- MOSFET DRAIN
MOSFET SOURCE -------- GND*
ESP32 GPIO 26 --[100Ω]-- MOSFET GATE
|
[10kΩ]
|
GND*
* Common ground only when the driver and power architecture require
and permit it. Add transient suppression as required by the fan type.
Use a MOSFET that fully switches at the ESP32's 3.3 V logic level and can withstand the fan's startup current. A motor driver or protected MOSFET module may be preferable. Do not power the fan from the ESP32's 3.3 V pin.
For a pump, use a separate correctly rated driver and a suitable flyback or transient-protection arrangement. For water cooling, add leak protection and keep exposed electronics away from water.
7. Cooling strategy and efficiency calculations
7.1 Temperature-based cooling logic
Use two temperature thresholds rather than switching the fan on and off at exactly one temperature. This is called hysteresis and prevents rapid switching.
For the initial prototype, the following are example values, not universal safe limits.
|
Condition |
Example behavior |
|---|---|
|
Panel temperature below 40°C |
Fan OFF, provided no fault requires another response |
|
Panel temperature reaches 45°C |
Fan ON |
|
Panel temperature falls to 38°C or below |
Fan OFF |
|
Temperature sensor fails |
Raise fault alert; apply the preconfigured safe actuator policy |
|
Temperature exceeds critical limit |
Keep protective cooling enabled and send an urgent alert |
Choose thresholds based on the panel manufacturer's limits, sensor placement, local climate, and experimental results.
7.2 Electrical calculations
The instantaneous DC output power is:
For example, if the measured voltage is 18.2 V and the current is 2.1 A:
This is the measured operating power, not necessarily the panel's maximum available power.
The relative change in power between comparable baseline and cooled measurements is:
If baseline power is 35 W and cooled power is 38 W, the increase is approximately 8.57%. This is only a valid cooling comparison if sunlight, electrical loading, and other relevant conditions are sufficiently comparable.
For temperature-related analysis, a first-order estimate is:
where γPγP is the panel's power temperature coefficient expressed per °C. Use the value in the actual module datasheet. This equation estimates temperature-related behavior and does not replace a measured maximum-power calculation.
7.3 Measure the energy cost of cooling
Cooling is beneficial only if its benefit exceeds its electrical cost and, for liquid systems, its water cost.
For a fan that consumes 3 W:
-
Before cooling: 35 W PV output.
-
After cooling: 38 W PV output.
-
Fan consumption: 3 W.
Net output is 35 W in both cases. Therefore, this example has no net instantaneous power gain, even though the panel output increased.
For credible project results, log panel temperature, irradiance or a consistent proxy, PV voltage/current, fan state, cooling power, and timestamps. Compare controlled cooling-on and cooling-off trials.
8. Software installation and setup
8.1 ESP32 development environment
Install:
-
Arduino IDE.
-
ESP32 board support package.
-
OneWire library.
-
DallasTemperature library.
-
Adafruit INA219 library if using that sensor.
-
A compatible ESP32 Arduino core.
The official ESP32 Arduino Wi-Fi documentation describes station mode and Wi-Fi connectivity.
In Arduino IDE:
-
Install ESP32 board support through Boards Manager.
-
Select the correct ESP32 board and serial port.
-
Install the sensor libraries through Library Manager.
-
Connect the ESP32 over USB.
-
Upload a sensor test sketch.
-
Open Serial Monitor at 115200 baud and verify readings before connecting the cloud services.
8.2 ThingSpeak setup
-
Create an account at ThingSpeak .
-
Create a new channel named
AI Solar Cooling Monitor. -
Enable and label the following fields:
|
Field |
Label |
Unit |
|---|---|---|
|
1 |
Panel Temperature |
°C |
|
2 |
Ambient Temperature |
°C |
|
3 |
PV Voltage |
V |
|
4 |
PV Current |
A |
|
5 |
PV Power |
W |
|
6 |
Cooling State |
0 or 1 |
|
7 |
Temperature Difference |
°C |
|
8 |
Cooling Power |
W |
-
Open the channel's API Keys section.
-
Copy the Write API Key for the ESP32.
-
Configure charts and verify that test measurements appear.
ThingSpeak supports channel updates using its REST API. The /update endpoint accepts a write key and numbered fields; successful writes return an entry identifier, while failed updates may return 0.
ThingSpeak commonly enforces a minimum update interval on standard channels, often 15 seconds. Use a 20-second telemetry interval for this prototype, and verify the limits of your account and service configuration.
8.3 n8n setup
You can run n8n on a server, a managed deployment, or a local computer for testing. For an external ESP32 to call a self-hosted n8n webhook, the webhook must be reachable from the device over a secure connection.
-
Create an n8n instance at n8n .
-
Create a workflow named
AI Solar Panel Monitoring. -
Add a Webhook node with method
POSTand pathsolar-telemetry. -
Set the webhook to expect JSON.
-
Add validation and threshold-checking nodes.
-
Add a Google Sheets node.
-
Add an AI Agent with an LLM connection.
-
Add Telegram notification actions.
-
Test the workflow with sample JSON.
-
Activate the workflow and use its production webhook URL in the ESP32 firmware.
The Google Sheets integration supports appending rows and appending or updating rows through n8n.
9. ESP32 firmware — complete starter implementation
This firmware is designed to monitor two DS18B20 probes, read PV voltage/current through an INA219, operate a DC fan, and publish readings to ThingSpeak and an n8n webhook.
It is a functional starter sketch, not a certified controller. Verify sensor readings and the circuit before connecting the fan or PV source.
9.1 Install the libraries
-
OneWire
-
DallasTemperature
-
Adafruit INA219
The Wi-Fi and HTTP libraries are provided by the ESP32 Arduino core.
9.2 Configure credentials
Replace the placeholder values with your own Wi-Fi, ThingSpeak, and n8n configuration. Keep API keys private and do not publish them in source repositories.
9.3 Arduino code
#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <Adafruit_INA219.h>
// -------- USER CONFIGURATION --------
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
const char* THINGSPEAK_WRITE_KEY = "YOUR_THINGSPEAK_WRITE_KEY";
const char* N8N_WEBHOOK_URL =
"https://YOUR_PUBLIC_N8N_HOST/webhook/solar-telemetry";
// For production, validate the HTTPS server certificate.
// Do not use insecure TLS mode in a deployed system.
// -------- HARDWARE --------
constexpr int ONE_WIRE_PIN = 4;
constexpr int FAN_PIN = 26;
OneWire oneWire(ONE_WIRE_PIN);
DallasTemperature temperatureBus(&oneWire);
Adafruit_INA219 ina219;
// -------- CONTROL SETTINGS --------
const float FAN_ON_C = 45.0;
const float FAN_OFF_C = 38.0;
const float CRITICAL_C = 60.0;
const unsigned long SAMPLE_MS = 2000;
const unsigned long UPLOAD_MS = 20000;
float panelC = NAN;
float ambientC = NAN;
float pvVoltage = NAN;
float pvCurrent = NAN;
float pvPower = NAN;
bool fanOn = false;
bool sensorFault = true;
unsigned long lastSample = 0;
unsigned long lastUpload = 0;
void connectWiFi() {
if (WiFi.status() == WL_CONNECTED) return;
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED &&
millis() - start < 15000) {
delay(250);
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("WiFi connected");
} else {
Serial.println("WiFi unavailable; local control continues");
}
}
bool validTemperature(float t) {
return !isnan(t) && t >= -40.0 && t <= 125.0;
}
void setFan(bool enabled) {
fanOn = enabled;
digitalWrite(FAN_PIN, enabled ? HIGH : LOW);
}
void readSensors() {
temperatureBus.requestTemperatures();
// The first and second sensors must be installed in this order
// OR replaced with explicit device-address lookups.
float p = temperatureBus.getTempCByIndex(0);
float a = temperatureBus.getTempCByIndex(1);
panelC = p;
ambientC = a;
sensorFault =
!validTemperature(panelC) ||
!validTemperature(ambientC) ||
panelC == DEVICE_DISCONNECTED_C ||
ambientC == DEVICE_DISCONNECTED_C;
float busVoltage = ina219.getBusVoltage_V();
float shuntVoltage = ina219.getShuntVoltage_mV() / 1000.0;
float current = ina219.getCurrent_mA() / 1000.0;
pvVoltage = busVoltage + shuntVoltage;
pvCurrent = current;
if (isfinite(pvVoltage) && isfinite(pvCurrent) &&
pvVoltage >= 0 && pvCurrent >= 0) {
pvPower = pvVoltage * pvCurrent;
} else {
pvPower = NAN;
}
}
void controlCooling() {
// Fail-safe example: keep fan running if temperature sensing fails.
// Validate this policy against the actual cooling hardware.
if (sensorFault) {
setFan(true);
return;
}
if (panelC >= FAN_ON_C) {
setFan(true);
} else if (panelC <= FAN_OFF_C) {
setFan(false);
}
if (panelC >= CRITICAL_C) {
Serial.println("CRITICAL: panel temperature threshold exceeded");
}
}
void sendThingSpeak() {
if (WiFi.status() != WL_CONNECTED) return;
WiFiClientSecure client;
client.setCACert(nullptr); // Replace with trusted root CA setup.
// IMPORTANT: configure a valid root certificate before production.
// Do not replace certificate validation with insecure TLS mode.
HTTPClient http;
if (!http.begin(client, "https://api.thingspeak.com/update.json")) {
Serial.println("ThingSpeak HTTPS setup failed");
return;
}
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
String body = "api_key=" + String(THINGSPEAK_WRITE_KEY);
body += "&field1=" + String(panelC, 2);
body += "&field2=" + String(ambientC, 2);
body += "&field3=" + String(pvVoltage, 2);
body += "&field4=" + String(pvCurrent, 3);
body += "&field5=" + String(pvPower, 2);
body += "&field6=" + String(fanOn ? 1 : 0);
body += "&field7=" + String(panelC - ambientC, 2);
body += "&field8=0"; // Replace with measured cooling power.
int code = http.POST(body);
String response = http.getString();
Serial.printf("ThingSpeak HTTP: %d, response: %s\n",
code, response.c_str());
http.end();
}
void sendN8n() {
if (WiFi.status() != WL_CONNECTED) return;
// Replace with a WiFiClientSecure configured with a trusted CA
// for production. This code deliberately fails closed until TLS
// verification is configured.
WiFiClientSecure client;
client.setCACert(nullptr);
HTTPClient http;
if (!http.begin(client, N8N_WEBHOOK_URL)) {
Serial.println("n8n HTTPS setup failed");
return;
}
http.addHeader("Content-Type", "application/json");
String payload = "{";
payload += "\"device_id\":\"solar-esp32-01\",";
payload += "\"panel_temp_c\":" + String(panelC, 2) + ",";
payload += "\"ambient_temp_c\":" + String(ambientC, 2) + ",";
payload += "\"voltage_v\":" + String(pvVoltage, 2) + ",";
payload += "\"current_a\":" + String(pvCurrent, 3) + ",";
payload += "\"power_w\":" + String(pvPower, 2) + ",";
payload += "\"fan_on\":" + String(fanOn ? "true" : "false") + ",";
payload += "\"sensor_fault\":" +
String(sensorFault ? "true" : "false");
payload += "}";
int code = http.POST(payload);
Serial.printf("n8n HTTP status: %d\n", code);
http.end();
}
void setup() {
Serial.begin(115200);
pinMode(FAN_PIN, OUTPUT);
setFan(false);
temperatureBus.begin();
Wire.begin(21, 22);
if (!ina219.begin()) {
Serial.println("INA219 not detected; verify I2C wiring");
}
connectWiFi();
Serial.println("AI Solar Cooling Monitor started");
}
void loop() {
unsigned long now = millis();
if (now - lastSample >= SAMPLE_MS) {
lastSample = now;
readSensors();
controlCooling();
Serial.printf(
"Panel: %.2f C | Ambient: %.2f C | V: %.2f V | "
"I: %.3f A | P: %.2f W | Fan: %s | Fault: %s\n",
panelC, ambientC, pvVoltage, pvCurrent, pvPower,
fanOn ? "ON" : "OFF",
sensorFault ? "YES" : "NO"
);
}
if (now - lastUpload >= UPLOAD_MS) {
lastUpload = now;
connectWiFi();
sendThingSpeak();
sendN8n();
}
delay(10);
}
9.4 Important firmware corrections before deployment
The sketch shows the integration points, but make these changes before treating it as a reliable controller:
-
TLS certificates:
setCACert(nullptr)is a placeholder, not a valid trust configuration. Load the appropriate trusted root CA certificate and check the certificate chain and hostname for each HTTPS service. As written, secure requests may fail. Never disable certificate verification on a production device. -
Temperature sensor ordering: DS18B20 index order is not guaranteed. For repeatable mounting, identify each probe's unique address and read it explicitly.
-
INA219 initialization: Check
ina219.begin()and prevent power measurements from being treated as valid if the sensor fails. -
Power measurement: Verify that the sensor is installed at the correct point in the PV circuit and that its shunt and current ratings are adequate.
-
Fail-safe behavior: The example turns the fan on when a temperature sensor fails. Confirm that this is safe for your actuator and thermal design; use independent over-temperature protection if required.
-
Watchdog and recovery: Add robust Wi-Fi reconnection, bounded retries, and persistent fault reporting.
-
Secrets: Store keys in a separate secrets file excluded from source control or use an appropriate provisioning method.
-
Cooling power: Replace the fixed zero value in ThingSpeak field 8 with a real measurement or clearly document that the field is unavailable.
-
Alert logic: Prevent repeated alerts from every upload. Use a cooldown and alert only when an event begins, escalates, or clears.
-
Sampling: Use a suitable sensor conversion interval and test how the DS18B20 reading behaves in your chosen resolution mode.
The official ThingSpeak Arduino examples demonstrate ESP32 field updates, multiple-field writes, and checking for successful HTTP responses.
10. n8n automation workflow
The workflow should perform deterministic checks before invoking AI. The AI Agent explains what is happening and recommends action; the ordinary rule engine determines whether a critical condition exists.
10.1 Main workflow diagram
flowchart TD
A[ESP32 sends JSON telemetry] --> B[n8n Webhook]
B --> C[Validate device and payload]
C --> D{Payload valid?}
D -- No --> E[Log invalid payload]
D -- Yes --> F[Normalize measurements]
F --> G[Calculate power and temperature difference]
G --> H[Rule-based threshold check]
H --> I[Append telemetry to Google Sheets]
H --> J[AI Agent analyzes readings]
J --> K[Structured recommendation]
K --> L{Critical event?}
L -- No --> M[Log status and recommendations]
L -- Yes --> N[Telegram urgent text alert]
N --> O[Text-to-speech service]
O --> P[Convert audio to Telegram voice format]
P --> Q[Telegram voice notification]
I --> R[Update event history]
M --> R
Q --> R
10.2 Create the workflow node by node
Node 1 — Webhook
Node type: Webhook
-
HTTP method:
POST -
Path:
solar-telemetry -
Response: return a JSON acknowledgment
-
Expected content: JSON
Test with the ESP32 payload shown below. Use HTTPS and authenticate the device in production.
Node 2 — Validate input
Node type: IF or Code
Confirm that the device ID is allowed, numeric values are finite and within plausible ranges, and the required fields exist. Reject invalid readings rather than sending them to the AI Agent.
Node 3 — Calculate and classify
Node type: Edit Fields or Code
Compute power if valid voltage and current are available. Calculate panel-to-ambient temperature difference and assign an operating state such as NORMAL, COOLING, WARNING, or SENSOR_FAULT.
Node 4 — AI Agent
Node type: AI Agent with a connected chat model
Provide the validated measurements, current cooling state, recent trend, and threshold configuration. Ask the model to return a short diagnosis and recommendation using a defined JSON schema.
Node 5 — Google Sheets
Node type: Google Sheets → Append Row
Log timestamp, device ID, sensor readings, power, fan state, alarm state, and AI recommendation. Use a separate worksheet for alarm events if desired.
Node 6 — Telegram notification
Node type: Telegram → Send Message
Send a concise message with the current panel temperature, PV power, fan state, and recommended action. Use a Switch or IF node to separate ordinary status messages from urgent alarms.
11. Webhook JSON format
The ESP32 sends telemetry to n8n in this format:
{
"device_id": "solar-esp32-01",
"panel_temp_c": 48.6,
"ambient_temp_c": 34.1,
"voltage_v": 18.2,
"current_a": 2.1,
"power_w": 38.22,
"fan_on": true,
"sensor_fault": false
}
In n8n, inspect the Webhook node's output to confirm whether the payload appears at $json.body or directly in $json. This can vary with the webhook configuration and node output. Map the subsequent nodes accordingly.
11.1 Example Code node
After validating the incoming JSON, use an n8n Code node to calculate a status. The example below assumes the payload is already available as the top-level JSON object.
const d = $json;
const required = [
"panel_temp_c",
"ambient_temp_c",
"voltage_v",
"current_a",
];
for (const key of required) {
if (typeof d[key] !== "number" || !Number.isFinite(d[key])) {
throw new Error(`Invalid measurement: ${key}`);
}
}
if (
d.panel_temp_c < -40 || d.panel_temp_c > 125 ||
d.ambient_temp_c < -40 || d.ambient_temp_c > 85 ||
d.voltage_v < 0 || d.current_a < 0
) {
throw new Error("Measurement outside configured limits");
}
const powerW = d.voltage_v * d.current_a;
const deltaT = d.panel_temp_c - d.ambient_temp_c;
let status = "NORMAL";
if (d.sensor_fault === true) {
status = "SENSOR_FAULT";
} else if (d.panel_temp_c >= 60) {
status = "CRITICAL";
} else if (d.panel_temp_c >= 45) {
status = "COOLING";
} else if (d.panel_temp_c >= 40) {
status = "WARNING";
}
return [{
json: {
...d,
calculated_power_w: powerW,
temperature_difference_c: deltaT,
status,
received_at: new Date().toISOString()
}
}];
The limits in this example are illustrative. Match them to the installed hardware and project configuration.
12. AI Agent design
The AI Agent should do more than rewrite a temperature value into natural language. It should analyze the trend, compare the current measurements with the expected behavior, and recommend a next diagnostic step.
12.1 Suggested AI system prompt
You are the diagnostic assistant for an AI solar panel cooling
and efficiency monitoring prototype.
Analyze only the validated telemetry and historical observations
provided to you.
Objectives:
1. Explain the current operating state.
2. Identify possible temperature or output anomalies.
3. Recommend practical diagnostic checks.
4. Evaluate whether the cooling system appears to be helping.
5. Avoid claiming a verified efficiency improvement without
comparable measurements and supporting evidence.
Rules:
- Do not invent sensor values, irradiance, or historical trends.
- Distinguish measured facts from possible explanations.
- A sensor fault must be treated as a fault, not as a valid
temperature measurement.
- Do not command pumps, relays, or other actuators directly.
- Never override the ESP32's local protection logic.
- Treat critical thresholds as configured rules, not AI guesses.
- Recommend checking shading, dust, wiring, sensor placement,
and cooling operation when relevant.
- If evidence is insufficient, say what additional measurement
is needed.
Return valid JSON with these keys:
{
"diagnosis": "short explanation",
"severity": "NORMAL | WARNING | CRITICAL | SENSOR_FAULT",
"recommendation": "next practical step",
"confidence": "LOW | MEDIUM | HIGH",
"evidence": "measurements supporting the diagnosis"
}
12.2 Example AI result
For a panel temperature of 48.6°C, ambient temperature of 34.1°C, power of 38.22 W, and fan ON:
{
"diagnosis": "Panel temperature is elevated relative to ambient.",
"severity": "WARNING",
"recommendation": "Verify fan airflow and compare power with a similar irradiance and load condition.",
"confidence": "MEDIUM",
"evidence": "Panel temperature 48.6 C; ambient temperature 34.1 C; fan reported ON."
}
This is an example output, not a live diagnosis from a connected panel.
12.3 Agentic behavior and safe autonomy
A practical agentic IoT system follows an observe–reason–recommend–verify loop:
-
Observe: Read current and historical sensor data.
-
Reason: Evaluate the temperature trend and power behavior.
-
Recommend: Suggest a cooling or diagnostic action.
-
Execute: Let the ESP32's deterministic local controller operate the fan.
-
Verify: Examine subsequent measurements to determine whether the condition improved.
-
Escalate: Notify the user when the condition remains critical or the sensor fails.
The AI should not be the only mechanism responsible for emergency cooling. Internet outages, model timeouts, and incorrect AI interpretations must not disable local protection.
13. Telegram text and voice notifications
Telegram supports text messages through its Bot API, and the API distinguishes ordinary audio files from voice messages. The sendVoice method supports voice-message uploads in a compatible format such as OGG/Opus.
13.1 Create a Telegram bot
-
Open Telegram and search for the official
@BotFather. -
Start a conversation and use
/newbot. -
Follow the instructions and copy the bot token.
-
Open the new bot and send
/start. -
Obtain the intended destination chat ID through the bot's updates or a suitable n8n Telegram trigger.
-
In n8n, create Telegram credentials and enter the bot token securely.
-
Send a test message to confirm that the destination is correct.
Never publish the bot token or allow untrusted webhook callers to trigger arbitrary Telegram messages.
13.2 Example alert message
☀️ AI SOLAR COOLING ALERT
Device: solar-esp32-01
Panel temperature: 48.6°C
Ambient temperature: 34.1°C
PV voltage: 18.2 V
PV current: 2.10 A
Measured PV power: 38.22 W
Cooling fan: ON
Status: WARNING
AI recommendation: Verify fan airflow and compare the electrical output with measurements taken under similar sunlight and load conditions.
The local ESP32 controller remains responsible for automatic cooling.
13.3 Voice-alert workflow
flowchart TD
A[Critical alarm detected] --> B[Build alert text]
B --> C[Text-to-speech API]
C --> D[Generate audio file]
D --> E{Compatible Telegram voice format?}
E -- No --> F[Convert to OGG Opus]
E -- Yes --> G[Telegram Send Voice]
F --> G
G --> H[Record alert event in Sheets]
For the text-to-speech node, use a compatible TTS provider or a self-hosted speech engine. If the provider returns MP3 audio, convert it to a Telegram-compatible OGG/Opus voice message before uploading it using a Telegram Bot API sendVoice request. Alternatively, use the Telegram node for text and an HTTP Request node for the voice upload.
Use voice alerts for critical temperature, persistent sensor failure, cooling failure, and severe output anomalies. Use text-only notifications for routine status updates to avoid unnecessary alert volume.
14. Google Sheets database
Google Sheets serves as the project's lightweight historical database. It can support performance analysis, event auditing, and a final project report.
14.1 Create the spreadsheet
Create a spreadsheet named AI Solar Cooling Data Log and add two worksheets.
Worksheet 1: Telemetry
|
Column |
Example |
|---|---|
|
Timestamp |
2026-10-18T16:30:00Z |
|
Device ID |
solar-esp32-01 |
|
Panel Temp (°C) |
48.6 |
|
Ambient Temp (°C) |
34.1 |
|
Voltage (V) |
18.2 |
|
Current (A) |
2.10 |
|
Power (W) |
38.22 |
|
Fan State |
ON |
|
Sensor Fault |
FALSE |
|
Status |
WARNING |
|
AI Recommendation |
Verify fan airflow |
Worksheet 2: Events
|
Timestamp |
Event |
Severity |
Action |
Resolved |
|---|---|---|---|---|
|
Example timestamp |
High temperature |
WARNING |
Fan activated |
No |
14.2 Configure Google Sheets in n8n
-
Add a Google Sheets node after payload validation and calculations.
-
Connect your Google account using the supported n8n credential flow.
-
Select the spreadsheet and
Telemetryworksheet. -
Choose Append Row.
-
Map each input field to the corresponding column.
-
Test the node and verify the new row appears.
-
Add a separate append-row operation to
Eventsfor alert transitions.
Use one row per telemetry sample and a separate event row when the system transitions into an alert. This makes it easier to distinguish repeated measurements from actual incidents.
For larger deployments, a time-series database may eventually be more suitable than a spreadsheet.
15. ThingSpeak IoT dashboard
ThingSpeak stores up to eight numeric channel fields, making it a good fit for this prototype.
15.1 Configure the visualizations
Create charts for:
-
Panel temperature over time.
-
Ambient temperature over time.
-
PV voltage and current.
-
PV output power.
-
Cooling state.
-
Panel-to-ambient temperature difference.
-
Cooling power consumption.
Keep measurement units in the field labels. A cooling-state field should use 0 = OFF and 1 = ON.
15.2 Example chart layout
Solar monitoring dashboard — example layout
PANEL TEMPERATURE
48.6°C
Illustrative reading
PV OUTPUT POWER
38.22 W
Illustrative reading
COOLING FAN
ON
Illustrative state
AMBIENT TEMPERATURE
34.1°C
Illustrative reading
Suggested time-series charts
Panel temperature (°C)
Ambient temperature (°C)
PV power (W)
These are illustrative dashboard values and layout, not live data from an actual device.
15.3 Display ThingSpeak charts on your webpage
Once the channel is configured, ThingSpeak provides chart embed options. For a private channel, use the supported private-view or read-key mechanism and avoid exposing write keys in browser code.
An example chart embed is:
<iframe
title="Solar panel temperature"
width="100%"
height="260"
style="border:1px solid #cccccc;"
src="https://thingspeak.com/channels/YOUR_CHANNEL_ID/charts/1?bgcolor=%23ffffff&color=%23d97706&dynamic=true&results=60">
</iframe>
Replace YOUR_CHANNEL_ID with your channel ID. For a public channel, this can display the chart without exposing the write key. For private telemetry, use an appropriately authenticated approach rather than making sensitive readings public.
16. Custom IoT webpage
A custom web interface can complement ThingSpeak by presenting status cards, sensor values, and alarm messages in one place.
A straightforward implementation is:
-
Front end: HTML, CSS, and JavaScript.
-
Telemetry source: ThingSpeak's read API.
-
Workflow status and AI recommendations: an authenticated n8n API endpoint or a small backend.
-
Hosting: a static website host or a web server.
-
Authentication: protect private device data and all control endpoints.
16.1 Webpage architecture
flowchart LR
A[ESP32] --> B[ThingSpeak]
A --> C[n8n webhook]
B --> D[Web dashboard]
C --> E[AI Agent]
E --> F[Recommendation API]
F --> D
C --> G[Google Sheets]
C --> H[Telegram alerts]
16.2 Basic HTML dashboard
This example reads the latest entry from a public ThingSpeak channel and displays the first six fields. It does not control hardware and does not display private AI recommendations.
