Esp8266 редирект,

Тема в разделе "ESP8266, ESP32", создана пользователем serega4789, 24 окт 2019.

  1. serega4789

    serega4789 Нерд

    Добрый день! Возникла проблема с перенаправлением в корневой запрос.

    Код (C++):
    server.on("/socket1On", [](){
        digitalWrite(D0_pin, LOW);
        server.send(200, "text/html", webPage());
        delay(2000);
     
          digitalWrite(D0_pin, HIGH);
      });

    после delay(200); воткнуть:


    server.sendHeader("Location", String("/"), true);
    У меня функция включать реле по нажатию кнопки , после истечения времени реле выключается а состояние не обновляется реле (зелёным on , of красный ) мне нужно перенаправить по ссылке чтобы состояние обновилось на веб сервере
     
  2. В обработчике запроса /socket1On вы выполняете server.send
    Код (C++):
    // send response to the client
    // code - HTTP response code, can be 200 or 404
    // content_type - HTTP content type, like "text/plain" or "image/png"
    // content - actual content body
    void send(int code, const char* content_type = NULL, const String& content = String(""));
    браузер получит этот ответ.
    То что вернула webPage то и будет обрабатывать браузер.

    Если по истечении времени реле из включенного состояния переходит в выключенное и, как вы говорите, чтобы состояние обновилось на веб сервере, т.е. веб сервер пока об этом не знает, нужно заставить браузер перейти по указанной ссылке.
    Непонятно совсем тут стало.

    Если веб сервер готов отдавать текущее состояние реле, то логично было бы просто запрашивать текущее состояние скриптом (например раз в секунду) и обновлять отображаемую страницу в браузере.
     
  3. serega4789

    serega4789 Нерд

    Дело в том ,что если я обновлю страницу командой то , выполнится включение реле повторно, кнопка рефреш перенаправляет на стартовую страницу , сайт перезагружается и все работает как надо, я нашел команду редирект которая выполняет роль рефреш , но не перезагружает страницу
     
  4. serega4789

    serega4789 Нерд

    Вечером скину весь код программы
     
  5. Кто управляет реле, выключает/включает подает логические уровни "digitalWrite" разве не веб сервер?
    Если всё-же это веб сервер, то почему "чтобы состояние обновилось на веб сервере" а не обновилось отображение в браузере, нужно браузеру отправлять редирект, и как его отправлять собрались, если браузер в этот момент ничего не запрашивает?
     
  6. serega4789

    serega4789 Нерд

    Я не знаю вот и спрашиваю, как сделать включение реле по кнопке в браузере выкл по таймеру и видеть на веб странице статус реле ?
     
  7. serega4789

    serega4789 Нерд

    Код (C++):
    #include <ESP8266WiFi.h>
    #include <ESP8266WebServer.h>
    //ESP AP Mode configuration
    const char *ssid = "Redirect-demo-circuits4you.com";
    ESP8266WebServer server(80);
    void handleNotFound(){
      server.sendHeader("Location", "/",true);   //Redirect to our html web page
      server.send(302, "text/plane","");
    }
    void handleRoot() {
      server.send(200, "text/html", "<html><body>Hello from ESP <br><a href='/Thispage'>Failed Link</a></body></html>");
    }
    void setup() {
      delay(1000);
      Serial.begin(115200);
      Serial.println();
      //Initialize AP Mode
      WiFi.softAP(ssid);  //Password not used
      IPAddress myIP = WiFi.softAPIP();
      Serial.print("Web Server IP:");
      Serial.println(myIP);
      //Initialize Webserver
      server.on("/",handleRoot);
      server.onNotFound(handleNotFound);
      server.begin();
    }
    void loop() {
    server.handleClient();
    }

    Редирект пример
     
  8. serega4789

    serega4789 Нерд

    Прошу прощения ввел в заблуждение, сам запутался в терминах, все управления с браузера кнопки и состояние реле , так как при нажатии кнопки в браузере происходит переход по ссылке( например вкл ), то состояние изменится один раз на вкл ,а когда сработает задержка или таймер реле отключится без ссылки , адрес не изменится, если перезагрузить все повториться и я не увижу выкл реле в браузере ,вот и надо перенаправить на стартовую страницу и перезагрузить для изменения состояния реле
     
  9. Ну почему-же так то??? Хотим изменить что либо на сервере, например включить реле, и выполняем метод get а не post, я плакал...

    Если веб-сервер на esp и реле подключено к esp, то потребуется всего одна страница на которой есть кнопка для управления реле и элемент отображающий текущее состояние.
    И соответственно два скрипта, один "постит" запросы на включение/выключение по нажатию на кнопку, а другой скрипт раз в секунду запрашивает статус.
    Таким образом, открыв два окна у браузера, в одном можете нажимать на кнопку, а в обеих окнах видеть изменения статуса при включении и по истечении таймаута.
    И ничего не требуется обновлять и никуда не нужно редиректить
     
  10. serega4789

    serega4789 Нерд

    Код (C++):
    // Данный скетч предназначен для демонстрации возможности обращения к модулю из интернет и обновления IP-адреса ESP8266 (WiFi-сети в которой он находится) в сервисе http://hldns.ru
    // Помимо регистрации на сайте http://hldns.ru для работы также требуется настройка переадресации с 10200-го порта маршрутизатора (роутера) на ESP8266

    #include <ESP8266WiFi.h>                                      // Библиотека для создания Wi-Fi подключения (клиент или точка доступа)
    #include <WiFiClient.h>                                       // Библиотека для связи с сетевыми хостами (локальными и интернет)
    #include <ESP8266WebServer.h>                                 // Библиотека для поднятия веб-сервера
    int D0_pin = 16;

    const char* ssid = "";                                // Указываем имя WiFi-сети, к которой будет подключаться ESP8266
    const char* password = "";                            // Указываем пароль для подключения к WiFi-сети
                                  // Указываем имя WiFi-сети, к которой будет  
    const char* ip_update_host = "hldns.ru";                      // Указываем хост (адрес сайта) службы DynDNS
    const char* ip_update_get = "/update/8XO5I5QSITYWDWE5HLBQ6BITOJJM8J";               // Указываем GET-запрос (набор параметров) адреса идентификации в службе DynDNS
    bool obnov=0;
    ESP8266WebServer server(10200);                               // Создаём объект для работы с нашим веб-сервером, указав номер порта, по которому он будет доступен в WWW
    WiFiClient client;                                            // Создаём объект для работы с удалёнными хостами

    void setup(void){
      pinMode(D0_pin, OUTPUT);
      digitalWrite(D0_pin, HIGH);
      WiFi.disconnect();
      WiFi.mode(WIFI_STA);
      WiFi.softAPdisconnect(true); //for fix stupid bug
      WiFi.enableAP(false); //for fix stupid bug

      Serial.begin(9600);                                         // Инициализируем вывод данных на серийный порт со скоростью 9600 бод
      WiFi.begin(ssid, password);                                 // Соединяемся с WiFi-сетью
      while (WiFi.status() != WL_CONNECTED)                       // Пока соединение не установено
        delay(500);                                               //  делаем задержку в пол секунды, пока соединение не установится
      Serial.println("WiFi connected");                           // Выводим сообщение о том, что устройство соединилось с WiFi-сетью
      server.begin();                                             // Инициализируем работу веб-сервера
      //server.on("/", root);// Сообщаем о том, что при обращении к корневой директории нашего веб-сервера должна вызываться функция root
    //+++++++++++++++++++++++ START  LED-1 ++++++++++++++++++++
        server.on("/", [](){
        server.send(200, "text/html", webPage());
      });
      server.on("/socket1On", [](){
        digitalWrite(D0_pin, LOW);
        server.send(200, "text/html", webPage());
        delay(2000);
     
       digitalWrite(D0_pin, HIGH);
        server.sendHeader("Location", "/",true);
     


      });
     
     
     

     
     
     
     
     
     
     

    //+++++++++++++++++++++++ END  LED-1 ++++++++++++++++++++
      Serial.println("HTTP server started");                      // Выводим на монитор серийного порта сообщение о том, что веб-сервер запущен
      Serial.print("Local IP: ");                                 // Выводим на монитор серийного порта сообщение о том, что сейчас будем выводить локальный IP
      Serial.println(WiFi.localIP());                             // Выводим локальный IP-адрес ESP8266
      Serial.print("MAC-address: ");                              // Выводим на монитор серийного порта сообщение о том, что сейчас будем выводить MAC-адрес ESP8266
      Serial.println(WiFi.macAddress());                          // Выводим MAC-адрес ESP8266
      ip_update();                                                // Вызываем функцию, обновляющую IP маршрутизатора (роутера) в службе динамических DNS
    }
    void loop(void){
      server.handleClient();                                      // Ожидаем обращение к веб-серверу
    }

    void ip_update(){                                             // Функция, обновляющая IP маршрутизатора (роутера) в службе динамических DNS
      if (client.connect(ip_update_host,80)) {                    // Если возможно соединиться с хостом на 80-й порт:
        client.print("GET ");                                     //  Эта и следующие 7 строк отправляют системные заголовки на сервер службы динамических DNS
        client.print(ip_update_get);                              //  Формат заголовков строгий и в нём важны даже переводы строк
        client.println( " HTTP/1.1");                             //
        client.print("Host:");                                    //
        client.println(ip_update_host);                           //
        client.println( "Connection: close" );                    //
        client.println();                                         //
        client.println();                                         //
        delay(200);                                               //  Задержка в 0.2 сек., чтобы дать удалённому серверу возможность обработать и отправить ответ на наш запрос
        Serial.println("\nResponse of DDNS-Server:");             //  Шлём в монитор серийного порта сообщение о том, что далее будет выводиться ответ от сервера службы DynDNS
        while (client.available()) {                              //  Пока сервер на связи
          char a = client.read();                                 //    считываем его ответ по одному символу
          Serial.print(a);                                        //    и выводим на монитор серийного порта
        }
      }
    }
    void root(){                                                   // Функция,вызывающаяся при обращении клиента к корневой дирректории нашего веб-сервера
      server.send(200, "text/html","<h1>Web-server ESP8266</h1>"); // Сервер отправляет клиенту информацию о том, что
    }                                                              // 200 - запрос успешно обработан

    void handleNotFound(){
      server.sendHeader("Location", "/",true);
       //server.send(200, "text/plane","");
       server.send(200, "text/html", webPage());
    }
    String webPage()
    {
      String web;
      web += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/> <meta charset=\"utf-8\"><title>ESP 8266</title><style>button{color:red;padding: 10px 27px;}</style></head>";
      web += "<h1 style=\"text-align: center;font-family: Open sans;font-weight: 100;font-size: 20px;\">ESP8266 Web Server</h1><div>";
      //++++++++++ LED-1  +++++++++++++
      web += "<p style=\"text-align: center;margin-top: 0px;margin-bottom: 5px;\">----korm----</p>";
       if (digitalRead(D0_pin) == 0)
      {
        web += "<div style=\"text-align: center;width: 98px;color:white ;padding: 10px 30px;background-color: #43a209;margin: 0 auto;\">ON</div>";

      }
      if (digitalRead(D0_pin) == 1)
      {
        web += "<div style=\"text-align: center;width: 98px;color:white ;padding: 10px 30px;background-color: #ec1212;margin: 0 auto;\">OFF</div>";
      //if(obnov==1){obnov=0;handleNotFound();};
      }

      web += "<div style=\"text-align: center;margin: 5px 0px;\"> <a href=\"socket1On\"><button>ON</button></a></div>";

      // ++++++++ LED-1 +++++++++++++
                           // web +="<meta http-equiv=\"refresh\" content=\"1\" >\n"; рефреш страницы
                   
                       web += "<div style=\"text-align:center;margin-top: 20px;\"><a href=\"/\"></div>"; ;                                        ;      
    // ========REFRESH============
      web += "<div style=\"text-align:center;margin-top: 20px;\"><a href=\"/\"><button style=\"width:158px;\">REFRESH</button></a></div>";
      // ========REFRESH=============



      web += "</div>";
      return(web);
    }
     
  11. serega4789

    serega4789 Нерд

    Подскажите как применить в моем проекте эту запись
    Код (C++):
    <meta http-equiv="refresh" content="5; url=https://www.google.com">
    я так написал
    Код (C++):
      web +="<meta http-equiv=""refresh"" content=""5""; ""url=https://www.google.com"">";
     
  12. Просто экранируем символ "
    Код (Text):
    web +="<meta http-equiv=\"refresh\" content=\"5; url=https://www.google.com\">";
     
    Последнее редактирование: 25 окт 2019
  13. serega4789

    serega4789 Нерд

    в таком виде не работает проверял уже
     
  14. serega4789

    serega4789 Нерд

    Код (C++):
    /*
       Hello world web server
       circuits4you.com
    */


    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>


    //SSID and Password to your ESP Access Point
    const char* ssid = "Server";
    const char* password = "";
    int D0_pin = 16;
    bool b=0;
    ESP8266WebServer server(80); //Server on port 80



    //==============================================================
    //     This rutine is exicuted when you open its IP in browser
    //==============================================================


    //===============================================================
    //                  SETUP
    //===============================================================

    void setup(void) {


    pinMode(D0_pin, OUTPUT);
    digitalWrite(D0_pin, HIGH);





      Serial.begin(9600);
     
      Serial.println("");
      WiFi.mode(WIFI_AP);           //Only Access point
      WiFi.softAP(ssid, password);  //Start HOTspot removing password will disable security

      IPAddress myIP = WiFi.softAPIP(); //Get IP address
      Serial.print("HotSpt IP:");
      Serial.println(myIP);

     
      //+++++++++++++++++++++++ START  LED-1 ++++++++++++++++++++
      server.on("/", []() {
        server.send(200, "text/html", webPage());
      });

     
        ;
       
       
       
     
        server.on("/socket1On", []() {
        if(b==1){
        server.sendHeader("Location", "/",true);
        server.send(302, "text/plane","");b=0;  }

        else
       
        {
        digitalWrite(D0_pin, LOW);b=1;
       
        server.send(200, "text/html", webPage());
        delay(2000);
       
        digitalWrite(D0_pin, HIGH);  } });                    
       
     
     
       
     
     
     
       
     
     
     
     
     
      server.begin();                  //Start server
      Serial.println("HTTP server started");
    }
    //===============================================================
    //                     LOOP
    //===============================================================
    void loop(void) {
      server.handleClient();          //Handle client requests
     

    }

    String webPage()
    {
    String web;
      web += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/> <meta charset=\"utf-8\"><title>ESP 8266</title><style>button{color:red;padding: 10px 27px;}</style></head>";
      web += "<h1 style=\"text-align: center;font-family: Open sans;font-weight: 100;font-size: 20px;\">ESP8266 Web Server</h1><div>";
      if(b==1){web +="<meta http-equiv=""refresh"" content=""0"">"; delay(1000);};
      //++++++++++ LED-1  +++++++++++++
      web += "<p style=\"text-align: center;margin-top: 0px;margin-bottom: 5px;\">----korm----</p>";
       if (digitalRead(D0_pin) == 0)
      {
        web += "<div style=\"text-align: center;width: 98px;color:white ;padding: 10px 30px;background-color: #43a209;margin: 0 auto;\">ON</div>";
     
      }
      if (digitalRead(D0_pin) == 1)
      {
        web += "<div style=\"text-align: center;width: 98px;color:white ;padding: 10px 30px;background-color: #ec1212;margin: 0 auto;\">OFF</div>";
      //if(obnov==1){obnov=0;handleNotFound();};
      }

      web += "<div style=\"text-align: center;margin: 5px 0px;\"> <a href=\"socket1On\"><button>ON</button></a></div>";
     
     




     
     

     
      //web +="<head><meta http-equiv=""refresh""/content=""5""/"> "<""url=https://www.google.com""></head>";
     
     
      // ========REFRESH=============
      web += "<div style=\"text-align:center;margin-top: 20px;\"><a href=\"/\"><button style=\"width:158px;\">REFRESH</button></a></div>";
      // ========REFRESH=============


      web += "</div>";
      return (web);
    }
     
  15. serega4789

    serega4789 Нерд

    вот собрал, работает как мне надо))
    надо бы разобраться со всеми скриптами "meta", применительно ардуино ,методом научного тыка все получается, то контроллер сбоит уходит в рестарт по wdt (решил проблему в настройках ардуино иде erase flach) то библиотеки конфликтуют ))....
    Посоветуйте , что почитать для построения веб сервера, управление по браузеру: авторизация логин пароль , кнопки ,таймеры,ввод вывод информации? Чтобы в будущем правильные вопросы задавать ...
     
  16. Что значит не работает?
    На запрос к вашему серверу в ответе от него приходит искаженный контент, не тот что вы ожидали? А что приходит?
     
  17. serega4789

    serega4789 Нерд

    прошу прощения , работает это сбой был юсб порта проверю этот скрип в контроллере позже,
     
  18. Просто включаю синий светодиод на ноде-мсу.
    Корневой контент грузится один раз, обновлений редиректов и т.п. не требуется.
    Раз в секунду скриптом выполняется get запрос для получения актуального состояния.
    По нажатию на кнопки Включить/Выключить скриптом выполняется post запрос.
    Подключаюсь к веб-серверу с ПК и со смартфона, на любом устройстве вижу актуальное состояние включенного/выключенного светодиода.
    Проще придумать сложно.
    Код (C):

    #include <ESP8266WebServer.h>

    static const char content[] PROGMEM = "<!doctype html>\r\n"
    "<html>\r\n"
    "<head>\r\n"
    "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />\r\n"
    "<title>Проверка</title>\r\n"
    "</head>\r\n"
    "<body onLoad='updateStatus()'>\r\n"
    "<script type='text/javascript'>\r\n"
    "  var timer;\r\n"
    "  function updateStatus() {\r\n"
    "    var xhr = new XMLHttpRequest();\r\n"
    "    xhr.open('GET', '/status?r='+(new Date()).getTime());\r\n"
    "    xhr.onreadystatechange = function() {\r\n"
    "      if (this.readyState == 4) {\r\n"
    "        showStatus(this.status == 200 ? this.responseText : '');\r\n"
    "        timer = setTimeout('updateStatus()', 1000);\r\n"
    "      }\r\n"
    "    }\r\n"
    "    xhr.send();\r\n"
    "  }\r\n"
    "  function relaySwitch(code) {\r\n"
    "    clearTimeout(timer);\r\n"
    "    document.getElementById('status').innerHTML = 'Пожалуйста подождите';\r\n"
    "    var xhr = new XMLHttpRequest();\r\n"
    "    xhr.open('POST', '/switch');\r\n"
    "    xhr.onreadystatechange = function() {\r\n"
    "      if (this.readyState == 4) {\r\n"
    "        showStatus(this.status == 200 ? this.responseText : '');\r\n"
    "        timer = setTimeout('updateStatus()', this.status == 200 ? 1000 : 5000);\r\n"
    "      }\r\n"
    "    }\r\n"
    "    xhr.send(code ? 'ON' : 'OFF');\r\n"
    "  }\r\n"
    "  function showStatus(msg) {\r\n"
    "    document.getElementById('status').innerHTML = msg.startsWith('ON') == true ? 'Включено' : msg.startsWith('OFF') == true ? 'Выключено' : 'Ошибка';\r\n"
    "  }\r\n"
    "</script>\r\n"
    "<p id='status'></p>\r\n"
    "<button onclick='relaySwitch(true)'>Включить</button>\r\n"
    "<button onclick='relaySwitch(false)'>Выключить</button>\r\n"
    "</body>\r\n"
    "</html>\r\n";

    #define RELAY_TIMEOUT 3000
    static ESP8266WebServer server(80);
    static unsigned long relayOnTime = 0;
    static int relayPin = 2;

    void setup() {
      pinMode(relayPin, OUTPUT);
      digitalWrite(relayPin, HIGH);
     
      WiFi.persistent(false);
      WiFi.mode(WIFI_OFF);
      delay(100);
      WiFi.mode(WIFI_AP);
      WiFi.softAP("Relay-Test");

      server.on("/", HTTP_GET, []() {
        server.send_P(200, "text/html", content);
      });

      server.on("/status", HTTP_GET, []() {
        server.send(200, "text/plain", digitalRead(relayPin) ? "OFF" : "ON");
      });
     
      server.on("/switch", HTTP_POST, []() {
        String s = server.arg("plain");
        if (s.equals("ON")) {
          relayOnTime = millis();
          digitalWrite(relayPin, LOW);
          server.send(200, "text/plain", "ON");
        } else if (s.equals("OFF")) {
          relayOnTime = 0;
          digitalWrite(relayPin, HIGH);
          server.send(200, "text/plain", "OFF");
        } else {
          server.send(200, "text/plain", "ERROR");
        }
      });

      server.begin();
    }

    void loop() {
      server.handleClient();
      if (relayOnTime && abs(millis() - relayOnTime) > RELAY_TIMEOUT) {
        relayOnTime = 0;
        digitalWrite(relayPin, HIGH);
      }
    }
     
     
    parovoZZ нравится это.
  19. serega4789

    serega4789 Нерд

    Эта кнопка лишь часть проекта, надо будет настраивать таймер включения в автомате, программа таймеров с дисплеем и меню с ds1307 собрана, осталось привезать к веб интерфейсу поэтому смотрю в сторону ArduinoJson, и главная проблема медлительность работы сервера при большем объеме кода, проверял разные скетчи готовые