← Bot de Telegram para riego: alertas y control remoto
Riego agrícola automatizadoRaspberry Pi (Docker)TelegramAlertas
Bot de Telegram para riego: alertas y control remoto — ejemplo completo
Controla el riego desde el móvil con un bot de Telegram en Node-RED: consulta de estado, arranque y paro remotos y notificaciones de alarma al instante.
Programa completo y ejecutable para el Raspberry Pi (Docker) (telegram-bot-alarms-control.js): incluye cabecera de conexionado, requisitos y notas de integración.
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales
Vista de solo lectura.
/*
* COMPLETE EXAMPLE — Notifications and remote control via Telegram bot (Node-RED)
*
* Hardware: Raspberry Pi (Docker) with Node-RED
* Based on: automated agricultural irrigation project
*
* Requirements:
* - Palette: node-red-contrib-telegrambot.
* - Bot created with @BotFather; the token is stored in the container's
* TELEGRAM_TOKEN environment variable (configure the credentials node
* with ${TELEGRAM_TOKEN}), never in the exported flow.
* - Authorized chat_id in the TELEGRAM_CHAT_ID environment variable.
*
* Flow wiring (tab "Telegram"):
*
* COMMAND INPUT:
* [telegram receiver] --> [function A: parse command] --> [switch msg.cmd]
* /status --> [function B: reply with status] --> [telegram sender]
* /irrigate --> [change: msg.mode="manual"] --> (to Irrigation Logic)
* /stop --> [function C: stop command] --> (to Modbus VFD)
* other --> [function B with help text] --> [telegram sender]
*
* ALARM OUTPUT:
* (alarm detection, Alarms tab) --> [function D: format alarm]
* --> [telegram sender]
*/
// ===========================================================================
// FUNCTION A — "Parse command"
// Filters by authorized chat and normalizes the received command.
// ===========================================================================
const AUTHORIZED_CHAT = Number(env.get("TELEGRAM_CHAT_ID"));
const chatId = msg.payload.chatId;
const text = (msg.payload.content || "").trim().toLowerCase();
if (chatId !== AUTHORIZED_CHAT) {
// Unknown chat: ignore it and leave a trace in the log
node.warn(`Command rejected from unauthorized chat: ${chatId}`);
return null;
}
const COMMANDS = ["/status", "/irrigate", "/stop", "/alarms"];
msg.cmd = COMMANDS.includes(text.split("@")[0]) ? text.split("@")[0] : "help";
msg.chatId = chatId;
return msg;
// ===========================================================================
// FUNCTION B — "Reply with status"
// Reads from context the latest values published by the other tabs.
// ===========================================================================
/*
const irrigationActive = flow.get("irrigation_active") || false;
const weather = flow.get("last_weather") || {};
const photovoltaic = flow.get("last_pv") || {}; // from the Fronius tab
const lines = [
irrigationActive ? "🟢 Irrigation RUNNING" : "⚪ Irrigation stopped",
`PV: ${photovoltaic.generated_w || "?"} W generated, ` +
`${photovoltaic.surplus_w || "?"} W of surplus`,
`Weather: ${weather.rain_24h_mm ?? "?"} mm forecast / ` +
`minimum ${weather.min_temp_c ?? "?"} ºC`,
];
if (msg.cmd === "help") {
lines.push("", "Commands: /status /irrigate /stop /alarms");
}
msg.payload = {
chatId: msg.chatId,
type: "message",
content: lines.join("\n"),
};
return msg;
*/
// ===========================================================================
// FUNCTION C — "Stop command"
// Cuts the cycle in progress and confirms via Telegram.
// ===========================================================================
/*
flow.set("irrigation_active", false);
node.warn("Remote stop requested via Telegram");
// Output 1: command to the VFD (Modbus tab) — ramp stop
const vfdCommand = { topic: "irrigation/vfd", payload: { command: "stop" } };
// Output 2: confirmation to the user
const confirmation = {
payload: {
chatId: msg.chatId,
type: "message",
content: "⏹ Irrigation stopped manually",
},
};
return [vfdCommand, confirmation]; // function node with 2 outputs
*/
// ===========================================================================
// FUNCTION D — "Format alarm"
// Receives the already detected alarm (digital input + definition in MySQL)
// and sends it to the authorized chat. The same msg is inserted into the history.
// ===========================================================================
/*
const a = msg.payload; // { input: "I3", message: "Pump thermal fault", ... }
msg.payload = {
chatId: Number(env.get("TELEGRAM_CHAT_ID")),
type: "message",
content: `🚨 ALARM [${a.input}] ${a.message}\n${new Date().toLocaleString("en-GB")}`,
};
return msg;
*/
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales