Skip to Content

← All functionalities

Automated agricultural irrigationRaspberry Pi (Docker)TelegramAlerts

A Telegram bot for irrigation alerts and remote control

The field is a 40-minute drive away; your phone is in your pocket. This Node-RED flow uses node-red-contrib-telegrambot on a Raspberry Pi to push alarm notifications and accept remote commands: /estado for a live status summary, /regar to force a cycle, /parar for an emergency stop. Only a whitelisted chat id is obeyed and the token lives in an environment variable. It is the exact remote-control layer of a real automated irrigation deployment.

Commands in, one function to rule them

A telegram receiver node feeds a parser function that whitelists the chat id (TELEGRAM_CHAT_ID environment variable) and normalizes the text into /estado, /regar, /parar or /alarmas. Anything else routes to a help reply. Unknown chats are dropped and logged — the bot simply does not exist for strangers, which matters when it can start a pump.

Status built from flow context

The /estado reply is assembled from values the other tabs already publish to flow context: whether a cycle is running, the latest photovoltaic surplus from the Fronius tab and the rain and frost forecast from the OpenWeather tab. No extra polling — the bot is a window into state the system maintains anyway, so replies are instant even over slow rural connections.

Alarms push themselves

When a supervised digital input trips, the same message that gets inserted into the MySQL history is formatted and pushed to the authorized chat with input name, message and local timestamp. The farmer learns about a pump thermal fault in seconds, not on the next visit to the field — usually before the water pressure has even settled.

A snippet from the implementation

Straight from the example as deployed on the Raspberry Pi (Docker) — copy it freely:

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`,

The full example is a complete program — wiring header, setup and main loop — ready to adapt to your application.

Frequently asked questions

How do I create the bot and get the token?

Talk to @BotFather on Telegram, create a new bot and copy the token into the TELEGRAM_TOKEN environment variable of the Node-RED container. Configure the telegrambot credentials node to read it from the environment instead of pasting it.

How do I find my chat id for the whitelist?

Send any message to your new bot and inspect msg.payload.chatId in a debug node, or query the getUpdates endpoint of the Bot API. Put that number in TELEGRAM_CHAT_ID and the parser will reject every other chat.

Is Telegram reliable enough for critical alarms?

Treat it as a notification channel, not a safety layer. Hardwired protections (thermal relays, pressure switches) still act locally; Telegram tells the human what already happened and lets them stop or start cycles remotely.

Related functionalities