Умный дом, начало... esp,websoket

vitalikost
Offline
Зарегистрирован: 28.11.2014

Добрый день! Хочу поделиться наработками по созданию системы управления устройствами, по типу умного дома. Создан простой протокой общения, между управляющим устройством(Контроллером) и подключаемыми клиентами. Количество котроллеров так и клиентов не ограничено. Реализована обратная связь, между котроллерами и клиентами, это основная идея проекта. На данный момент реализовано один тип устройств – relay(Реле).  В примере показано упрощенное управление этим устройством. Алгоритм можно, и нужно адаптировать под свои нужны. Для запуска проекта минимально нужно 2 esp, одна в роли сервера обмена, вторая в роли клиента. Также можно использовать сторонний websoket-сервер(для примера Herokuapp.com на Node JS) для обмена. Контроллером выступает веб-страничка, ее можно загрузить на сервер обмена, а можно просто открыть с устройства. Таким образом проект состоит из 3 файлов: Скеч клиента, скеч сервера обмена(если есть необходимость), веб-страничка.

vitalikost
Offline
Зарегистрирован: 28.11.2014

Клиент:

/*
 * WebSocketClient.ino
 *
 *  Created on: 24.05.2015
 *
 */
#include <ArduinoJson.h>
#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <WebSocketsClient.h>
#include <Hash.h>
#include <EEPROM.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
WebSocketsClient webSocket;
#define USE_SERIAL Serial
boolean start = true;
long previousMillis = 60000;        // храним время последнего переключения 
long interval = 1000*60*5;          // интервал между проверкой доступности сервера (300 секунд)
long interval_restart = 1000*60*60; // интервал между включение/выключением (60 минут)

DynamicJsonBuffer jsonBuffer;

String str = "";

String html_header = "<html>\
 <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\
 <head>\
   <title>ESP8266 Settings</title>\
   <style>\
     body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
   </style>\
 </head>";

void runCommand(String command)
  {         String StatusPin = "[0,0,0,0,0,0,0,0]";//Пример для 8 пинов.
            String Name = String(WiFi.macAddress());        
            String Device = "\"Relay\"";//Тип устройства, в перспективе планируеться разширение устройств.        
            boolean OK = false;
            //Пример управленыя 1 пином, для примера wemos d1 mini, pin - D4(gpio02)
            if (command == "STATUS"){
              if(digitalRead(D4) == LOW )
                StatusPin = "[1,1,1,0,0,0,1,0]";
              else  
                StatusPin = "[0,1,1,0,0,0,1,0]";
              OK =true;
            }

            if (command == "ON_1"){
              StatusPin = "[1,1,1,0,0,0,1,0]";//Включить
              digitalWrite(LED_BUILTIN, LOW);
              OK =true;
            }
            if (command == "OFF_1"){
              StatusPin = "[0,1,1,0,0,0,1,0]";//Выключить
              OK =true;
              digitalWrite(LED_BUILTIN, HIGH);
            }

            //Для остальных ON_2,OFF_2,ON_3,OFF_3... и сколько пинов хватет
            
            //Если команда выполнена успешно
            if(OK)
              webSocket.sendTXT("{\"Name\":\""+Name+"\",\"Status\":"+StatusPin+",\"Device\":"+Device+"}");
            else
              webSocket.sendTXT("{\"Name\":\""+Name+"\",\"Status\":"+"\"Not support command\""+"}");
  }

//Сдесь обработка собитиый, взята стандартная
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {

	switch(type) {
		case WStype_DISCONNECTED:
			USE_SERIAL.printf("[WSc] Disconnected!\n");
			break;
		case WStype_CONNECTED: {
			USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
          runCommand("STATUS");
		}
			break;
		case WStype_TEXT:{
			String text = (char*) payload;
			USE_SERIAL.printf("[WSc] get text: %s\n", payload);
      JsonObject& root = jsonBuffer.parseObject(text);
      //Проверяем коррекность полученого сообщения
      if (!root.success()){
         USE_SERIAL.println("Error message");
      }
      else{//Обрабатует тоько полученые от контроллера, и только если адресованы нам
        if (root["Name"] == "Controller"){
          if (root["Client"] == String(WiFi.macAddress()) || root["Client"] == "ALL")
          { 
            String command = root["Command"];
            runCommand(command);
          }
        }          
     }
		}
			break;
		case WStype_BIN:
			USE_SERIAL.printf("[WSc] get binary length: %s\n", length);
			hexdump(payload, length);
			break;
    case WStype_ERROR:
			USE_SERIAL.printf("[WSc] Error connection: %s\n", payload);
			break;
	}

}

void setup() {
  

  pinMode(D7, INPUT);  //Замкнуть на GND, перезапустить, вовдет в режым настройки параметров подключеныя
  pinMode(D4, OUTPUT); //Пин для управленыя
  digitalWrite(LED_BUILTIN, HIGH);   
  int buttonState = 0; 
  buttonState = digitalRead(D7);

  byte len_ssid, len_pass, len_server, len_port ;
	EEPROM.begin(98);
   delay(1000);
   Serial.begin(115200);
   Serial.println("start");
 //Еслы D7 замкныта на GND заходив в режым настройки параметров   
 if (buttonState == HIGH) {
    len_server = EEPROM.read(94);
    len_port = EEPROM.read(95);
    len_ssid = EEPROM.read(96);
    len_pass = EEPROM.read(97);
        // Режим STATION
          WiFi.mode( WIFI_STA);
          unsigned char* buf_ssid = new unsigned char[32];
          unsigned char* buf_pass = new unsigned char[48];
          unsigned char* buf_server = new unsigned char[64];
          unsigned char* buf_port = new unsigned char[80];
          for(byte i = 0; i < len_ssid; i++) buf_ssid[i] = char(EEPROM.read(i));
          buf_ssid[len_ssid] = '\x0';
          const char *ssid  = (const char*)buf_ssid;
          for(byte i = 0; i < len_pass; i++) buf_pass[i] = char(EEPROM.read(i + 32));
          const char *pass  = (const char*)buf_pass;
          buf_pass[len_pass] = '\x0';

          for(byte i = 0; i < len_server; i++) buf_server[i] = char(EEPROM.read(i + 48));
          const char *server_  = (const char*)buf_server;
          buf_server[len_server] = '\x0';

          for(byte i = 0; i < len_port; i++) buf_port[i] = char(EEPROM.read(i + 80));
          const char *port_  = (const char*)buf_port;
          buf_port[len_port] = '\x0';


          Serial.print("SSID: ");
          Serial.print(ssid);
          Serial.print("   ");
          Serial.print("Password: ");
          Serial.print(pass);
          Serial.print("   ");
          Serial.print("Server ws: ");
          Serial.print(server_);
          Serial.print("   ");
          Serial.print("Port ws: ");
          Serial.println(port_);

          
         
          WiFi.begin(ssid, pass);
          // Wait for connection
          int start = 0;
          while ( WiFi.status() != WL_CONNECTED ) {
            delay ( 500 );
            Serial.print ( "." );
            start = start +1;
            if(start > 100 )
            {
              //Ну удалось подключиться по указаным настройкам, переходим в режым настройки параметров   
              start_server();
              break;
            }
            
          }
          //Если все удачно, подключаемся у серверу
          if(WiFi.status() == WL_CONNECTED)
          {
      
            Serial.println();
            Serial.print("Connected to ");
            Serial.println(ssid);
            Serial.print("IP address: ");
            Serial.println(WiFi.localIP());    
            //---------------------------
              String port_ws;
              port_ws = String(port_);
              int port_ws_ = port_ws.toInt();
              webSocket.begin(server_, port_ws_, "/");
              webSocket.onEvent(webSocketEvent);
            //  webSocket.setAuthorization("user", "Password");
              webSocket.setReconnectInterval(5000);
         }


  } else {start_server();}

}

void loop() {

	webSocket.loop();
  server.handleClient();
  // здесь будет код, который будет работать постоянно
  // и который не должен останавливаться на время между переключениями 
  unsigned long currentMillis = millis();
    //проверяем не прошел ли нужный интервал, если прошел то
  if(currentMillis - previousMillis > interval) {
    // сохраняем время последнего переключения
    previousMillis = currentMillis; 
      runCommand("STATUS");
  }
  if(currentMillis > interval_restart) {
      //Перезапускаем ESP 
      ESP.restart();
  }
}
//Форма для ввода параметров
void handleRoot() {
  String str = "";
  str += html_header;
  str += "<body>\
   <form method=\"POST\" action=\"ok\">\
     <input name=\"ssid\"> WIFI Net</br>\
     <input name=\"pswd\"> Password</br></br>\
     <input name=\"server_ws\"> Server ws</br></br>\
     <input name=\"port_ws\"> Port ws</br></br>\
     <input type=SUBMIT value=\"Save settings\">\
   </form>\
 </body>\
</html>";
server.send ( 200, "text/html", str );
}
//Обработка полученых параметров 
void handleOk(){
  String ssid_ap;
  String pass_ap;
  String server_ws;
  String port_ws;
  unsigned char* buf = new unsigned char[64];
 
  String str = "";
  str += html_header;
  str += "<body>";
 
  EEPROM.begin(98);
 
  ssid_ap = server.arg(0);
  pass_ap = server.arg(1);
  
  server_ws = server.arg(2);
  port_ws =  server.arg(3);
 
  if(ssid_ap != ""){
    EEPROM.write(94,server_ws.length());
    EEPROM.write(95,port_ws.length());
    EEPROM.write(96,ssid_ap.length());
    EEPROM.write(97,pass_ap.length());
    ssid_ap.getBytes(buf, ssid_ap.length() + 1);
    for(byte i = 0; i < ssid_ap.length(); i++)
      EEPROM.write(i, buf[i]);
    pass_ap.getBytes(buf, pass_ap.length() + 1);
    for(byte i = 0; i < pass_ap.length(); i++)
      EEPROM.write(i + 32, buf[i]);
    
    server_ws.getBytes(buf, server_ws.length() + 1);
    for(byte i = 0; i < server_ws.length(); i++)
      EEPROM.write(i + 48, buf[i]);
    port_ws.getBytes(buf, port_ws.length() + 1);
    for(byte i = 0; i < port_ws.length(); i++)
      EEPROM.write(i + 80, buf[i]);      
    
    EEPROM.commit();
    EEPROM.end();
   
    str +="Configuration saved in FLASH</br>\
   Changes applied after reboot</p></br></br>\
   <a href=\"/\">Return</a> to settings page</br>";
  }
  else {
    str += "No WIFI Net</br>\
   <a href=\"/\">Return</a> to settings page</br>";
  }
  str += "</body></html>";
  server.send ( 200, "text/html", str );
}
//Запуск настройки параметров
void start_server()
{
     const char *ssid_ap = "ESPap";
     WiFi.mode(WIFI_AP);
     Serial.print("Configuring access point...");
    /* You can remove the password parameter if you want the AP to be open. */
     WiFi.softAP(ssid_ap);
 
    delay(2000);
    Serial.println("done");
    IPAddress myIP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(myIP);
    server.on("/", handleRoot);
        server.on("/ok", handleOk);
    server.begin();
    Serial.println("HTTP server started"); 
}

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Сервер обмена:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
#include <WebSocketsServer.h>
#include <Hash.h>
#include <FS.h>
 
String str = "";
boolean conf = false;

long previousMillis = 1000;        // храним время последнего переключения 
long interval = 1000;          // интервал между миганием
byte ledState = LOW;
 
String html_header = "<html>\
 <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\
 <head>\
   <title>ESP8266 Settings</title>\
   <style>\
     body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
   </style>\
 </head>";
 
ESP8266WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {

    switch(type) {
        case WStype_DISCONNECTED:
            Serial.printf("[%u] Disconnected!\n", num);
            break;
        case WStype_CONNECTED:
            {
                IPAddress ip = webSocket.remoteIP(num);
                Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
           }
            break;
        case WStype_TEXT:
            Serial.printf("[%u] get Text: %s\n", num, payload);
            webSocket.broadcastTXT(payload);
            break;
        case WStype_BIN:
            Serial.printf("[%u] get binary length: %u\n", num, length);
            hexdump(payload, length);
            break;
    }

}

void setup(void)
{
    pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
    
    byte len_ssid, len_pass;
   
    delay(1000);
    Serial.begin(115200);
    Serial.println("start");  


    EEPROM.begin(98);
    len_ssid = EEPROM.read(96);
    len_pass = EEPROM.read(97);
    if(len_pass > 64) len_pass = 0;
     if((len_ssid < 33) && (len_ssid != 0)){
        // Режим STATION
          WiFi.mode( WIFI_STA);
          unsigned char* buf_ssid = new unsigned char[32];
          unsigned char* buf_pass = new unsigned char[64];
          for(byte i = 0; i < len_ssid; i++) buf_ssid[i] = char(EEPROM.read(i));
          buf_ssid[len_ssid] = '\x0';
          const char *ssid  = (const char*)buf_ssid;
          for(byte i = 0; i < len_pass; i++) buf_pass[i] = char(EEPROM.read(i + 32));
          const char *pass  = (const char*)buf_pass;
          buf_pass[len_pass] = '\x0';
         
          Serial.print("SSID: ");
          Serial.print(ssid);
          Serial.print("   ");
          Serial.print("Password: ");
          Serial.println(pass);
         
          WiFi.begin(ssid, pass);
          // Wait for connection
          int start = 0;
          while ( WiFi.status() != WL_CONNECTED ) {
            delay ( 500 );
            Serial.print ( "." );
            start = start +1;
            if(start > 100 )
            {
              
              start_server();
              break;
            }
            
          }
          
          if(WiFi.status() == WL_CONNECTED)
          {
            SPIFFS.begin();
            Serial.println();
            Serial.print("Connected to ");
            Serial.println(ssid);
            Serial.print("IP address: ");
            Serial.println(WiFi.localIP());    
            //---------------------------
            WiFi.softAP("ESP-Server", "");
            delay(2000);      
            IPAddress myIP = WiFi.softAPIP();
            Serial.print("AP IP address: ");
            Serial.println(myIP);     
            server.on("/", serveIndexFile);            
            server.on("/status", handleRootStatus);            
            server.begin();
            Serial.println("HTTP server started"); 
          }

    }
    else // Режим SoftAP
      {
        start_server();
      }  
  
  
    webSocket.begin();
    webSocket.onEvent(webSocketEvent);
 
Serial.println("stop");     
}
void loop() {

  // здесь будет код, который будет работать постоянно
  // и который не должен останавливаться на время между переключениями свето
  unsigned long currentMillis = millis();
    //проверяем не прошел ли нужный интервал, если прошел то
  if(currentMillis - previousMillis > interval) {
    // сохраняем время последнего переключения
    previousMillis = currentMillis; 
    
    // если светодиод не горит, то зажигаем, и наоборот
    if (ledState == LOW)
      ledState = HIGH;  // Note that this switches the LED *off*
    else
      ledState = LOW;   // Note that this switches the LED *on*

    digitalWrite(LED_BUILTIN, ledState); 
   
    // устанавливаем состояния выхода, чтобы включить или выключить светодиод
  }

  server.handleClient();
  webSocket.loop();
}
 
void handleRootStatus() {
  String str = "";
  String str_ip = "";
  IPAddress ip = WiFi.localIP();
  str_ip = String(ip[0])+"." +String(ip[1])+"."+String(ip[2])+"."+String(ip[3]);
  str += html_header;
  str += "<body>\
      <H1>Server Smart House</H1>\
      <p>ip -"+str_ip+     
 "</body>\
</html>";
server.send ( 200, "text/html", str );
}

void handleRoot() {
  String str = "";
  str += html_header;
  str += "<body>\
   <form method=\"POST\" action=\"ok\">\
     <input name=\"ssid\"> WIFI Net</br>\
     <input name=\"pswd\"> Password</br></br>\
     <input type=SUBMIT value=\"Save settings\">\
   </form>\
 </body>\
</html>";
server.send ( 200, "text/html", str );
}
 
void handleOk(){
  String ssid_ap;
  String pass_ap;
  unsigned char* buf = new unsigned char[64];
 
  String str = "";
  str += html_header;
  str += "<body>";
 
  EEPROM.begin(98);
 
  ssid_ap = server.arg(0);
  pass_ap = server.arg(1);
 
  if(ssid_ap != ""){
    EEPROM.write(96,ssid_ap.length());
    EEPROM.write(97,pass_ap.length());
    ssid_ap.getBytes(buf, ssid_ap.length() + 1);
    for(byte i = 0; i < ssid_ap.length(); i++)
      EEPROM.write(i, buf[i]);
    pass_ap.getBytes(buf, pass_ap.length() + 1);
    for(byte i = 0; i < pass_ap.length(); i++)
      EEPROM.write(i + 32, buf[i]);
    EEPROM.commit();
    EEPROM.end();
   
    str +="Configuration saved in FLASH</br>\
   Changes applied after reboot</p></br></br>\
   <a href=\"/\">Return</a> to settings page</br>";
  }
  else {
    str += "No WIFI Net</br>\
   <a href=\"/\">Return</a> to settings page</br>";
  }
  str += "</body></html>";
  server.send ( 200, "text/html", str );
}

void start_server()
{
       const char *ssid_ap = "ESPap";
       
        WiFi.mode(WIFI_AP);
       
        Serial.print("Configuring access point...");
    /* You can remove the password parameter if you want the AP to be open. */
    WiFi.softAP(ssid_ap);
 
     delay(2000);
    Serial.println("done");
    IPAddress myIP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(myIP);
    server.on("/", handleRoot);
        server.on("/ok", handleOk);
    server.begin();
    Serial.println("HTTP server started"); 
}


void serveIndexFile()
{
  File file = SPIFFS.open("/index.html","r");
  server.streamFile(file, "text/html");
  file.close();
}  

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Контроллер:

<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<head>
  <style type="text/css">
    .checkbox input {
      position: absolute;
      z-index: -1;
      opacity: 0;
      margin: 10px 0 0 20px;
    }
    .checkbox__text {
      position: relative;
      padding: 0 0 0 60px;
      cursor: pointer;
    }
    .checkbox__text:before {
      content: '';
      position: absolute;
      top: -4px;
      left: 0;
      width: 50px;
      height: 26px;
      border-radius: 13px;
      background: #CDD1DA;
      box-shadow: inset 0 2px 3px rgba(0,0,0,.2);
      transition: .2s;
    }
    .checkbox__text:after {
      content: '';
      position: absolute;
      top: -2px;
      left: 2px;
      width: 22px;
      height: 22px;
      border-radius: 10px;
      background: #FFF;
      box-shadow: 0 2px 5px rgba(0,0,0,.3);
      transition: .2s;
    }
    .checkbox input:checked + .checkbox__text:before {
      background: #9FD468;
    }
    .checkbox input:checked + .checkbox__text:after {
      left: 26px;
    }
    .checkbox input:focus + .checkbox__text:before {
      box-shadow: inset 0 2px 3px rgba(0,0,0,.2), 0 0 0 3px rgba(255,255,0,.7);
    }

  </style>
</head>
<h2>Contol esp-12e</h2>

<input type="text" id="wsurl">
<button id="connect"> Connect </button>
<br>
<input type="checkbox" id="AutoUpdate"> Autoupdate
<input type="checkbox" id="Log" checked = 1> Syslog
<div id="Controllers"></div>
<!--
<label class="checkbox">
 <input type="checkbox" id="LED1"/>
 <div class="checkbox__text">Led_1</div>
</label>
<br>


<label class="checkbox">
 <input type="checkbox" id="LED2"/>
 <div class="checkbox__text">Led_2</div>
</label>
-->


<!--
        <button id="button_ON_LED1">ON LED_1</button>
        <button id="button_OFF_LED1">OFF LED_1</button>
        <button id="button_ON_LED2">ON LED_2</button>
        <button id="button_OFF_LED2">OFF LED_2</button>
-->

<div id="output"></div>

<script language="javascript" type="text/javascript">

    //var wsUri = "wss://echo.websocket.org/";
    var wsUri = "";
    var output;
    var interval;
    var clientArray = new Array();
    var debug = true;//Через консоль задать true, будет выден лог РѕР±РСена
    function init()
    {
        output = document.getElementById("output");
        initWebSocket();
    }

    function initWebSocket()
    {
        websocket = new WebSocket(wsUri);
        websocket.onopen = function(evt) { onOpen(evt) };
        websocket.onclose = function(evt) { onClose(evt) };
        websocket.onmessage = function(evt) { onMessage(evt) };
        websocket.onerror = function(evt) { onError(evt) };
    }

    function onOpen(evt)
    {
        writeToScreen("CONNECTED");
        doSend(JSON.stringify({"Name":"Controller","Command":"STATUS","Client":"ALL"}));
    }

    function onClose(evt)
    {
        writeToScreen("DISCONNECTED");//heroku.com
        setTimeout(initWebSocket,5000);
    }

    function onMessage(evt)
    {
        var JSONcommand;
        try {
            JSONcommand = JSON.parse(evt.data);
        }
        catch (e) {
            writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
            return;
        }

        if( (JSONcommand.Name != "Controller") )
        {

            var res = clientArray.find(function(e){return e == JSONcommand.Name });
            if(res == undefined){//
                clientArray.push(JSONcommand.Name);
                console.log("add new client");

                if (JSONcommand.Device == "Relay") {
                    if (Array.isArray(JSONcommand.Status)) {
                        AddCheckbox(JSONcommand.Name, JSONcommand.Status.length);
                        UpdateStatusRelay(JSONcommand.Name, JSONcommand.Status);
                    }
                }
            }
            else//
            {
                if (JSONcommand.Device == "Relay") {
                    UpdateStatusRelay(JSONcommand.Name,JSONcommand.Status);
                }
            }

         }
          if(debug = 1)
              writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
    }

    function onError(evt)
    {
        writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
    }

    function doSend(message)
    {
        writeToScreen("SENT: " + message);

        websocket.send(message);
    }

    function writeToScreen(message)
    {
        if(debug){
            var pre = document.createElement("p");
            pre.style.wordWrap = "break-word";
            pre.innerHTML = message;
            output.appendChild(pre);
        }

    }

    window.addEventListener("load", function () {
        var serverhouse = localStorage.getItem("ServerHouse");
        if (serverhouse != null)
        {
            wsUri = serverhouse;
            document.getElementById("wsurl").value = wsUri;
            init();
        }
    }, false);


    function AddCheckbox(comment,pin) {//Для Relay

        var root = document.getElementById("Controllers");
        var pre = document.createElement("div");
        pre.innerHTML = "<H2>"+comment+"</H2>";
        root.appendChild(pre);
        root = pre;

        var a = 1;
        while (a <= pin ){
            pre = document.createElement("p");
            root.appendChild(pre);
            pre = document.createElement("label");
            pre.className = "checkbox";
            root.appendChild(pre);
            root  = pre;
            pre = document.createElement("input");
            pre.type = "checkbox";
            pre.id = comment+"_pin_"+a;
            pre.i = a;
            pre.addEventListener("change",function () {
                if(this.checked) {
                    doSend(JSON.stringify({"Name":"Controller","Command":"ON_"+this.i,"Client":comment}));
                } else {
                    doSend(JSON.stringify({"Name":"Controller","Command":"OFF_"+this.i,"Client":comment}));
                }
            });

            root.appendChild(pre);
            pre = document.createElement("div");
            pre.className = "checkbox__text";
            pre.innerHTML = "Led "+a;
            root.appendChild(pre);
            root = document.getElementById("Controllers");
            pre = document.createElement("br");
            root.appendChild(pre);
            a++;
        }
    }

    function UpdateStatusRelay(comment,pin) {
        if(Array.isArray(pin))
        {
            for(var i = 0;i <= pin.length-1;i++)
            {
                document.getElementById(comment+"_pin_"+(i+1)).checked = pin[i];
            }
        }
    }

    document.getElementById("Log").addEventListener("change",function () {
        if(this.checked)
            debug = true;
        else
            debug = false;
    })


    document.getElementById("AutoUpdate").addEventListener("change",function () {
        if(this.checked) {
            interval = setInterval(function () {
                var root = document.getElementById("Controllers");
                while (root.firstChild) {
                    root.removeChild(root.firstChild);
                }
                clientArray  = [];
                doSend(JSON.stringify({"Name":"Controller","Command":"STATUS","Client":"ALL"}));
            },60*1000);//Раз в минуту проверяем клиентов
        } else {


            clearInterval(interval);
        }
    })

    document.getElementById("connect").addEventListener("click",function () {
        wsUri = document.getElementById("wsurl").value;
        localStorage.setItem("ServerHouse",wsUri);
        init();
    })

</script>

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Поиграться устройстовм можно тут:

https://test-websoket.herokuapp.com

vitalikost
Offline
Зарегистрирован: 28.11.2014

Строка  подключения:

На Herokuapp.com - wss://test-websoket.herokuapp.com

Если 2 есп, ws://192.168.0.4:81/, или ws://"адрес  который выдал роутер":81/

Чтобы узнать адрес ,который выдал роутер, можно подключиться к точке "ESP-Server", перейти по адресу http://192.168.4.1/status

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Слишком сложно для местных =))

vitalikost
Offline
Зарегистрирован: 28.11.2014

Это еще я упростил, зараз клиенте реализовано:

  1. Восстановленные состояние пинов после выключения
  2. Резервное управление кнопками, с обратной связью.
  3. Сделано 2 устройства, 1 – конечное, 2 – стенд.