Сбрасывается цвет кнопки
- Войдите на сайт для отправки комментариев
Вс, 08/05/2022 - 17:21
Проблема скорей комсетическая. И так, есть вэб панель управления кнопками. Когда кнопки в состоянии OFF, то должны быть красного цвета. Переключаем в стояние ON, кнопка как и положено меняет цвет на зеленной. Вроде всё нормально. Но стоит обновить страницу, зеленный цвет сбрасывается, хотя статус так и остался ON.
// Импортируем библиотеки #include <WiFi.h> #include <AsyncTCP.h> #include <ESPAsyncWebServer.h> #include "SPIFFS.h" #include <AsyncElegantOTA.h> // Задаем сетевые настройки const char* ssid = "uname"; const char* password = "password"; AsyncWebServer server(80); // Создаем сервер через 80 порт AsyncWebSocket ws("/ws"); // Создаем объект WebSocket // Запускаем SPIFFS void initSPIFFS() { if (!SPIFFS.begin(true)) { Serial.println("Произошла ошибка при монтировании SPIFFS"); } Serial.println("SPIFFS примонтировано успешно"); } // Запускаем WiFi void initWiFi() { WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.print("Подключаюсь к WiFi ..."); while (WiFi.status() != WL_CONNECTED) { Serial.print('.'); delay(500); } Serial.println(WiFi.localIP()); } bool ledState1 = 0; bool ledState2 = 0; bool ledState3 = 0; bool ledState4 = 0; bool ledState5 = 0; // Уведомляем клиентов о текущем состоянии светодиода void notifyClients1() {ws.textAll(String(ledState1));} void notifyClients2() {ws.textAll(String(ledState2 + 2));} void notifyClients3() {ws.textAll(String(ledState3 + 4));} void notifyClients4() {ws.textAll(String(ledState4 + 6));} void notifyClients5() {ws.textAll(String(ledState5 + 8));} /* функция обратного вызова, которая запускается всякий раз, когда мы получаем новые данные от клиентов по протоколу WebSocket. Если мы получаем сообщение “toggle”, мы переключаем значение переменной ledState. Кроме того, мы уведомляем всех клиентов, вызывая функцию notifyClients (). Таким образом, все клиенты получают уведомление об изменении и соответствующим образом обновляют интерфейс.*/ void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) { AwsFrameInfo *info = (AwsFrameInfo*)arg; if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) { data[len] = 0; if (strcmp((char*)data, "toggle1") == 0) {ledState1 = !ledState1;notifyClients1();} if (strcmp((char*)data, "toggle2") == 0) {ledState2 = !ledState2;notifyClients2();} if (strcmp((char*)data, "toggle3") == 0) {ledState3 = !ledState3;notifyClients3();} if (strcmp((char*)data, "toggle4") == 0) {ledState4 = !ledState4;notifyClients4();} if (strcmp((char*)data, "toggle5") == 0) {ledState5 = !ledState5;notifyClients5();} } } // Настройка прослушивателя событий для обработки различных асинхронных шагов протокола WebSocket void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { switch (type) { case WS_EVT_CONNECT: // когда клиент вошел в систему Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str()); break; case WS_EVT_DISCONNECT: // когда клиент вышел из системы Serial.printf("WebSocket client #%u disconnected\n", client->id()); break; case WS_EVT_DATA: // при получении пакета данных от клиента handleWebSocketMessage(arg, data, len); break; case WS_EVT_PONG: // в ответ на запрос ping case WS_EVT_ERROR: // при получении ошибки от клиента break; } } String processor(const String& var) { Serial.println(var); if (var == "STATE1") {if (ledState1) {return "ON";} else {return "OFF";}} if (var == "STATE2") {if (ledState2) {return "ON";} else {return "OFF";}} if (var == "STATE3") {if (ledState3) {return "ON";} else {return "OFF";}} if (var == "STATE4") {if (ledState4) {return "ON";} else {return "OFF";}} if (var == "STATE5") {if (ledState5) {return "ON";} else {return "OFF";}} } // Инициализация WebSocket void initWebSocket() { ws.onEvent(onEvent); server.addHandler(&ws); } void setup() { // Последовательный порт для отладки Serial.begin(115200); pinMode(32, OUTPUT); digitalWrite(32, LOW); pinMode(33, OUTPUT); digitalWrite(33, LOW); pinMode(25, OUTPUT); digitalWrite(25, LOW); pinMode(26, OUTPUT); digitalWrite(26, LOW); pinMode(27, OUTPUT); digitalWrite(27, LOW); initSPIFFS(); initWiFi(); initWebSocket(); // Начальная страница server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, "/index.html", "text/html", false, processor); }); server.serveStatic("/", SPIFFS, "/"); // Запускаем ElegantOTA AsyncElegantOTA.begin(&server); // Запускаем сервер server.begin(); } void loop() { AsyncElegantOTA.loop(); ws.cleanupClients(); digitalWrite(32, ledState1); digitalWrite(33, ledState2); digitalWrite(25, ledState3); digitalWrite(26, ledState4); digitalWrite(27, ledState5); }
JavaScript
var gateway = `ws://${window.location.hostname}/ws`; var websocket; window.addEventListener('load', onLoad); function initWebSocket() { console.log('Trying to open a WebSocket connection...'); websocket = new WebSocket(gateway); websocket.onopen = onOpen; websocket.onclose = onClose; websocket.onmessage = onMessage; } function onOpen(event) { console.log('Connection opened'); } function onClose(event) { console.log('Connection closed'); setTimeout(initWebSocket, 2000); } function onMessage(event) { switch(event.data) { case '0': document.getElementById("state1").innerHTML = "OFF"; document.getElementById('button1').style.backgroundColor = "#c90411"; break; case '1': document.getElementById("state1").innerHTML = "ON "; document.getElementById('button1').style.backgroundColor = "#04b50a"; break; case '2': document.getElementById("state2").innerHTML = "OFF"; document.getElementById('button2').style.backgroundColor = "#c90411"; break; case '3': document.getElementById("state2").innerHTML = "ON "; document.getElementById('button2').style.backgroundColor = "#04b50a"; break; case '4': document.getElementById("state3").innerHTML = "OFF"; document.getElementById('button3').style.backgroundColor = "#c90411"; break; case '5': document.getElementById("state3").innerHTML = "ON "; document.getElementById('button3').style.backgroundColor = "#04b50a"; break; case '6': document.getElementById("state4").innerHTML = "OFF"; document.getElementById('button4').style.backgroundColor = "#c90411"; break; case '7': document.getElementById("state4").innerHTML = "ON "; document.getElementById('button4').style.backgroundColor = "#04b50a"; break; case '8': document.getElementById("state5").innerHTML = "OFF"; document.getElementById('button5').style.backgroundColor = "#c90411"; break; case '9': document.getElementById("state5").innerHTML = "ON "; document.getElementById('button5').style.backgroundColor = "#04b50a"; break; } } function onLoad(event) {initWebSocket(); initButton();} function initButton() { document.getElementById('button1').addEventListener('click', toggle1); document.getElementById('button2').addEventListener('click', toggle2); document.getElementById('button3').addEventListener('click', toggle3); document.getElementById('button4').addEventListener('click', toggle4); document.getElementById('button5').addEventListener('click', toggle5); } function toggle1(){websocket.send('toggle1');} function toggle2(){websocket.send('toggle2');} function toggle3(){websocket.send('toggle3');} function toggle4(){websocket.send('toggle4');} function toggle5(){websocket.send('toggle5');}
html
<!DOCTYPE HTML> <html> <head> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="data:,"> <link rel="stylesheet" type="text/css" href="style.css"> <title>ESP Web Server</title> </head> <body> <div class="topnav"> <h1>ESP WebSocket Server</h1> </div> <div class="content"> <div class="card"> <h2>Out - GPIO 32</h2> <p class="state">Status: <span id="state1">%STATE1%</span></p> <p><button id="button1" class="button">Button 1</button></p> <h2>Out - GPIO 33</h2> <p class="state">Status: <span id="state2">%STATE2%</span></p> <p><button id="button2" class="button">Button 2</button></p> <h2>Out - GPIO 25</h2> <p class="state">Status: <span id="state3">%STATE3%</span></p> <p><button id="button3" class="button">Button 3</button></p> <h2>Out - GPIO 26</h2> <p class="state">Status: <span id="state4">%STATE4%</span></p> <p><button id="button4" class="button">Button 4</button></p> <h2>Out - GPIO 27</h2> <p class="state">Status: <span id="state5">%STATE5%</span></p> <p><button id="button5" class="button">Button 5</button></p> <br> <br> <div><a href="/update" class="ota">Update</a></div> <br> </div> </div> <script src="/script.js"></script> </body> </html>
Как сделать чтобы обновление страницы не изменяло цвет кнопок? Цвет кнопок должен быть привязан исключительно к состоянию ON или OFF.
На onload сразу запросить состояние с вебсокета, а дальше связанные функции сами справятся. Ну, или в куках хранить, но это так себе способ.
Адольф, ты чего опять тупишь то на ровном месте? Ты html откуда «отдаёшь»? С esp? Менять там же бэкграунд можешь? Намёк понят? ))))
Адольф, ты чего опять тупишь то на ровном месте? Ты html откуда «отдаёшь»? С esp? Менять там же бэкграунд можешь? Намёк понят? ))))
Бум, тупить мое нормальное состояние. Бекграунд там указан. Ты его в html не видишь, потому как он указан в файле стилей style.css параметр background-color: #c90411; Ну вот представь теперь. Допустим кнопка в положении ON (зеленненькая), обновил страницу она бац, стала красной. Потому как раз перечитали из беграунда.
Бум, тупить мое нормальное состояние. Бекграунд там указан. Ты его в html не видишь, потому как он указан в файле стилей style.css параметр background-color: #c90411; Ну вот представь теперь. Допустим кнопка в положении ON (зеленненькая), обновил страницу она бац, стала красной. Потому как раз перечитали из беграунда.
Я имел в виду динамически менять сам html-код, чтобы отдавать сразу "правильный", вот так:
В css добавить стиль button_on с бэкграундом включенной кнопки (стиль button лучше переименовать в button_off, чтобы не путаться). Ну и кури str_replace () какой-нибудь.
Ну чего там? Или ещё продолжение празднования?)))))
ЗЫ: #4 не исключает всего ранее проделанного, а дополняет.
Ну чего там? Или ещё продолжение празднования?)))))
ЗЫ: #4 не исключает всего ранее проделанного, а дополняет.
BOOM ты в NodeJS и REACT шаришь? На хостинг устанавливал?
BOOM ты в NodeJS и REACT шаришь? На хостинг устанавливал?
Не, когда я веб говнокодил еще их и в проекте не было )))
Ну чего там? Или ещё продолжение празднования?)))))
ЗЫ: #4 не исключает всего ранее проделанного, а дополняет.
В html создаем два id, каждый для своего класса.
html
Style.css
ЗЫ. Похоже при обновлении страницы таки вызывает "function onOpen(event)". До дома доберусь попробую запустить из этой функции.
на данном форуме острить по этому поводу крайне НЕ рекомендуется.
Адольф! Ещё раз - не тупи. Зачем ты лезешь в сложности с Явой? Я же написал выше - изменяй отдаваемый с esp html, ты же его с esp отдаёшь «клиенту» или откуда? Меняй сразу сам отдаваемый клиенту html.
Не стесняйся спрашивать.
Адольф! Ещё раз - не тупи. Зачем ты лезешь в сложности с Явой? Я же написал выше - изменяй отдаваемый с esp html, ты же его с esp отдаёшь «клиенту» или откуда? Меняй сразу сам отдаваемый клиенту html.
Не стесняйся спрашивать.
Да с esp конечно. Весь код лежит в трех файлах, index.html, style.css и script.js. Бум, по твоему рецепту нифига не выходит.
style.css
index.html
PHP не знаю, поэтому не уверен в корректности второй строки. Кроме того не понятно как переменная $resulat при обновлении страницы вызывается?
ESP научилась работать интерпретатором PHP и таскать его из HTML? Чего только не узнаешь на форуме Arduino.
Да с esp конечно. Весь код лежит в трех файлах, index.html, style.css и script.js. Бум, по твоему рецепту нифига не выходит.
index.html
Это, конечно же, не верный подход. Во первых - на сколько я знаю php не портировали никогда на ESP. Во вторых - какой смысл использовать интерпретатор там, где он не нужен? Ну и в третьих - "шаблон" (html) должен иметь четкие однозначные "метки".
Я только еще заказал esp себе и точно утверждать не могу в правильности кода, но надеюсь хотя бы основную мысль донесу. Собственно так как я не знаю как у тебя организовано "хранение всех трех файлов" и как организована "отдача их клиенту" (кстати, напиши и то и другое ... ), поэтому я просто беру пример из интернета.
index.h
Дальше, считываем содержимое прогмем (так ты делаешь?) и меняем в шаблоне значения "меток" на конкретные значения. Ну, например, так:
Не уверен в правильности, но суть такая.
Собственно говоря, об этом же я тебе говорил когда ты уперся в "в разных места меняется тра-та-та". Какая разница где там что меняется? В переменных запомнил что поменялось и потом разом поменял в шаблоне и отдал клиенту. В следующий раз что-то поменялось - так же прочитал шаблон, поменял в нем все метки на значения и отдал клиенту. Ну и так далее.
Я так делал, и всё автоматом обновляется (ajax)
Ajax это же не только ява-скрипт на стороне клиента, но еще и ответная часть на "сервере". Поэтому в итоге получается сложнее (на мой взгляд).
Добрался таки до форума к выходным.)
Собственно так как я не знаю как у тебя организовано "хранение всех трех файлов" и как организована "отдача их клиенту" (кстати, напиши и то и другое ... )
Прогемов нет. Все три файла index.html, style.css и style.js хранятся в FS SPIFFS флеш памяти. Аля виртуальная SD карта )).
Отдается клиенту так
Я так делал, и всё автоматом обновляется (ajax)
IMHO Крутить каждую секунду функцию с целью проверки на предмет изменилось ли там состояние кнопки или нет, не очень рационально.
Правильно?
Бл..
или запроси в онлоаде через ajax с ESP https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onl...
или формируй html программно на стороне ESP.
Других вариантов у тебя нет.
Решено! В функции onEvent после строки 70 добавил условный оператор
А если войти с нового устройства?
А если войти с нового устройства?