• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь запросы c WEB сервера

DRC

New member
Добрый день!

Помогите, пожалуйста разобраться в проблеме:

есть Web server на esp8266 который управляет реле в режиме on/off

Код:
#include <ESP8266WiFi.h>
const char* ssid     = "xxx";
const char* password = "xxx";
WiFiServer server(80);
String header;
String output5State = "off";
const int output5 = 5;

// устанавливаем mac адрес устройства
void initVariant() {
  uint8_t mac[6] = {0x00, 0xA3, 0xA0, 0x1C, 0x8C, 0x45};
  wifi_set_macaddr(STATION_IF, &mac[0]);
}

void setup() {
Serial.begin(115200);

pinMode(output5, OUTPUT);
digitalWrite(output5, LOW);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop(){
  WiFiClient client = server.available();  

  if (client) {                            ,
    Serial.println("New Client.");         
    String currentLine = "";            
    while (client.connected()) {          
      if (client.available()) {          
        char c = client.read();          
        Serial.write(c);                 
        header += c;
        if (c == '\n') {                  
         
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
          
            // включаем-выключаем реле
            if (header.indexOf("GET /5/on") >= 0) {
              Serial.println("GPIO 5 on");
              digitalWrite(output5, HIGH);
              output5State = "on";
            } else if (header.indexOf("GET /5/off") >= 0) {
              Serial.println("GPIO 5 off");
              output5State = "off";
              digitalWrite(output5, LOW);
          
            }
          
            //HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #77878A;}</style></head>");
          
            // Web Page Heading
            client.println("<body><h1>ESP8266 Web Server</h1>");
          
            // Display current state, and ON/OFF buttons for GPIO 5 
            client.println("<p>GPIO 5 - State " + output5State + "</p>");
            // If the output5State is off, it displays the ON button     
            if (output5State=="off") {
              client.println("<p><a href=\"/5/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/5/off\"><button class=\"button button2\">OFF</button></a></p>");
            }
                              
              client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;     
        }
      }
    }
    header = "";
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}
при просто работе с WEB все работает как надо.

При попытке соединить это с HomeBridge возникает проблема, решение которой не нашел в силу отсутствия глубоких знаний.

Использую плагин:
Powerful http switch for Homebridge (Supereg/homebridge-http-switch)

Код:
        {
            "accessory": "HTTP-SWITCH",
            "name": "Switch",
            "switchType": "stateful",
            "debug": true,
            "onUrl": {
                "url": "http://10.0.1.21/5/on",
                "method": "GET"
            },
            "offUrl": {
                "url": "http://10.0.1.21/5/off",
                "method": "GET"
            },
            "statusUrl": {
                "url": "http://10.0.1.21/output5State",
                "method": "GET"
            }

для определения состояния выключателя был использован параметр output5State. Но состояние не изменятся не важно какой метод был выбран или какие значения "on" или 1 были присвоены в коде esp
Сам выключатель работает как из WEB так и из HomeKit но в HomeKit не запоминает состояния которое на устройстве если преложение закрыть и открыть снова

Отсюда вопрос, что не так или где можно на примерах посмотреть как надо делать и как это должно работать?
 

remrum

Member
Сделайте отдельный обработчик запроса статуса http://10.0.1.21/output5State
Пример как сделать есть здесь.
Плагину homebridge отдавайте статус в виде 0 или 1.
Для обновления статуса в homekit попробуйте для начала метод периодического опроса указав в настройке pullInterval.
Все описано на странице плагина.
Но даже не используя дополнительный опрос, homekit делает запрос статуса при открытии приложения.
 

DRC

New member
Сделайте отдельный обработчик запроса статуса http://10.0.1.21/output5State
Пример как сделать есть здесь.
Плагину homebridge отдавайте статус в виде 0 или 1.
Для обновления статуса в homekit попробуйте для начала метод периодического опроса указав в настройке pullInterval.
Все описано на странице плагина.
Но даже не используя дополнительный опрос, homekit делает запрос статуса при открытии приложения.
получается я создаю запрос вида:
Код:
server.on("/stat", sendServer);
и делаю модуль ответа с условиями:
Код:
// Отправляем серверу события ручного вкл./выкл.
void sendServer(){
if(lamp_on == true) {
    server.send(200, "text/plain", "1");
      } else {
    server.send(200, "text/plain", "0");
      }
}
если через браузер провеляю команду localhost/stat то получаю ответ 1 или 0, но homedridge по прежнему не видит состояние
 

remrum

Member
homebridge-http-switch передает состояние каждый раз когда открывается интерфейс "Дом".
В чем можно легко убедится поменяв состояние и закрыв/открыв "Дом".
Для того что-бы в реальном времени видеть статус переключателя добавьте в конфиг строчку: "pullInterval": 1000,
И получите обновление каждую секунду.
Но это не самый хороший способ. Есть и другие - сервер уведомлений, websocket.
Ещё раз повторю, все описано на странице плагина.
 
Сверху Снизу