chickencoop/ESP8266/main.ino
2025-06-10 01:05:32 +02:00

161 lines
4.4 KiB
C++

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include "secrets.h"
// --- WiFi & Telegram Config ---
const char* ssid = WIFI_SSID;
const char* password = WIFI_PASS;
const char* botToken = TELEGRAM_BOT_TOKEN;
const char* chatID = TELEGRAM_CHAT_ID;
WiFiClientSecure telegramClient;
// --- Timing ---
long lastUpdateId = 0;
unsigned long lastTelegramCheck = 0;
const unsigned long telegramCheckInterval = 10000; // 10 seconds
unsigned long lastLDRSend = 0;
const unsigned long ldrSendInterval = 5UL * 60UL * 1000UL; // 5 minutes
// --- Utility: URL Encode ---
String urlencode(const String& str) {
String encoded = "";
char c;
char code0, code1;
for (unsigned int i = 0; i < str.length(); i++) {
c = str.charAt(i);
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
encoded += c;
} else {
code1 = (c & 0xf) + '0';
if ((c & 0xf) > 9) code1 = (c & 0xf) - 10 + 'A';
c = (c >> 4) & 0xf;
code0 = c + '0';
if (c > 9) code0 = c - 10 + 'A';
encoded += '%';
encoded += code0;
encoded += code1;
}
}
return encoded;
}
// --- Telegram Messaging ---
void sendTelegramMessage(String message) {
if (WiFi.status() != WL_CONNECTED) return;
HTTPClient http;
String url = "https://api.telegram.org/bot" + String(botToken) +
"/sendMessage?chat_id=" + String(chatID) +
"&text=" + urlencode(message);
http.begin(telegramClient, url);
int httpCode = http.GET();
http.end();
}
// --- LDR Handling ---
void sendLDRToTelegram() {
Serial.write('R');
unsigned long start = millis();
String ldrValue = "";
while (millis() - start < 2000) { // wait up to 2 seconds
if (Serial.available()) {
ldrValue = Serial.readStringUntil('\n');
ldrValue.trim();
break;
}
}
if (ldrValue.length() > 0) {
sendTelegramMessage("Current LDR value: " + ldrValue);
} else {
sendTelegramMessage("Failed to read LDR value from Arduino.");
}
}
// --- Telegram Command Handling ---
void checkTelegramCommands() {
HTTPClient http;
String url = "https://api.telegram.org/bot" + String(botToken) +
"/getUpdates?offset=" + String(lastUpdateId + 1);
http.begin(telegramClient, url);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
DynamicJsonDocument doc(2048);
DeserializationError error = deserializeJson(doc, payload);
if (error) {
http.end();
return;
}
JsonArray results = doc["result"].as<JsonArray>();
for (JsonObject msg : results) {
lastUpdateId = msg["update_id"];
long fromId = msg["message"]["from"]["id"];
String text = msg["message"]["text"];
if (String(fromId) != chatID) {
continue;
}
if (text == "/open_chickencoop") {
Serial.write('O');
sendTelegramMessage("Opening chicken coop.");
} else if (text == "/close_chickencoop") {
Serial.write('C');
sendTelegramMessage("Closing chicken coop.");
} else if (text == "/ldr") {
sendLDRToTelegram();
} else {
sendTelegramMessage("Unknown command.");
}
}
}
http.end();
}
// --- Sync lastUpdateId on startup ---
void syncLastUpdateId() {
HTTPClient http;
String url = "https://api.telegram.org/bot" + String(botToken) + "/getUpdates";
http.begin(telegramClient, url);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
DynamicJsonDocument doc(4096);
DeserializationError error = deserializeJson(doc, payload);
if (!error) {
JsonArray results = doc["result"].as<JsonArray>();
for (JsonObject msg : results) {
long updateId = msg["update_id"];
if (updateId > lastUpdateId) lastUpdateId = updateId;
}
}
}
http.end();
}
// --- Setup ---
void setup() {
Serial.begin(9600);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
telegramClient.setInsecure();
syncLastUpdateId();
sendTelegramMessage("ESP8266 connected. IP: " + WiFi.localIP().toString());
}
// --- Main Loop ---
void loop() {
unsigned long now = millis();
if (now - lastTelegramCheck >= telegramCheckInterval) {
lastTelegramCheck = now;
checkTelegramCommands();
}
if (now - lastLDRSend >= ldrSendInterval) {
lastLDRSend = now;
sendLDRToTelegram();
}
}