Automatic Plant Watering Messenger (using Telegram)
by sipandrei in Living > Gardening
461 Views, 4 Favorites, 0 Comments
Automatic Plant Watering Messenger (using Telegram)
This is a quick and easy IOT project, that I've made at the request of my girlfriend, which helps you remember to water your much loved plants by sending messages via a Telegram bot, giving you a more hand-on experience than an automatic pump.
It works by connecting to a WiFi network(using the WiFiManager arduino library) and then sending messages through a Telegam bot depending on the moisture level of the soil.
This project requires you to have two environment variables:
- PLANT_NOTE_BOT - the telegram bot api key
- CHAT_ID - the ID of the chat in which you want it to send messages
- BOT_NAME - name of the bot
Here is a link for the GitHub repo - https://github.com/sipandrei/espPlantNotificationBot
Supplies
For this project you need two components and some jumper wires:
- an ESP8266 develompent board
- a soil moisture sensor(i recommend a capacitive one because it does not rust)
You will also need acces to a power socket and a WiFi connection
Doing the Wiring
Starting out easy with connecting our two components!
The moisture sensor has three wires, one positive, one negative and a signal wire
- Connect the positive cable(+) to the 5V pin on your development board
- Connect the negative cable(-) to the GND pin on your development board
- Connect the signal wire to an analog pin(in my code that is A0)
Installing the Libraries
This project uses a couple of libraries that you need to install:
- Universal Telegram Bot - https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot - zip file
- WiFiManager - https://github.com/tzapu/WiFiManager - library manager
- ArduinoJson - https://github.com/bblanchon/ArduinoJson - library manager
For the library manager do this:
Sketch -> Include Libraries -> Manage Libraries
For .Zip libraries do this:
Sketch -> Include Libraries -> Add .ZIP Library
Set Up the Telegram Bot
For this you will need a telegram account - https://web.telegram.org/
Make a new bot using @BotFather
Set up the commands:
- for adjusting the minimum soil humidity : /setmin
- for getting a humidity reading: /humidity
Set Up the Environment Variables
I am using the Arduino IDE so i used environment variables by defining them inside a header file that I have placed in the libraries folder and then included it in the project.
The credentials.h file should have this structure:
#define PLANT_NOTE_BOT "<the api key of the bot from BotFather>"
#define CHAT_ID "<the id of the chat in which you want your bot to send messages>"
#define BOT_NAME "<the name of the robot you created>"
Program the Development Board
And now, the last big step is programming the board by uploading the following code:
#include <UniversalTelegramBot.h>
#include <WiFiClientSecure.h>
#include <WiFiManager.h>
#include <credentials.h>
#include <ArduinoJson.h>
X509List cert(TELEGRAM_CERTIFICATE_ROOT);
WiFiClientSecure secured_client;
UniversalTelegramBot bot(PLANT_NOTE_BOT, secured_client);
const unsigned long SCAN_DELAY = 1000;
unsigned long lastScan;
extern "C"
{
#include <lwip/icmp.h> // needed for icmp packet definitions
}
int soilSensorInput, soilSensorPercentage;
int baselineAir = 680;
int baselineWater = 280;
int minimumPercentage = 35;
bool watered = true;
bool waitMin = false;
IPAddress local_IP(192, 168, 100, 36);
IPAddress gateway(192,168,100,1);
IPAddress subnet(255,255,255,0);
IPAddress dns(8,8,8,8);
const int DNS_PORT = 53;
void percentageLimiter(int &percentageReading){
if(percentageReading < 0)
percentageReading = 0;
else if(percentageReading > 100)
percentageReading = 100;
}
void configModeCallback(WiFiManager *wifiManager){
Serial.println("entered config mode");
Serial.println(WiFi.softAPIP());
}
void messagesHandler(int numNewMessages){
Serial.printf("\n Received %d new messages \n", numNewMessages);
String response;
for(int i = 0; i < numNewMessages; i++){
telegramMessage &msg = bot.messages[i];
Serial.print("Message " + msg.text);
Serial.print(numNewMessages);
Serial.print(i);
if(msg.text == "/setmin" || msg.text == "/setmin@plantnote_bot"){
waitMin = true;
response = "Set the minimum humidity by replying with a number between 5 and 90";
} else if(msg.text.toInt() >= 5 && msg.text.toInt() <= 90 && waitMin == true){
waitMin = false;
minimumPercentage = msg.text.toInt();
response = "Minimum percentage set to " + msg.text;
} else if(msg.text == "/humidity" || msg.text == "/humidity@plantnote_bot"){
response = "Current humidity is " + String(soilSensorPercentage) + "%";
} else {
response = "That was not a valid input";
}
bot.sendMessage(msg.chat_id, response, "Markdown");
}
}
void setup() {
WiFi.mode(WIFI_STA);
WiFiManager wifiManager;
bool res;
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("");
wifiManager.setAPCallback(configModeCallback);
wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
res = wifiManager.autoConnect(BOT_NAME);
Serial.println(WiFi.localIP());
if(!res){
Serial.print("DID NOT CONNECT");
ESP.restart();}
else {
secured_client.setTrustAnchors(&cert);
Serial.print("Retrieving time: ");
configTime(0, 0, "pool.ntp.org"); // get UTC time via NTP
time_t now = time(nullptr);
while (now < 24 * 3600)
{
Serial.print(".");
delay(100);
now = time(nullptr);
}
Serial.println(now);
Serial.print("Sending message to ");
Serial.println(CHAT_ID);
bot.sendMessage(CHAT_ID, "Plant bot started, minimum moisture - 35%", "");
}
}
void loop() {
soilSensorInput = analogRead(A0);
soilSensorPercentage = map(soilSensorInput,baselineAir,baselineWater, 0, 100);
percentageLimiter(soilSensorPercentage);
if(millis() - lastScan > SCAN_DELAY){
int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
Serial.print(numNewMessages);
while (numNewMessages)
{
Serial.println("got response");
messagesHandler(numNewMessages);
numNewMessages = bot.getUpdates(bot.last_message_received + 1);
}
Serial.print(numNewMessages);
lastScan = millis();
}
if(waitMin == false){
if(soilSensorPercentage < minimumPercentage && watered == true){
watered = false;
Serial.print("Plant needs water!! Current humidity: ");
Serial.println(soilSensorPercentage);
bot.sendMessage(CHAT_ID, "*ALERT!! PLANT NEEDS WATER!!* Current percentage: ", "Markdown");
bot.sendMessage(CHAT_ID, String(soilSensorPercentage),"");
} else if(soilSensorPercentage >= minimumPercentage && watered == false){
watered = true;
Serial.print("Plant plant *watered*! Current humidity: ");
Serial.println(soilSensorPercentage);
bot.sendMessage(CHAT_ID, "Plant *watered*!", "");
}
}
}
Connect the Device to Wifi
Now that you have uploaded the code you need to connect the cot to the internet, that can be done by connecting to the acces point with the name of your bot, from your phone, and then access the WiFiManager portal, either by being automatically redirected or by accessing it at the address:
10.0.1.1
From there you will be able to connect to the home WiFi network
Use It!
Now that you have a fully functional bot all you need to do is to place the sensor in the soil near the plant and plug it in!
If the connection to the WiFi succeeds you will get a notification on Telegram saying Plant bot started, minimum moisture - 35%
The bot will automatically send a telegram message if the moisture of the soil gets below the threshold, which can be modified with the command:
/setmin
and then replying to the message it sends with a number from 5 to 90
You can also get the current moisture by sending this command:
/humidity
After you water the plant you also get a message for confirmation