#include #include #include #include #include #include #include #define PIN_RELAY D1 // Время работы (более понятные имена) const uint8_t DAY_START_HOUR = 7; // Начало дня const uint8_t NIGHT_START_HOUR = 23; // Начало ночи const uint8_t DAY_WORK_MINUTES = 10; // Дневной интервал (минут) const uint8_t NIGHT_WORK_MINUTES = 20; // Ночной интервал (минут) const uint8_t DAY_START_MINUTE = 25; // Старт дневного интервала // Ночные интервалы (для ясности) const uint8_t NIGHT_INTERVAL1_START = 0; const uint8_t NIGHT_INTERVAL2_START = 40; // Интервал синхронизации (сейчас 30 минут для тестирования?) const uint32_t SYNC_INTERVAL_MS = 30 * 60 * 1000; // 30 минут // const char *ssid = "link"; const char *ssid = "MikroTik-2"; const char *pass = "dkfgf#*12091997"; const char *ntp_server = "ntp3.vniiftri.ru"; const char *host = "89.110.92.137"; const uint16_t port = 8000; const char *address_page = "/"; const uint32_t utcOffsetInSeconds = 10800; const uint32_t utcPeriodMseconds = 30 * 60 * 1000; // 86400000-р/сут; 604800000-р/нед uint32_t lastSync = 0; WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, ntp_server, utcOffsetInSeconds, utcPeriodMseconds); const uint16_t TIME_SLEEP = 60000; const uint8_t NUMBER_OF_ATTEMPTS = 20; bool flagBegining = true; const char *mqtt_client = "esp8266-761924"; const char *mqtt_client2 = "Villa_Septik"; const char *mqtt_user = "mqtt"; const char *mqtt_pass = "qwe1243"; const char *mqtt_server = "89.110.92.137"; const char *mqtt_port = "1883"; const char *outTopicData = "/data"; ESP8266WebServer server(80); ESP8266HTTPUpdateServer httpUpdater; WiFiClient espClient; PubSubClient client(espClient); //----------------------------------- inline bool mqtt_subscribe(PubSubClient &client, const String &topic) { Serial.print("Subscribing to: "); Serial.println(topic); return client.subscribe(topic.c_str()); } //----------------------------------- inline bool mqtt_publish(PubSubClient &client, const String &topic, const String &value) { Serial.print(topic); Serial.print(" = "); Serial.println(value); return client.publish(topic.c_str(), value.c_str()); } //----------------------------------- void mqttDataOut(uint8_t a) { String topic, topicValue; topic = "/"; topic += mqtt_client2; topic += outTopicData; topicValue = a; topicValue += ";;;;"; uint8_t count = NUMBER_OF_ATTEMPTS; while (!mqtt_publish(client, topic, topicValue) && count--) { mqtt_publish(client, topic, topicValue); delay(500); } } //----------------------------------- bool setupMQTT() { client.setServer(mqtt_server, String(mqtt_port).toInt()); Serial.print("MQTT connect : "); Serial.println(mqtt_server); uint8_t count = NUMBER_OF_ATTEMPTS; while (!(client.connect(mqtt_client, mqtt_user, mqtt_pass)) && count--) { Serial.print(count); Serial.print('>'); delay(500); } if (client.connected()) { Serial.println("MQTT connected - OK !"); return true; } else { return false; } } //=========================================== // подключение к WiFi bool setupWiFi() { digitalWrite(LED_BUILTIN, LOW); Serial.println("\n\nSetup WiFi: "); WiFi.begin(ssid, pass); uint8_t count = NUMBER_OF_ATTEMPTS; while (WiFi.status() != WL_CONNECTED) { Serial.print(count); Serial.print('>'); if (!count--) return false; delay(500); } digitalWrite(LED_BUILTIN, HIGH); //----------------------------------- // индикация IP Serial.print("\nWiFi connected !\nIP: "); Serial.println(WiFi.localIP()); //----------------------------------- // индикация силы сигнала int8_t RSSI_MAX = -50; int8_t RSSI_MIN = -100; int8_t dBm = WiFi.RSSI(); Serial.print("RSSI dBm = "); Serial.println(dBm); String l = ""; (dBm <= RSSI_MIN) ? l += 0 : (dBm >= RSSI_MAX) ? l += 100 : l += 2 * (dBm + 100); Serial.print("RSSI % = "); Serial.println(l); return true; } //=========================================== // синхронизация с NTP: bool syncNTP() { Serial.println("\nСинхронизируем время: "); uint8_t count = NUMBER_OF_ATTEMPTS; while (!timeClient.update()) { Serial.print(count); Serial.print('.'); if (!count--) return false; delay(500); } Serial.println(timeClient.getFormattedTime()); return true; } //=========================================== // Проверка валидности времени: bool isTimeValid() { // Проверяем, что время получено (не эпоха 1970 года) return timeClient.getEpochTime() > 1000000; } bool calculateRelayState() { uint8_t h = timeClient.getHours(); uint8_t m = timeClient.getMinutes(); // Дневной режим if (h >= DAY_START_HOUR && h < NIGHT_START_HOUR) { return (m >= DAY_START_MINUTE && m < DAY_START_MINUTE + DAY_WORK_MINUTES); } // Ночной режим if (m < NIGHT_WORK_MINUTES) // Первый интервал return true; if (m >= NIGHT_INTERVAL2_START && m < NIGHT_INTERVAL2_START + NIGHT_WORK_MINUTES) // Второй интервал return true; return false; } void controlRelay() { static bool lastRelayState = false; bool newRelayState = calculateRelayState(); if (newRelayState != lastRelayState) { if (setupMQTT()) { mqttDataOut(newRelayState); Serial.println("Данные успешно отправлены"); } digitalWrite(PIN_RELAY, newRelayState ? HIGH : LOW); Serial.printf("Реле %s в %02d:%02d\n", newRelayState ? "ВКЛ" : "ВЫКЛ", timeClient.getHours(), timeClient.getMinutes()); lastRelayState = newRelayState; } } // void goToDeepSleep() // { // Serial.println("Переход в глубокий сон на 1 минуту..."); // server.close(); // Закрываем сервер перед сном // delay(100); // // Настраиваем пробуждение через TIME_SLEEP миллисекунд // ESP.deepSleep(TIME_SLEEP * 1000); // deepSleep принимает микросекунды! // } //=========================================== void setup() { Serial.begin(115200); pinMode(PIN_RELAY, OUTPUT); digitalWrite(PIN_RELAY, LOW); timeClient.begin(); server.begin(); httpUpdater.setup(&server); lastSync = millis(); } //=========================================== void loop() { // Синхронизация времени if (millis() - lastSync >= SYNC_INTERVAL_MS || flagBegining) { if (setupWiFi()) { if (syncNTP()) { Serial.println("Время успешно синхронизировано"); } } // Всегда отключаем Wi-Fi после синхронизации // WiFi.disconnect(); // delay(100); // WiFi.mode(WIFI_OFF); // Serial.println("\nWi-Fi отключен для экономии энергии"); lastSync = millis(); flagBegining = false; } // Управление реле только если время валидно if (isTimeValid()) { controlRelay(); } // if (!flagBegining && WiFi.getMode() == WIFI_OFF) // { // goToDeepSleep(); // } server.handleClient(); delay(10); } // if (millis() - lastSync >= utcPeriodMseconds || flagBegining) // { // if (setupWiFi()) // syncNTP(); // WiFi.disconnect(); // Отключаемся от роутера // delay(100); // Небольшая задержка для завершения процесса // WiFi.mode(WIFI_OFF); // Полностью выключаем Wi-Fi // Serial.println("Wi-Fi отключен."); // lastSync = millis(); // } // //----------------------------- // // Работа по дневному тарифу: // if (timeClient.getHours() >= TIME_DAY && timeClient.getHours() < TIME_NIGHT) // { // if (timeClient.getMinutes() >= TIME_BEGINNING_DAY && timeClient.getMinutes() < TIME_BEGINNING_DAY + TIME_WORK_DAY_MINUT) // digitalWrite(PIN_RELAY, HIGH); // } // else // { // digitalWrite(PIN_RELAY, LOW); // } // //----------------------------- // // Работа по ночному тарифу: // if (timeClient.getHours() >= TIME_NIGHT && timeClient.getHours() < TIME_DAY) // { // if (timeClient.getMinutes() >= 0 && timeClient.getMinutes() < TIME_WORK_NIGHT_MINUT) // { // digitalWrite(PIN_RELAY, HIGH); // } // else // { // digitalWrite(PIN_RELAY, LOW); // } // if (timeClient.getMinutes() >= 40 && timeClient.getMinutes() < 40 + TIME_WORK_NIGHT_MINUT) // { // digitalWrite(PIN_RELAY, HIGH); // } // else // { // digitalWrite(PIN_RELAY, LOW); // } // } // server.handleClient(); // delay(10); //===========================================