Created
February 8, 2025 08:23
-
-
Save kvv69/dd3113a1ed358169b2b93779df60e6a9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Режим Wi-Fi: Установлен режим WIFI_AP_STA, чтобы ESP8266 могла быть одновременно точкой доступа и клиентом. | |
Создание точки доступа: Используется функция WiFi.softAP(AP_SSID, AP_PASSWORD) для создания точки доступа. | |
Логирование: Добавлены сообщения в Serial Monitor для отладки (SSID, пароль и IP-адрес точки доступа). | |
Как это работает: | |
При запуске ESP8266 создает точку доступа с именем ESP8266_AP и паролем 12345678. | |
Одновременно устройство подключается к указанной Wi-Fi сети. | |
Вы можете подключиться к точке доступа с любого устройства (например, смартфона или ноутбука) и управлять устройством через Telegram-бота. | |
*/ | |
#include <ESP8266WiFi.h> | |
#include <WiFiClientSecureBearSSL.h> | |
#include <UniversalTelegramBot.h> | |
#include <Adafruit_NeoPixel.h> | |
#include <OneWire.h> | |
#include <DallasTemperature.h> | |
#include <ArduinoJson.h> | |
// Настройки Wi-Fi и Telegram-бота | |
const char* ssid = "**-****_****"; // Название сети | |
const char* password = "********"; // Пароль сети | |
const String BOTtoken = "********:******************************"; // Токен Telegram бота | |
const String YOUR_CHAT_ID = "***********"; // Замените на ваш chat_id | |
// Настройки точки доступа | |
const char* AP_SSID = "ESP8266_AP"; // Имя точки доступа | |
const char* AP_PASSWORD = "12345678"; // Пароль точки доступа (минимум 8 символов) | |
// Массив с ID пользователей | |
const char* CHAT_IDS[] = {"**********", "**********", "**********"}; | |
const int NUM_CHAT_IDS = sizeof(CHAT_IDS) / sizeof(CHAT_IDS[0]); | |
// Константы для пинов и настроек | |
#define LED_PIN D5 | |
#define NUM_LEDS 30 | |
#define ONE_WIRE_BUS D3 | |
#define BUTTON_PIN D6 | |
#define BUTTON2_PIN D7 | |
#define RELAY_PIN D8 | |
#define DEBOUNCE_DELAY 50 | |
// Константы для яркости | |
#define BRIGHTNESS_25 64 | |
#define BRIGHTNESS_50 128 | |
#define BRIGHTNESS_75 191 | |
#define BRIGHTNESS_100 255 | |
// Объекты для работы с библиотеками | |
BearSSL::WiFiClientSecure client; | |
UniversalTelegramBot bot(BOTtoken, client); | |
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800); | |
OneWire oneWire(ONE_WIRE_BUS); | |
DallasTemperature sensors(&oneWire); | |
// Переменные состояния | |
String lightStatus = "off"; | |
int brightness = BRIGHTNESS_100; | |
bool auroraMode = false; | |
bool relayState = false; | |
bool buttonState = LOW; | |
bool lastButtonState = LOW; | |
bool button2State = LOW; | |
bool lastButton2State = LOW; | |
unsigned long lastDebounceTime = 0; | |
unsigned long lastButton2DebounceTime = 0; | |
unsigned long auroraLastUpdate = 0; | |
unsigned long auroraInterval = 100; | |
int botRequestDelay = 500; // Уменьшенный интервал для быстрого ответа | |
unsigned long lastTimeBotRan = 0; | |
float currentTemperature = 0.0; | |
unsigned long lastTemperatureUpdate = 0; | |
const unsigned long temperatureUpdateInterval = 60000; // 1 минута | |
// Палитра цветов для эффекта "северное сияние" | |
uint32_t auroraColors[] = { | |
strip.Color(100, 50, 150), | |
strip.Color(120, 60, 160), | |
strip.Color(140, 70, 170) | |
}; | |
int auroraColorIndex = 0; | |
// Функция для проверки авторизации пользователя | |
bool isAuthorizedUser(const String& chat_id) { | |
for (int i = 0; i < NUM_CHAT_IDS; i++) { | |
if (chat_id == CHAT_IDS[i]) { | |
return true; | |
} | |
} | |
return false; | |
} | |
void setup() { | |
Serial.begin(115200); | |
// Настройка точки доступа | |
WiFi.mode(WIFI_AP_STA); // Режим точки доступа и клиента одновременно | |
WiFi.softAP(AP_SSID, AP_PASSWORD); // Создание точки доступа | |
Serial.println("Точка доступа запущена"); | |
Serial.print("SSID: "); | |
Serial.println(AP_SSID); | |
Serial.print("Пароль: "); | |
Serial.println(AP_PASSWORD); | |
Serial.print("IP-адрес точки доступа: "); | |
Serial.println(WiFi.softAPIP()); | |
// Подключение к Wi-Fi | |
WiFi.begin(ssid, password); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(1000); | |
Serial.println("Connecting to WiFi..."); | |
} | |
Serial.println("Connected to WiFi"); | |
Serial.print("IP-адрес клиента: "); | |
Serial.println(WiFi.localIP()); | |
client.setInsecure(); | |
pinMode(BUTTON_PIN, INPUT); | |
pinMode(BUTTON2_PIN, INPUT); | |
pinMode(RELAY_PIN, OUTPUT); | |
digitalWrite(RELAY_PIN, LOW); // По умолчанию реле выключено | |
strip.begin(); | |
strip.show(); | |
sensors.begin(); | |
} | |
void loop() { | |
// Проверка подключения к Wi-Fi | |
if (WiFi.status() != WL_CONNECTED) { | |
Serial.println("WiFi disconnected. Reconnecting..."); | |
WiFi.begin(ssid, password); | |
delay(5000); // Подождать 5 секунд перед повторной попыткой | |
return; | |
} | |
// Обработка сообщений | |
if (millis() - lastTimeBotRan > botRequestDelay) { | |
int numNewMessages = bot.getUpdates(bot.last_message_received + 1); | |
if (numNewMessages) { | |
handleBotMessages(numNewMessages); | |
} | |
lastTimeBotRan = millis(); | |
} | |
updateTemperature(); | |
handleButtonPress(); | |
handleButton2Press(); | |
if (auroraMode && millis() - auroraLastUpdate >= auroraInterval) { | |
auroraLastUpdate = millis(); | |
updateAuroraEffect(); | |
} | |
} | |
void handleBotMessages(int numNewMessages) { | |
Serial.println("New messages: " + String(numNewMessages)); | |
for (int i = 0; i < min(numNewMessages, 3); i++) { // Обрабатываем не более 3 сообщений за раз | |
String chat_id = String(bot.messages[i].chat_id); | |
String text = bot.messages[i].text; | |
Serial.println("Message from: " + chat_id + ", text: " + text); | |
if (!isAuthorizedUser(chat_id)) { | |
sendUnauthorizedMessage(chat_id); | |
continue; | |
} | |
if (bot.messages[i].type == "callback_query") { | |
handleCallbackQuery(chat_id, bot.messages[i].text); | |
} else if (text == "/start" || text == "меню") { | |
sendMainMenu(chat_id); | |
} else if (text == "статус") { | |
sendStatusMenu(chat_id); | |
} | |
} | |
// Обновляем last_message_received | |
if (numNewMessages > 0) { | |
bot.last_message_received = bot.messages[numNewMessages - 1].update_id + 1; | |
} | |
} | |
void sendUnauthorizedMessage(String chat_id) { | |
String message = | |
"Вибачте! Мій розробник не дозволяє мені спілкуватися з незнайомими користувачами.\n\n" | |
"Sorry! My developer doesn't allow me to chat with strangers.\n\n" | |
"Извините! Мой разработчик не разрешает мне общаться с незнакомыми пользователями."; | |
bot.sendMessage(chat_id, message); | |
Serial.println("Попытка доступа от неавторизованного пользователя. ID: " + chat_id); | |
String logMessage = "Попытка доступа от неавторизованного пользователя. ID: " + chat_id; | |
bot.sendMessage(YOUR_CHAT_ID, logMessage); | |
} | |
void handleCallbackQuery(String chat_id, String callbackData) { | |
if (callbackData == "light_menu") { | |
sendLightMenu(chat_id); | |
} else if (callbackData == "relay_menu") { | |
sendRelayMenu(chat_id); | |
} else if (callbackData == "status") { | |
sendStatusMenu(chat_id); | |
} else if (callbackData == "main_menu") { | |
sendMainMenu(chat_id); | |
} else if (callbackData == "light_on") { | |
turnOnLights(); | |
bot.sendMessage(chat_id, "Свет включен", ""); | |
} else if (callbackData == "light_off") { | |
turnOffLights(); | |
bot.sendMessage(chat_id, "Свет выключен", ""); | |
} else if (callbackData == "brightness_25") { | |
setBrightness(BRIGHTNESS_25); | |
bot.sendMessage(chat_id, "Яркость установлена на 25%", ""); | |
} else if (callbackData == "brightness_50") { | |
setBrightness(BRIGHTNESS_50); | |
bot.sendMessage(chat_id, "Яркость установлена на 50%", ""); | |
} else if (callbackData == "brightness_75") { | |
setBrightness(BRIGHTNESS_75); | |
bot.sendMessage(chat_id, "Яркость установлена на 75%", ""); | |
} else if (callbackData == "brightness_100") { | |
setBrightness(BRIGHTNESS_100); | |
bot.sendMessage(chat_id, "Яркость установлена на 100%", ""); | |
} else if (callbackData == "aurora_mode") { | |
auroraMode = !auroraMode; | |
bot.sendMessage(chat_id, auroraMode ? "Режим 'Северное сияние' включен" : "Режим 'Северное сияние' выключен", ""); | |
} else if (callbackData == "get_temperature") { | |
String temperatureMsg = "Текущая температура: " + String(currentTemperature) + "°C"; | |
bot.sendMessage(chat_id, temperatureMsg, ""); | |
} else if (callbackData == "relay_on") { | |
relayState = true; | |
digitalWrite(RELAY_PIN, HIGH); | |
bot.sendMessage(chat_id, "Реле включено", ""); | |
} else if (callbackData == "relay_off") { | |
relayState = false; | |
digitalWrite(RELAY_PIN, LOW); | |
bot.sendMessage(chat_id, "Реле выключено", ""); | |
} | |
} | |
void sendMainMenu(String chat_id) { | |
String keyboardJson = "[[" | |
"{\"text\": \"Управление светом\", \"callback_data\": \"light_menu\"}," | |
"{\"text\": \"Управление реле\", \"callback_data\": \"relay_menu\"}" | |
"],[" | |
"{\"text\": \"Северное сияние\", \"callback_data\": \"aurora_mode\"}," | |
"{\"text\": \"Температура\", \"callback_data\": \"get_temperature\"}" | |
"],[" | |
"{\"text\": \"Статус\", \"callback_data\": \"status\"}" | |
"]]"; | |
bot.sendMessageWithInlineKeyboard(chat_id, "Главное меню:", "", keyboardJson); | |
} | |
void sendLightMenu(String chat_id) { | |
String keyboardJson = "[[" | |
"{\"text\": \"Включить свет\", \"callback_data\": \"light_on\"}," | |
"{\"text\": \"Выключить свет\", \"callback_data\": \"light_off\"}" | |
"],[" | |
"{\"text\": \"Яркость 25%\", \"callback_data\": \"brightness_25\"}," | |
"{\"text\": \"Яркость 50%\", \"callback_data\": \"brightness_50\"}," | |
"{\"text\": \"Яркость 75%\", \"callback_data\": \"brightness_75\"}," | |
"{\"text\": \"Яркость 100%\", \"callback_data\": \"brightness_100\"}" | |
"],[" | |
"{\"text\": \"Назад\", \"callback_data\": \"main_menu\"}" | |
"]]"; | |
bot.sendMessageWithInlineKeyboard(chat_id, "Меню управления светом:", "", keyboardJson); | |
} | |
void sendRelayMenu(String chat_id) { | |
String keyboardJson = "[[" | |
"{\"text\": \"Реле ВКЛ\", \"callback_data\": \"relay_on\"}," | |
"{\"text\": \"Реле ВЫКЛ\", \"callback_data\": \"relay_off\"}" | |
"],[" | |
"{\"text\": \"Назад\", \"callback_data\": \"main_menu\"}" | |
"]]"; | |
bot.sendMessageWithInlineKeyboard(chat_id, "Меню управления реле:", "", keyboardJson); | |
} | |
void sendStatusMenu(String chat_id) { | |
String statusMessage = "📊 Текущий статус:\n\n"; | |
statusMessage += "💡 Свет: " + String(lightStatus == "on" ? "Включен" : "Выключен") + "\n"; | |
statusMessage += "☀ Яркость: " + String(brightness) + "\n"; | |
statusMessage += "🌌 Северное сияние: " + String(auroraMode ? "Включено" : "Выключено") + "\n"; | |
statusMessage += "🔌 Реле: " + String(relayState ? "Включено" : "Выключено") + "\n"; | |
statusMessage += "🌡 Температура: " + String(currentTemperature) + "°C\n"; | |
bot.sendMessage(chat_id, statusMessage, ""); | |
} | |
void turnOnLights() { | |
lightStatus = "on"; | |
setBrightness(brightness); | |
} | |
void turnOffLights() { | |
lightStatus = "off"; | |
strip.clear(); | |
strip.show(); | |
auroraMode = false; | |
} | |
void setBrightness(int level) { | |
brightness = level; | |
strip.setBrightness(brightness); | |
for (int i = 0; i < strip.numPixels(); i++) { | |
strip.setPixelColor(i, strip.Color(255, 255, 255)); | |
} | |
strip.show(); | |
} | |
void updateAuroraEffect() { | |
for (int i = 0; i < strip.numPixels(); i++) { | |
strip.setPixelColor(i, auroraColors[auroraColorIndex]); | |
} | |
strip.show(); | |
auroraColorIndex = (auroraColorIndex + 1) % (sizeof(auroraColors) / sizeof(auroraColors[0])); | |
} | |
void handleButtonPress() { | |
int reading = digitalRead(BUTTON_PIN); | |
if (reading != lastButtonState) { | |
lastDebounceTime = millis(); | |
} | |
if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) { | |
if (reading != buttonState) { | |
buttonState = reading; | |
if (buttonState == HIGH) { | |
if (lightStatus == "off") { | |
turnOnLights(); | |
} else { | |
turnOffLights(); | |
} | |
} | |
} | |
} | |
lastButtonState = reading; | |
} | |
void handleButton2Press() { | |
int reading = digitalRead(BUTTON2_PIN); | |
if (reading != lastButton2State) { | |
lastButton2DebounceTime = millis(); | |
} | |
if ((millis() - lastButton2DebounceTime) > DEBOUNCE_DELAY) { | |
if (reading != button2State) { | |
button2State = reading; | |
if (button2State == HIGH) { | |
relayState = !relayState; // Переключаем состояние реле | |
digitalWrite(RELAY_PIN, relayState ? HIGH : LOW); | |
} | |
} | |
} | |
lastButton2State = reading; | |
} | |
void updateTemperature() { | |
if (millis() - lastTemperatureUpdate >= temperatureUpdateInterval) { | |
sensors.requestTemperatures(); | |
currentTemperature = sensors.getTempCByIndex(0); | |
lastTemperatureUpdate = millis(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment