esp8266 вывод данных онлайн

iopq
Offline
Зарегистрирован: 05.07.2016

подскажите пожалуйста как лучше поступить. нужно показания счетчика вывести в локальной сети на страничку. для этих целей было решено применить esp8266. но столкнулся с некими трудностями. первая это не срабатывает событие onerror при обрыве соединения - 

#include <ESP8266WebServer.h>
#include <WebSocketsServer.h>

String ssid = "xxx";
String password = "xxx";

ESP8266WebServer server(80); 
WebSocketsServer socket = WebSocketsServer(91);

int i = 0;

void setup(void) {

  server.begin();
  socket.begin();

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

}


void loop(void) {

  server.handleClient();
  delay(10);
  socket.loop();
  String str = String(i++);
  socket.broadcastTXT(str);

}
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">

        $(document).ready(function() {

            $("#status").text('Offline');
            $("#status").css('color', 'red');

            var socket = new WebSocket("ws://192.168.1.187:91/");
            socket.onopen = function () {
                $("#status").text('Online');
                $("#status").css('color', 'green');
            };

            socket.onclose = function () {
                $("#status").text('Offline');
                $("#status").css('color', 'red');
            };

            socket.onerror = function(event) {
                $("#status").text('Offline');
                $("#status").css('color', 'red');
            };

            google.charts.load('current', {'packages': ['gauge']});
            google.charts.setOnLoadCallback(drawChart);

            function drawChart() {

                var data = google.visualization.arrayToDataTable([
                    ['Label', 'Value'],
                    ['ESP8266', 0]
                ]);

                var options = {
                    width: 800, height: 240,
                    redFrom: 90000, redTo: 100000,
                    yellowFrom: 75000, yellowTo: 90000,
                    minorTicks: 5, max: 100000
                };

                var chart = new google.visualization.Gauge(document.getElementById('chart_div'));

                chart.draw(data, options);

                socket.onmessage = function (event) {
                    data.setValue(0, 1, event.data);
                    chart.draw(data, options);
                }
            }
        });
    </script>
</head>
<body>
<div id="chart_div" style="width: 800px; height: 240px;"></div>
<div id="status"></div>
</body>
</html>

т. е если обесточить esp8266 данные поступать перестают, но статус не меняется

Logik
Offline
Зарегистрирован: 05.08.2014

Обесточить - это не корректно разорвать соединение. Там ниче не гарантируется, особенно сразу. Отсылай по вебсокету периодический 'пинг'. Как он пропадает - разрыв значить.

iopq
Offline
Зарегистрирован: 05.07.2016

просто не работал с сокетами и не знал таких вещей. 

вторая трудность - счетчик сам ничего не сообщает. ему нужно отправлять команду и получать ответ. в начале я хотел загрузить список команд на esp8266 и получать с минимально возможным интервалом ответы, которые пересылать по вебсокету. но теперь, наверное , логичнее их и использовать как пинг? но новая трудность в виде таскания за собой html странички. ведь вряд ли esp8266 потянет даже то что я привел выше?

Logik
Offline
Зарегистрирован: 05.08.2014

Так сделай чтоб счётчик отправлял сам. Периодически или при изменении значения. Оно в socketW.onmessage и прилетит. Хотя и запрос-ответ вполне удобно.

Такую страничку esp вполне потянет. Но можно хранить страничку на совершенно левом сервере, а esp тогда только вебсокет будет поддерживать. В общем как удобней - так и делай. Единственное, помню, были проблемы, когда здоровенную статическую страницу одним сендом пытался отправить то падало. А по частям и 100КБ уходят.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

Обесточить - это не корректно разорвать соединение. Там ниче не гарантируется, особенно сразу. Отсылай по вебсокету периодический 'пинг'. Как он пропадает - разрыв значить.

а на ESP32 ping в какой библиотеке, вчера что-то не нашёл (пришли два девайса, пытаюсь до вэбсокетов добраться в изучении)?
Сам и отвечу -  <ESP32Ping.h>

iopq
Offline
Зарегистрирован: 05.07.2016

пока сделал так, но что-то мне подсказывает что не удачно -

void loop(void) {
  socket.loop();
  Serial.write(powerParameters, sizeof(powerParameters));
  delay(2);
  if (Serial.available() > 0) {
    for (int i = 0; i < 15; i++) {
      str += String(Serial.read(), HEX);
    }
    socket.loop();
    socket.broadcastTXT(str);
    str = "";
  }
  delay(500);
}
                socket.onmessage = function (event) {
                    data.setValue(0, 1, (parseInt(event.data.substring(3, 7).toString(16),16))/100 );
                    chart.draw(data, options);
                }

 

iopq
Offline
Зарегистрирован: 05.07.2016
void loop() {
  jsonString = "";
  doc["powerParameters"] = getParam(powerParameters, sizeof(powerParameters));
  serializeJson(doc, jsonString);
  delay(5000);
}

//00 03 0A 59 34 00 00 00 00 20 00 13 8C 94 CD
//3й байт - размер ответа
String getParam(byte *command, int leng) {
  String str = "";
  Serial.write(command, leng);
  delay(200);
  if (Serial.available() > 0) {
    Serial.read();
    Serial.read();
    int len = Serial.read(); 
    for (int i = 0; i < len + 2; i++) {
      str += String(Serial.read(), HEX);
    }
  }
  return str;
}

сделал отправку в виде json, что гораздо удобнее. 

iopq
Offline
Зарегистрирован: 05.07.2016

да с библиотекой json проблемы. периодически вместо данных null отправляет. 

я сделал чтение с проверкой crc. есть ли смысл отправлять crc и в браузере еще раз проверять или вебсокет сам контролирует целостность?

Logik
Offline
Зарегистрирован: 05.08.2014

Вебсокет поверх ТСР работает, а ТСР сам все контролирует. Потому в дополнительном crc смыслу особого нет. Правельней конечно найти багу и пофиксить, а не костыль лепить.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

Вебсокет поверх ТСР работает...

вот ты меня озадачил, теперь думаю как на апач с инжинксом вэбсокет прикрутить )))

iopq
Offline
Зарегистрирован: 05.07.2016

что то похоже не правильно делаю. если сделать вот так -

void loop(void) {
  socket.loop();
  String str = String(i++);
  socket.broadcastTXT(str);
}

то данные идут. при обновлении страницы соединение моментально устанавливается и данные продолжают поступать. 

если сделать так -

void loop(void) {
  jsonString = "";
  doc["powerParameters"] = getParam(powerParameters, sizeof(powerParameters));
  serializeJson(doc, jsonString);
  socket.loop();
  socket.broadcastTXT(jsonString);
}

то -

соединение устанавливается очень долго

при обновлении страницы так же нет сразу соединения