• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Ищется вэб таймер полива растений.

Ф.И.О.

New member
Приветсвую!
Нужен таймер полива растений. Отрабатыватся должно два значения. Переодичность включения и его длительность.
Например, необходимо включение полива по таймеру каждые 48 часов с интервалом два часа.
Гугл меня не понимает ))). Подкиньте ссылку на пример?
 

ESP-01S

Member
Ох и намучился я с похожим планировщиком задач ...
Есть у меня поделка, которая включает-выключает свет (в аквариуме) по устанавливаемому пользователем недельному расписанию.
По понятным причинам, дать адрес сервера для наглядной демонстрации не могу, но железка работает до сих пор и довольно успешно.
Например:
пн: 08:00 - включить;
пн: 19:00 - вЫключить;
вт: 09:30 - включить;
вт: 10:40 - вЫключить;
вт: 12:00 - включить;
вт: 13:00 - вЫключить;
...

Геморрой еще тот: для начала нужно "в голове" сложить то, что нужно получить в итоге, а потом подумать, как это объяснить "тупой железке".
Поскольку пост уже давний, то вопрос может быть не актуален. Автор, отзовись: если все еще в поиске - выложу полный исходник того проекта, может натолкнет на какую идею ...
 

Ф.И.О.

New member
Моя задача немного проще. Чистой воды таймер Включение-выключение повторяются через заданные промежутки времени. У вас же больше походит на планировщик задач. Буду пробовать через функцию millis реализовать.
 

CodeNameHawk

Moderator
Команда форума
Уровень программы просто определить по названию кнопок "Тыкай", сразу понятно назначение кнопок.
 

rossomahaar

New member
Уровень программы просто определить по названию кнопок "Тыкай", сразу понятно назначение кнопок.
приветствую Гуру) да, html дается мне с трудом. Как и работа с spiffs, но я всего лишь новичок) и в разделе для новичков. не судите строго. Я планирую все же довести до конца свою маленькую поделку и заняться чем то более интересным)
Код:
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.h>
#include <Hash.h>
#include <FS.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#define RELAY 2
boolean RELAYstate = true;
unsigned long previousMillis, currentMillis;
int onTime, offTime;
int interval = onTime;
String onContent, offContent, ssidContent, passContent, formattedDate, timeStamp, dayStamp, dayTime;
const char* PARAM_ON = "input_ON";
const char* PARAM_OFF = "input_OFF";
const char* PARAM_SSID = "input_ssid";
const char* PARAM_PASSWORD = "input_password";
char ssid[24], password[32];
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html lang="ru"><head><meta charset="UTF-8">
  <title>ESP Timer Input Form</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
  </style>
  </head><body>
  <h1>Главное меню железки</h1>
  <h2>Настройки WiFi</h2>
    <form action="/get">
    Введите точку доступа: <input type="text" name="input_ssid">
    <input type="submit" value="Тыкай!">
  </form><br>
  <form action="/get">
    Введите пароль:<input type="text" name="input_password">
    <input type="submit" value="Тыкай!">
  </form><br>
  <h2>Настройки таймера</h2>
  <form action="/get">
    Время работы(в минутах): <input type="number" name="input_ON">
    <input type="submit" value="Тыкай!">
  </form><br>
  <form action="/get">
    Время простоя (в минутах): <input type="number" name="input_OFF">
    <input type="submit" value="Тыкай!">
  </form><br>
  <p> 
  <span class="time">Текущее время:</span> <span id="humidity">%time%</span>
  </p>
</body></html>)rawliteral";
AsyncWebServer server(80);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}
String readFile(fs::FS &fs, const char * path) {
  Serial.printf("Reading file: %s\r\n", path);
  File file = fs.open(path, "r");
  if (!file || file.isDirectory()) {
    Serial.println("- empty file or failed to open file");
    return String();
  }
  Serial.println("- read from file:");
  String fileContent;
  while (file.available()) {
    fileContent += String((char)file.read());
  }
  file.close();
  Serial.println(fileContent);
  return fileContent;
}
void writeFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Writing file: %s\r\n", path);
  File file = fs.open(path, "w");
  if (!file) {
    Serial.println("- failed to open file for writing");
    return;
  }
  if (file.print(message)) {
    Serial.println("- file written");
  } else {
    Serial.println("- write failed");
  }
  file.close();
}
String processor(const String& var) {
  if (var == "input_ssid") {
    return readFile(SPIFFS, "/ssid");
  }
  else if(var == "time"){
    getTime();
    return String(timeStamp);
}
  else if (var == "input_password") {
    return readFile(SPIFFS, "/pass");
  }
  else if (var == "input_ON") {
    return readFile(SPIFFS, "/ontime");
  }
  else if (var == "input_OFF") {
    return readFile(SPIFFS, "/offtime");
  }
  return String();
}
void getTime() {
  formattedDate = timeClient.getFormattedDate();
  int splitT = formattedDate.indexOf("T");
  dayStamp = formattedDate.substring(0, splitT);
  timeStamp = formattedDate.substring(splitT + 1, formattedDate.length() - 1);
}
void initTime() {
  timeClient.begin();
  timeClient.setTimeOffset(25200);
  while (!timeClient.update()) {
    timeClient.forceUpdate();
  }
  getTime();
  dayTime = "Текущая дата:  " + String(dayStamp) + " \n";
  dayTime += "Текущее время:  " + String(timeStamp) + "\n";
  Serial.println(dayTime);
  delay(3000);
}
void initWifi() {
  const char* ssidAP = "Умный_Дом";
  const char* passAP = "*********";
  IPAddress local_IP(192, 168, 1, 150);
  IPAddress gateway(192, 168, 1, 1);
  IPAddress subnet(255, 255, 0, 0);
  IPAddress primaryDNS(8, 8, 8, 8);
  IPAddress secondaryDNS(8, 8, 4, 4);
  WiFi.mode(WIFI_STA);
  WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.printf("Не могу подключиться к вафле. Запускаю SoftAP\n");
    delay(1000);
    WiFi.mode(WIFI_AP);
    WiFi.softAP(ssidAP, passAP, 1, 1);
    Serial.print("AP IP address: ");
    Serial.println(WiFi.softAPIP());
    return;
  }
  Serial.println();
  delay(1000);
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
}
void initWeb() {
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html, processor);
  });
  server.on("/time", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(dayStamp).c_str());
  });
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest * request) {
    String inputMessage;
    String inputParam;

    if (request->hasParam(PARAM_ON)) {
      inputMessage = request->getParam(PARAM_ON)->value();
      inputParam = PARAM_ON;
      onTime = inputMessage.toInt() * 1000;
      inputMessage = String(inputMessage.toInt() * 1000);
      Serial.print("Время работы изменено:");
      writeFile(SPIFFS, "/ontime", inputMessage.c_str());
    }
    else if (request->hasParam(PARAM_OFF)) {
      inputMessage = request->getParam(PARAM_OFF)->value();
      inputParam = PARAM_OFF;
      offTime = inputMessage.toInt() * 1000;
      inputMessage = String(inputMessage.toInt() * 1000);
      Serial.print("Время простоя изменено:");
      writeFile(SPIFFS, "/offtime", inputMessage.c_str());
    }
    else if (request->hasParam(PARAM_SSID)) {
      inputMessage = request->getParam(PARAM_SSID)->value();
      inputParam = PARAM_SSID;
      //ssid = inputMessage.c_str();
      Serial.print("Точка доступа изменена");
      writeFile(SPIFFS, "/ssid", inputMessage.c_str());
    }
    else if (request->hasParam(PARAM_PASSWORD)) {
      inputMessage = request->getParam(PARAM_PASSWORD)->value();
      inputParam = PARAM_PASSWORD;
      //password = inputMessage.c_str();
      Serial.print("Пароль изменен:");
      writeFile(SPIFFS, "/pass", inputMessage.c_str());
    }
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    Serial.println(inputMessage);
    request->send(200, "text/html", "HTTP GET request sent to your ESP on input field (" + inputParam + ") with value: " + inputMessage + "<br><a href=\"/\">Return to Home Page</a>");
  });
  server.onNotFound(notFound);
  AsyncElegantOTA.begin(&server);
  server.begin();
  Serial.println("HTTP сервер запущен!");
}
void initVar() {
  File ontime = SPIFFS.open("/ontime", "r");
  if (!ontime || ontime.isDirectory()) {
    Serial.println("Ошибка чтения /ontime");
    return;
  }
  while (ontime.available()) {
    onContent += String((char)ontime.read());
  }
  ontime.close();
  onTime = onContent.toInt();
  File offtime = SPIFFS.open("/offtime", "r");
  if (!offtime || offtime.isDirectory()) {
    Serial.println("Ошибка чтения /offtime");
    return;
  }
  while (offtime.available()) {
    offContent += String((char)offtime.read());
  }
  offtime.close();
  offTime = offContent.toInt();
  File ssid_conf = SPIFFS.open("/ssid", "r");
  if (!ssid_conf || ssid_conf.isDirectory()) {
    Serial.println("Ошибка чтения /ssid");
    return;
  }
  while (ssid_conf.available()) {
    ssidContent += String((char)ssid_conf.read());
  }
  ssidContent.trim();
  int len = ssidContent.length() + 1;
  ssid[len];
  ssidContent.toCharArray(ssid, len);
  ssid_conf.close();
  File pass_conf = SPIFFS.open("/pass", "r");
  if (!pass_conf || pass_conf.isDirectory()) {
    Serial.println("Ошибка чтения /pass");
    return;
  }
  while (pass_conf.available()) {
    passContent += String((char)pass_conf.read());
  }
  passContent.trim();
  int len1 = passContent.length() + 1;
  password[len];
  passContent.toCharArray(password, len);
  pass_conf.close();
}
void initSPIFFS() {
  if (!SPIFFS.begin()) {
    Serial.println("Ошибка монтирования SPIFFS");
    return;
  }
  else {
    Serial.println("SPIFFS примонтирована");
  }
}
void timer_loop() {
  digitalWrite(RELAY, RELAYstate);
  currentMillis = millis();
  if ((unsigned long)(currentMillis - previousMillis) >= interval) {
    if (RELAYstate) {
      interval = offTime;
      Serial.println();
      Serial.println("Выключаем на " + String(offTime) + "ms");
    } else {
      interval = onTime;
      Serial.println();
      Serial.println("Включаем на " + String(onTime) + "ms");
    }
    RELAYstate = !(RELAYstate);
    previousMillis = currentMillis;
  }
}
void setup() {
  Serial.begin(115200);
  Serial.println();
  delay(1000);
  initSPIFFS();
  pinMode(RELAY, OUTPUT);
  digitalWrite(RELAY, LOW);
  initVar();
  delay(3000);
  Serial.print("ssid: ");
  Serial.println(ssid);
  Serial.print("password: ");
  Serial.println(password);
  Serial.print("Время работы: ");
  Serial.println(onTime);
  Serial.print("Время простоя: ");
  Serial.println(offTime);
  initWifi();
  initTime();
  initWeb();
}
void loop() {
  AsyncElegantOTA.loop();
  timer_loop();
}
 
Сверху Снизу