Cara Terhubung Dengan Bot Telegram Pada ESP32

Cara Terhubung Dengan Bot Telegram Pada ESP32

Bot Telegram adalah aplikasi otomatis yang berjalan di platform Telegram dan dapat berinteraksi dengan pengguna melalui pesan, perintah, atau bahkan dalam bentuk interaksi berbasis API.Berikut adalah cara menghubungkan esp32 ke bot telegram :

#include <Arduino.h>

#include <ArduinoJson.h>
#include <EEPROM.h>
#ifdef ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

extern const char* default_nama_ssid = "wifi-iot";
extern const char* default_password = "password-iot";
extern const char* default_server = "http://labrobotika.go-web.my.id/server.php?apikey=";
extern const char* default_apikey = "12345678";
String nama_ssid;
String password;
String server_url;
String apikey;
AsyncWebServer server(80);
int reset_default = 0;
//Initialize Telegram BOT
String BOTtoken = "5687845203:AAFC_OnUr_ZwCKrd4YEitYjZ7xiK1fscv9c";  // your Bot Token (notif tele)
String CHAT_ID = "isi";
WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);
 
// Checks for new messages every 1 second.
int botRequestDelay = 1000;
unsigned long lastTimeBotRan;


void debug(String message, int row = 0, int clear = 1) {
  Serial.println(message);
  //tampilkan jika menggunakan lcd
  if (clear == 0) {
    lcd.clear();
  }
  lcd.setCursor(0, row);
  lcd.print(message);
}
void writeStringToEEPROM(int address, const String &str) {
  int len = str.length();
  EEPROM.write(address, len);
  for (int i = 0; i < len; i++) {
    EEPROM.write(address + 1 + i, str[i]);
  }
}
String readStringFromEEPROM(int address) {
  int len = EEPROM.read(address);
  char data[len + 1];
  for (int i = 0; i < len; i++) {
    data[i] = EEPROM.read(address + 1 + i);
  }
  data[len] = '\0';
  return String(data);
}
void saveCredentialsToEEPROM() {
  EEPROM.begin(512);
  writeStringToEEPROM(0, nama_ssid);
  writeStringToEEPROM(64, password);
  writeStringToEEPROM(128, server_url);
  writeStringToEEPROM(192, apikey);
  EEPROM.commit();
  debug("Konfigurasi yang disimpan ke EEPROM:");
  debug("nama_ssid: " + nama_ssid);
  debug("Password: " + password);
  debug("Server URL: " + server_url);
  debug("API Key: " + apikey);
}
void loadCredentialsFromEEPROM() {
  
  EEPROM.begin(512);
  nama_ssid = readStringFromEEPROM(0);
  password = readStringFromEEPROM(64);
  server_url = readStringFromEEPROM(128);
  apikey = readStringFromEEPROM(192);
  if (nama_ssid.length() == 0) {
    nama_ssid = default_nama_ssid;
    debug("SSID Default.");
  } else {
   debug("SSID EEPROM.");
  }
  if (password.length() == 0) password = default_password;
  if (server_url.length() == 0) server_url = default_server;
  if (apikey.length() == 0) apikey = default_apikey;
 
Serial.println("SSID LENGTH : " + (String)nama_ssid.length());
  if (nama_ssid.length() > 250 || reset_default==1) {
    debug("NOVALID:" + nama_ssid );
    delay(3000);
    debug("RESET DEFAULT...");
    nama_ssid = default_nama_ssid;
    password = default_password;
    server_url = default_server;
    apikey = default_apikey;
    saveCredentialsToEEPROM();
    delay(1000);
    debug("ESP RESTART...");
    delay(1000);
    ESP.restart();
  }
  else
  {
    debug("SSID :" + nama_ssid);
    delay(1000);
    debug("PASS :" + password);
    delay(1000);
    debug("URL :" + server_url);
    delay(1000);
    debug("API :" + apikey);
    delay(1000);
  }
}
void setupWiFi() {
  WiFi.begin(nama_ssid.c_str(), password.c_str());
 client.setCACert(TELEGRAM_CERTIFICATE_ROOT); //sertifikat telegram bot
  int attempts = 0;
  while (WiFi.status() != WL_CONNECTED && attempts < 10) {
   
 delay(2000);
    debug("Connect Wi-Fi (" + (String)attempts + ")");
    attempts++;
  }
  if (WiFi.status() == WL_CONNECTED) {
    debug("Terhubung ke Wi-Fi");
    debug("ssid: " + String(WiFi.SSID()));
    debug("IP: " + WiFi.localIP().toString());
delay(1000);
debug("System Ready");
proses_iot("");
    
  } else {
//lcd.clear();
 
    debug("Gagal terhubung");
delay(2000);
   debug("Beralih mode AP");
    delay(2000);
 
    debug("Gagal terhubung..");
    WiFi.softAP("wifi-ESP");
    debug("AP: Wifi-ESP");
    delay(5000);
    debug("IP:" + WiFi.softAPIP().toString());
debug("Buka di Browser ",1,0);
  
delay(2000);
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      String nama_ssidValue = (nama_ssid.length() > 0) ? nama_ssid : default_nama_ssid;
      String passwordValue = (password.length() > 0) ? password : default_password;
      String serverValue = (server_url.length() > 0) ? server_url : default_server;
      String apiKeyValue = (apikey.length() > 0) ? apikey : default_apikey;
      String htmlContent = R"(
        <!DOCTYPE html>
        <html>
        <head>
          <title>ESP32 WiFi Configuration</title>
          <style>
            body {
              font-family: Arial, sans-serif;
              margin: 20px;
            }
            input[type="text"],
            input[type="password"] {
              width: 100%;
              padding: 10px;
              margin: 5px 0;
              display: inline-block;
              border: 1px solid #ccc;
              border-radius: 4px;
              box-sizing: border-box;
            }
          
            input[type="submit"]:hover {
              background-color: #45a049;
            }
            .container {
              padding: 20px;
              border-radius: 5px;
              background-color: #f2f2f2;
            }
          </style>
        </head>
        <body>
          <div style="max-width: 600px; margin: 20px auto; padding: 20px; border: 1px solid #ccc; border-radius: 5px; background-color: #f9f9f9;">
            <div class="container">
              <h2>ESP WiFi Configuration</h2>
              <form action="/save" method="post">
                <label for="nama_ssid">WiFi SSID:</label>
                <input type="text" id="nama_ssid" name="nama_ssid" value=")" + nama_ssidValue + R"(" required><br>
                <label for="password">WiFi Password:</label>
                <input type="text" id="password" name="password" value=")" + passwordValue + R"(" required><br>
                <label for="server">Server URL:</label>
                <input type="text" id="server" name="server" value=")" + serverValue + R"(" required><br>
                <label for="apikey">API Key:</label>
                <input type="text" id="apikey" name="apikey" value=")" + apiKeyValue + R"(" required><br>
               <input  style=" width: 100%;color: #fff; background-color: green; padding: 10px 20px; text-decoration: none; border-radius: 4px;" type="submit" value="SAVE CONFIGURATION">
              </form>
              <br>
              <br>
              Kembali Ke pengaturan Awal :
             <a href="/reset" style="color: #fff; background-color: red; padding: 10px 20px; text-decoration: none; border-radius: 4px;">RESET DEFAULT</a>
            </div>
          </div>
        </body>
        </html>
      )";
      request->send(200, "text/html", htmlContent);
    });
    server.on("/save", HTTP_POST, [](AsyncWebServerRequest *request){
      if(request->args() > 0){ // Pastikan ada argumen yang disampaikan
        for(uint8_t i = 0; i < request->args(); i++){
          if(request->argName(i) == "nama_ssid"){
            nama_ssid = request->arg(i);
          } else if(request->argName(i) == "password"){
            password = request->arg(i);
          } else if(request->argName(i) == "server"){
            server_url = request->arg(i);
          } else if(request->argName(i) == "apikey"){
            apikey = request->arg(i);
          }
        }
        saveCredentialsToEEPROM(); // Simpan konfigurasi ke EEPROM
        request->send(200, "text/html", R"(
          <div style="max-width: 600px; margin: 20px auto; padding: 20px; border: 1px solid #ccc; border-radius: 5px; background-color: #f9f9f9;">
            <h2 style="color: #4CAF50;">Konfigurasi Berhasil Disimpan</h2>
            <p><br>Klik tombol dibawah ini untuk restart esp <br><br><br><a href="/restart" style="color: #fff; background-color: #4CAF50; padding: 10px 20px; text-decoration: none; border-radius: 4px;">RESTART ESP</a></p>
          </div>
        </body>
        )");
      } else {
        request->send(400, "text/html", "Bad Request: Tidak ada data yang disampaikan.");
      }
    });
    server.on("/reset", HTTP_GET, [](AsyncWebServerRequest *request){
      
          nama_ssid = default_nama_ssid;
            password = default_password;
            server_url = default_server;
            apikey = default_apikey;
            saveCredentialsToEEPROM(); 
        request->send(200, "text/html", R"(
          <div style="max-width: 600px; margin: 20px auto; padding: 20px; border: 1px solid #ccc; border-radius: 5px; background-color: #f9f9f9;">
            <h2 style="color: RED;">Konfigurasi Berhasil Di Reset</h2>
            <p><br>Klik tombol dibawah ini untuk restart esp <br><br><br><a href="/restart" style="color: #fff; background-color: red; padding: 10px 20px; text-decoration: none; border-radius: 4px;">RESTART ESP</a></p>
          </div>
        )");
     
    });
    server.on("/restart", HTTP_GET, [](AsyncWebServerRequest *request){
   
      request->send(200, "text/html", R"(
        <head>
  <meta http-equiv="refresh" content="5;url=/">
</head>
<body>
  <div style="max-width: 600px; margin: 20px auto; padding: 20px; border: 1px solid #ccc; border-radius: 5px; background-color: #f9f9f9;">   
    <p><br>ESP Restart... <br><br></p>
  </div>
</body>
        )");
        
      delay(1000); // Tambahkan jeda sebelum merestart
      ESP.restart(); // Restart ESP
      request->redirect("/");
    });
  }
  server.begin();
}
int looping_iot = 0;
int out_1 = 0;
int out_2 = 0;
int out_3 = 0;
int out_4 = 0;
int out_5 = 0;
int out_6 = 0;
int out_7 = 0;
int out_8 = 0;
int out_9 = 0;
int out_10 = 0;
void proses_iot(String nilai) {
  if (WiFi.status() != WL_CONNECTED) return;
  
  WiFiClient client;
  HTTPClient http;
  String url = server_url + apikey + nilai; // Menggunakan server_url
  url.replace(" ", "%20");
  Serial.println("Request URL: " + url);
  http.begin(client, url);
  int httpResponseCode = http.GET();
  if (httpResponseCode == HTTP_CODE_OK) {
    const size_t capacity = JSON_OBJECT_SIZE(1024);
    DynamicJsonDocument jsonDoc(capacity);
    String jsonResponse = http.getString();
    DeserializationError error = deserializeJson(jsonDoc, jsonResponse);
    if (error) {
      Serial.println("Error parsing JSON: " + String(error.c_str()));
      return;
    }
    for (int i = 1; i <= 10; i++) {
      String out = jsonDoc["out_" + String(i)].as<String>();
      Serial.println("out_" + String(i) + ": " + out);
    }
   out_1 = jsonDoc["out_1"].as<int>();
    out_2 = jsonDoc["out_2"].as<int>();
    out_3 = jsonDoc["out_3"].as<int>();
    out_4 = jsonDoc["out_4"].as<int>();
    out_5 = jsonDoc["out_5"].as<int>();
    out_6 = jsonDoc["out_6"].as<int>();
    out_7 = jsonDoc["out_7"].as<int>();
    out_8 = jsonDoc["out_8"].as<int>();
    out_9 = jsonDoc["out_9"].as<int>();
    out_10 = jsonDoc["out_10"].as<int>();
  } else {
    Serial.println("Error Code: " + String(httpResponseCode));
  }
  http.end();
}


void setup()
{
Serial.begin(9600);
EEPROM.begin(512);
//BERI NILAI 1 JIKA MAU DIRESET (PERTAMA UPLOAD WAJIB RESET)
reset_default = 0;
loadCredentialsFromEEPROM();
setupWiFi();
CHAT_ID = String(out_10); // jika ID CHAT ada di web
  bot.sendMessage(CHAT_ID, "Power ON");

}
void loop(){
if (WiFi.status() == WL_CONNECTED) {} //masukan semua logic loop kedalam ini
 
if (looping_iot > 20)
{
 proses_iot("");
  looping_iot = 0;
}
else
{
  looping_iot = looping_iot +1;
  Serial.println("Looping IOT : " + (String)looping_iot);
}
delay(500);


}

Berikut ini adalah penjelasan dari kode di atas :

Kode yang Anda berikan adalah untuk mengkonfigurasi dan mengelola koneksi Wi-Fi, interaksi dengan server eksternal, serta kontrol perangkat IoT (Internet of Things) dengan menggunakan ESP32 atau ESP8266. Kode ini memungkinkan pengguna untuk mengatur SSID Wi-Fi, password, server URL, dan API key melalui antarmuka web, serta memanfaatkan Telegram Bot untuk memberi notifikasi.

Mari kita bahas kode ini bagian per bagian:

1. Library yang Digunakan

#include <Arduino.h>
#include <ArduinoJson.h>
#include <EEPROM.h>
#ifdef ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
  • ArduinoJson.h: Digunakan untuk parsing dan membuat data JSON.
  • EEPROM.h: Untuk menyimpan dan membaca data konfigurasi (seperti SSID, password, URL, API Key) ke/dari memori EEPROM.
  • WiFi.h dan ESP8266WiFi.h: Digunakan untuk menghubungkan perangkat ke jaringan Wi-Fi. Tergantung pada apakah menggunakan ESP32 atau ESP8266.
  • HTTPClient.h dan ESP8266HTTPClient.h: Digunakan untuk membuat request HTTP (misalnya GET atau POST).
  • ESPAsyncWebServer.h: Digunakan untuk membuat server web asinkron di ESP32/ESP8266.
  • WiFiClientSecure.h: Untuk membuat koneksi yang aman (SSL) dengan server, digunakan untuk Telegram bot.
  • UniversalTelegramBot.h: Digunakan untuk berinteraksi dengan Telegram Bot API.

2. Konfigurasi Awal dan Variabel Global

extern const char* default_nama_ssid = "wifi-iot";
extern const char* default_password = "password-iot";
extern const char* default_server = "http://labrobotika.go-web.my.id/server.php?apikey=";
extern const char* default_apikey = "12345678";
String nama_ssid;
String password;
String server_url;
String apikey;
AsyncWebServer server(80);
int reset_default = 0;
  • Beberapa variabel dan alamat default untuk SSID, password, server URL, dan API Key.
  • AsyncWebServer server(80);: Membuat server web yang berjalan di port 80.
  • reset_default: Variabel untuk menandakan jika konfigurasi default perlu di-reset.

3. Fungsi debug()

void debug(String message, int row = 0, int clear = 1) {
  Serial.println(message);
  // tampilkan jika menggunakan lcd
  if (clear == 0) {
    lcd.clear();
  }
  lcd.setCursor(0, row);
  lcd.print(message);
}

Fungsi debug() digunakan untuk mencetak pesan ke Serial Monitor dan juga bisa menampilkan pesan ke layar LCD (jika ada). Bisa membersihkan layar LCD jika diperlukan.

4. Fungsi untuk Menyimpan dan Membaca Data dari EEPROM

void writeStringToEEPROM(int address, const String &str) { ... }
String readStringFromEEPROM(int address) { ... }
  • writeStringToEEPROM(): Menyimpan string ke EEPROM pada alamat tertentu.
  • readStringFromEEPROM(): Membaca string dari EEPROM mulai dari alamat tertentu.

5. Menyimpan dan Membaca Konfigurasi dari EEPROM

void saveCredentialsToEEPROM() { ... }
void loadCredentialsFromEEPROM() { ... }
  • saveCredentialsToEEPROM(): Menyimpan SSID, password, server URL, dan API Key ke EEPROM.
  • loadCredentialsFromEEPROM(): Membaca data konfigurasi dari EEPROM dan mengatur SSID, password, server URL, dan API Key berdasarkan data yang disimpan.

6. Fungsi Setup Wi-Fi

void setupWiFi() { ... }

Fungsi setupWiFi() mencoba untuk menghubungkan perangkat ke jaringan Wi-Fi menggunakan SSID dan password yang telah disimpan. Jika koneksi gagal, perangkat akan beralih ke mode AP (Access Point) di mana pengguna bisa mengonfigurasi ulang jaringan Wi-Fi melalui halaman web.

7. Antarmuka Web untuk Pengaturan

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ ... });

Pada bagian ini, server web menampilkan halaman HTML untuk mengonfigurasi Wi-Fi SSID, password, server URL, dan API Key. Halaman ini dapat diakses melalui perangkat yang terhubung ke Wi-Fi AP yang dibuat oleh ESP jika tidak dapat terhubung ke jaringan Wi-Fi.

8. Formulir Pengaturan

<form action="/save" method="post"> ... </form>

Formulir ini memungkinkan pengguna untuk memasukkan data Wi-Fi, server URL, dan API Key. Setelah data dimasukkan dan dikirimkan, data tersebut akan disimpan ke dalam EEPROM dan server ESP32 akan memberikan konfirmasi bahwa pengaturan berhasil disimpan.

9. Reset Pengaturan ke Default

server.on("/reset", HTTP_GET, [](AsyncWebServerRequest *request){ ... });

Halaman web juga memungkinkan pengguna untuk mereset pengaturan ke nilai default dengan menekan tombol “RESET DEFAULT”. Pengaturan SSID, password, server URL, dan API Key akan dikembalikan ke nilai default.

10. Mengirimkan Notifikasi ke Telegram

String BOTtoken = "5687845203:AAFC_OnUr_ZwCKrd4YEitYjZ7xiK1fscv9c";  // your Bot Token
String CHAT_ID = "isi"; // ID Chat Telegram
UniversalTelegramBot bot(BOTtoken, client);
  • Telegram Bot diinisialisasi untuk mengirimkan notifikasi. Bot akan memberi tahu jika ESP telah dinyalakan dengan mengirimkan pesan “Power ON” ke CHAT_ID Telegram yang ditentukan.

11. Fungsi proses_iot()

void proses_iot(String nilai) { ... }

Fungsi ini mengirimkan request HTTP GET ke server eksternal (URL yang disimpan dalam EEPROM) dan menerima data dalam format JSON. Data yang diterima akan diproses, dan beberapa output yang ditentukan dalam JSON akan diambil dan disimpan dalam variabel (misalnya out_1, out_2, dll).

12. Fungsi setup()

void setup() { ... }
  • EEPROM.begin(512);: Inisialisasi EEPROM dengan kapasitas 512 byte.
  • loadCredentialsFromEEPROM();: Membaca konfigurasi yang disimpan di EEPROM.
  • setupWiFi();: Menyambungkan perangkat ke Wi-Fi.
  • bot.sendMessage(CHAT_ID, "Power ON");: Mengirimkan pesan “Power ON” ke Telegram ketika perangkat dinyalakan.

13. Looping IoT

void loop() { ... }

Pada loop(), perangkat akan secara berkala melakukan pengecekan dan pemrosesan data dengan server eksternal menggunakan fungsi proses_iot(). Jika kondisi tertentu terpenuhi (misalnya, setelah 20 kali loop), maka data IoT akan diproses dan output akan diperbarui.


untuk diskusi bisa kontak dibawah ini :

Sosial media :

Apa itu ESP32?