Тема для тех, кто хочет делать свои веб проекты.
Понимают, что надо вникать в HTML, CSS, JS.
Но не знают с чего начать, и как это использовать в программе FLProg. Цель этой темы:
Понять принцип и работу встроенных веб блоков FLProg,
а так же нюансы с которыми придется столкнуться на этом пути.
Начнем с того , что ESP у нас будет сервером.
Работать будем с блоком WebServerPage из раздела коммуникации.
содержаниеПоказать
Создаем новый проект ESP.
В дереве проекта, в настройках WiFi модуля, настраиваем ESP как клиента.
Вводим имя и пароль к точке доступа своего WiFi роутера.
Т.е наша ESP с сервером на борту, будет клиентом в сети WiFi роутера,
а мы (пользователи) будем клиентами, роутера, и ESP.
Ключевое звено в этой сети будет WiFi роутер, он распределяет ИП адреса устройствам.
Этот адрес роутер арендует на какое то время (несколько дней), после чего меняет его на другой. Первый нюанс с которым мы сталкиваемся - как узнать, какой адрес роутер предоставил нашей ESP.
Вариантов много:
Пока проект в стадии настройки, можно смотреть ИП по USB.
Можно через терминал винды пропинговать сеть.
Если есть фаервол, (например в антивирусе НОД секюрити) можно посмотреть локальное окружение.
Можно на ESP настроить точку доступа, которая будет выдавать ИП, но в данный момент это ни к чему.
Есть разные утилиты, которые могут это делать.
Но самый актуальный вариант, зайти в настройки роутера, и в разделе DHCP сервера, по мак адресу ESP посмотреть ИП.
Заодно где то там же, привязать ИП к этому мак адресу, что бы роутер его больше не менял.
Ставим на плату блок webserverpage. Заходим в настройки. Добавляем устройство ESP.
Во вкладке адреса страницы добавляем страницу, ставим птичку Головная страница (хост), готово.
Мы создали хостовую пустую страницу, которая при обращении к ESP будет ее передавать, и открывать в браузере клиента.
Теперь нам надо выяснить, что уже сделал FLProg в этой странице и что нужно делать нам.
Смотреть и настраивать проект будем с помощью браузера.
Которые есть во всех современных гаджетах(я привык к Мазиле, примеры и настройки будут на ней).
Заливаем проект. Заходим мазилой по адресу ESP. Видим пустую страницу.
ПКМ выбираем исходный код страницы(или сочетание CTRL+U). Откроется новая страница с 3 строками кода.
<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN>
<META content=text/html; charset=utf-8 http-equiv=Content-Type>
<html></body></html>
Этот код уже сформировал FLProg, и это будет в каждой странице созданной этим блоком.
Чтобы определить, что нам надо сюда добавить, придется обратиться к помощи гугла.
Рассматривать сам код не буду. Информации на русском языке, очень много.
Сложностей в освоении HTML, CSS, JS нет. Начал уделять этому внимания с этого года.
За это время не почувствовал себя знатоком веба, еще путаюсь в терминологии, часто захожу в тупик,
но зато понял где, и что конкретно надо искать, и как это использовать в своих проектах.
Единственно в этом коде хотел обратить внимание, на закрытый тег </body>,
т.е в своих страницах, нам надо только открывать, этот тег, а FLProg закроет его сам.
Хотя смотрю браузер переваривает это, и сам дополняет теги.
Но чтобы не ловить в дальнейшем грабли, будем делать как пишут в умных книгах )).
Структура страницы будет состоять из:
Стилей (CSS)-в которых будем задавать дизайн всей страницы в целом,
и каждого элемента или группы элементов в отдельности.
Код самой страницы (HTML) -тексты, кнопки, графика, и т д.
Ява скриптов (JS)-подпрограмм обслуживающих работу динамичных данных.
Начнем с обычной страницы приветствия.
Заполним нашу страницу кодом. Сразу будем комментировать, что бы потом легче ориентироваться.
<head>
<title>Client</title>
<!-- ===== НАШИ СТИЛИ CSS ===== -->
<style>
/* для всей страницы */
body{color:#6b1a1a;background-color:#efdece80;font-family:'Times New Roman',Times,serif;}
</style>
</head>
<!-- ===== ТЕЛО СТРАНИЦЫ HTML ===== -->
<body>
<p>Привет FLProg!!!</p>
<!-- ===== НАШИ СКРИПТЫ JS ===== -->
<script>
</script>
Здесь есть один нюанс.
Код в скриптах и CSS лучше писать в одну строку. Все пробелы (кроме жизненно необходимых) сразу удалять.
Иначе некоторые моменты FLProg воспринимает по своему, и код становится не рабочим.
Конечно, код при этом становится не очень читабельным, зато экономим на размере пакета, и свое время на поиски граблей ))
Заливаем проект в ESP. Заходим с браузера, и изучаем как это все выглядит, и работает.
Видео, чтобы было понятно о чем речь, когда пишу "изучать и настраивать в браузере"
Соберем что то динамичное. Возьмем встроенные часы ESP.
Время будем синхронизировать по NTP.
содержаниеПоказать
Собираем на отдельной плате схему из блоков NTP сервер и RTC (проект будет в низу).
Делаем необходимые настройки, и выводим время текстовой строкой.
Представим как это должно работать.
У нас есть страница хост. Это шаблон страницы.
Можно сказать фотография собранная из пазлов (кусочков). Цифры часов это набор пазлов в этой фото.
На данный момент чтобы сменить цифру секунд, нам надо каждую секунду обновлять страницу.
Т.е запрашивать у сервера новую фотографию, на которой будет запечатлена другая секунда.
Обновлять так часто страницу не удачное решение.
Во-первых при обновлении страницы в браузере, происходит перезагрузка части служб,
обновление всех привязок (кеш, url, стили, скрипты, итд). Это очень грузит систему.
Плюс сама страница может содержать много графики, инфы, т.е. много весить.
Гонять часто такие большие пакеты, повесят сеть.
Да и выглядит это дёрганно, с залипанием, глаза очень быстро пошлют вас ))
Мы пойдем другим путем. Создадим еще одну страницу, в теле которой будет только число времени. Назовем ее (server_info).
А в хостовой странице мы напишем программку (скрипт), которая каждую секунду, будет обращаться к странице (server_info),
и ее содержимое(число времени), будет подставлять в ячейки пазлов времени.
В результате мы по запросу клиента, с ESP, один раз загружаем хостовую страницу.
После чего эта страница, ежесекундным запросом вытягивает всего лишь байты времени с сервера.
По хорошему здесь надо написать еще один скрипт (генератор с счетчиком),
чтобы он секунды обновлял внутри браузера, и лишь каждую минуту обновлял с сервера.
Все таки каждую секунду для ESP будет тяжко, если по мимо сети, она будет загружена еще какой то тяжелой работой.
Но у меня цель, выяснить, на сколько ее можно загрузить частыми запросами, по этому оставим так.
В хостовой странице создадим стиль для наших часов. Сделаем их по середине, и огромными ))
В результате код хостовой страницы будет выглядеть так:
Добавим в проект 3 кнопки.
Будем управлять встроенным светодиодом ESP.
содержаниеПоказать
При отключенных кнопках светодиод молчит.
При вкл 1кнопки =1моргание, при 2 =2, при 3 =3, приоритет по старшинству,
т.е если нажата 3 кнопка состояние предыдущих не важно.
Добавим еще одну плату для кнопок. На ней поставим Web Page блок с тремя страницами.
Для каждой кнопки будет своя страница (с булеан выходом при обращении к странице).
Т.к команды от кнопок, на стороне ESP, работают при обращении к странице, будем использовать HEAD запрос (запрос без ответа).
Для этого напишем в главной странице клиента скрипт, выполняющий HEAD запрос кнопки на сервер.
Чтобы знать реальное состояние кнопок на сервере, будем обновлять их состояние.
Допишем в скрипт «АВТО ОБНОВЛЕНИЕ» запрос на состояние кнопок, а также изменение их цвета, в зависимости от состояния.
В главной странице клиента допишем в стилях внешний вид и расположение кнопок.
Ну и конечно в теле html допишем сами кнопки.
Ответ всех данных с сервера будем отправлять одним пакетом, в виде массива текстовых слов (на русском языке для лучшего понимания). Для этого в первой плате добавим состояние кнопок, и времени, в виде текстовой строки через запятые.
В браузере можем посмотреть пакет принимаемых данных
По аналогии Авторского веб интерфейса добавил поля header и footer.
Код в главной странице клиента теперь выглядит так:
<head><title>Client</title>
<!-- ===== НАШИ СТИЛИ CSS ===== --><style>
/* для всей страницы */
body{color:#6b1a1a;background-color:#efdece;font-family:'Times New Roman',Times,serif;}
/* верх страницы */
.header{background:#60ECEC;text-align:center;font-weight:600;font-size:200%;}
/* время на странице */
.time{line-height:1.0;text-align:center;font-weight:600;font-size:370%;}
/* для кнопок */
.button{margin:auto;display:block;font-size:25px;line-height:1.6;letter-spacing:0.88px;font-weight:600;padding:5px;border-radius:8px;border:3px solid green;width:200px;box-shadow:0 0 0 60px rgba(0,0,0,0)inset,2px 2px 8px #a990c3;}
.button:active{top:2px;left:2px;box-shadow:0 0 0 60px rgba(0,0,0,.05)inset;}
/* низ страницы */
.footer{background:#60ECEC;text-align:center;font-weight:350;font-size:100%;}
</style>
</head>
<!-- ===== ТЕЛО СТРАНИЦЫ HTML ===== -->
<body>
<!-- ВЕРХ -->
<h1 class="header">Сделано в FLProg</h1>
<!-- ВРЕМЯ -->
<p class="time" id="time">**:**:**</p>
<!-- КНОПКА 1 -->
<p><button type="button" class="button" id="kn1" onclick="sendKn('sendkn1')">****** *\n***</button></p>
<!-- КНОПКА 2 -->
<p><button type="button" class="button" id="kn2" onclick="sendKn('sendkn2')">****** *\n***</button></p>
<!-- КНОПКА 3 -->
<p><button type="button" class="button" id="kn3" onclick="sendKn('sendkn3')">****** *\n***</button></p>
<!-- НИЗ -->
<p class="footer">=== rw6cm 2020 ===</p>
<!-- ===== НАШИ СКРИПТЫ JS ===== -->
<script></script>
<!-- КОМАНДА С КНОПКИ НА СЕРВЕР -->
<script>
function sendKn(url){var xhttp=new XMLHttpRequest();xhttp.open("HEAD",url,true);xhttp.send();}
</script>
<!-- АВТО ОБНОВЛЕНИЕ ВЫБРАННЫХ ДАННЫХ -->
<script>
function sendRequest(){
setInterval(function(){loadDoc();},1000);function loadDoc(){var xhttp=new XMLHttpRequest();xhttp.onreadystatechange=function(){if(this.readyState==4&&this.status==200){var arr=xhttp.responseText.split(",");
document.getElementById("time").innerHTML=arr[0];
var k1=document.getElementById("kn1");
k1.innerHTML=arr[1];if(k1.innerHTML==="КНОПКА 1 ВКЛ"){k1.style.backgroundColor=('#7bf27b');}else{k1.style.backgroundColor=('#d9ddf7');}
var k2=document.getElementById("kn2");
k2.innerHTML=arr[2];if(k2.innerHTML==="КНОПКА 2 ВКЛ"){k2.style.backgroundColor=('#7bf27b');}else{k2.style.backgroundColor=('#d9ddf7');}
var k3=document.getElementById("kn3");
k3.innerHTML=arr[3];if(k3.innerHTML==="КНОПКА 3 ВКЛ"){k3.style.backgroundColor=('#7bf27b');}else{k3.style.backgroundColor=('#d9ddf7');}}};xhttp.open("GET","server_info",true);xhttp.send();}}
sendRequest();
</script>
Наша страница в браузере выглядит так:
В связи с тем что, при усложнении хостовой страницы, появлялся не понятный баг.
А именно: при обращении к странице с данными, вместо нее в ответе возвращается хостовая станица (Выглядит это как наложение сдвинутой страницы без данных на ней. И хотя это происходит не часто, но неприятно. Решил не использовать страницу хост). По этому в главной странице клиента адрес станицы теперь client. Заходим на ESP теперь по адресу “IP/client”
Сборка пакета Json рассматривается в соседней ветке
Здесь рассмотрим какие нюансы могут возникнуть при обмене данными в json формате.
содержаниеПоказать
Для примера возьмем абстрактный проект. Пусть это будет автомат обработки растений.
Нам нужно передавать исторические данные работы оборудования, расход химикатов, и при каких метео условиях была обработка.
По сути нам надо три списка выдаваемые по запросу.Пакет данных соберем в json строке средствами FLProg.
Прием передачу организуем с помощью блока веб сервер.
схема проекта:
Но тут нас поджидает разочарование (( ява скрипт не хочет парсить строку json.
Срока валидная все вроде правильно но …
Ошибка прям в начале строки.
Uncaught SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data.
Что может ему не нравится? строка начинается с фигурной скобки как положено.
Значит что то есть до нее, но не видим. Решил посмотреть под другим углом ))
Выяснилось ,что перед фигурными есть еще кавычки ,
Это понятно, мы передаем сроку с Си языка. А JS не любит двойные кавычки.
Если внутри двойные значит снаружи нужны одинарные. Вечная проблема с этими кавычками,
Пришлось обрезать с концов по фигурные скобки, и вставить одинарные кавычки. и !
весьма интересная тема, надеюсь она получит развитие.
посмотрел совместимость с библиотекой json на примере погодного информера.
Конфликтов нет, и это в чем то отличная альтернатива ESPUI
Однозначно с плагином esp8266fs.jar было бы огонь.
ВЕБ сервер в программе FLProg
Добавлено: 18.03.2021{, 03:07}
rw6cm
Пример информер погоды.
Разберем JSON строку с сайта погоды.
Возьмем прогноз погоды на неделю, и выберем с него почасовой прогноз на два дня.
В примере рассматривается вариант передачи данных в JSON виде,
с esp8266 (веб сервер) на ESP32 (веб клиент).
СпойлерПоказать
Веб сервер аналогичен проекту поста 8 , и использует блок веб сервер флп.
Веб клиент аналогичен посту выше распарсить JSON и использует ПБ веб клиент. (т.к. клиент флп для этого не подошел.)
Веб сервер esp8266 формирует данные в Json, и выдает их в теле веб страницы.
Веб клиент ESP32 берет данные с страницы, парсит, и выдает в нужном виде в UART.
п/с при подключении UART возможно понадобится ресетнуть есп32
- есть ли пример как читать значения например с веб страниц типа <input type="range"> и транслировать их на контроллер в переменную.
из возможностей стандартного блока не не нашел ничего кроме передачи булена
- так же прошу помощи как минимальным кодом обновлять локальные динамические данные на странице. (без CCS и прочих стилей только минимальный набор скрипта)
как это сделано с часами в одном из примеров.
<!-- АВТО ОБНОВЛЕНИЕ ВЫБРАННЫХ ДАННЫХ -->
<input type="text" value="Sec" id="gz" class="" />
<script>
var relay = document.getElementById("gz");
var relay_status = 0;
function relay_state() {
var request = new XMLHttpRequest();
request.open('GET','/Sec',true);
request.onload = function() {
if (request.readyState == 4 && request.status == 200) {
var response = request.responseText;
relay_status = Number.parseInt(response);
if (relay_status == 0)
relay.classList.add('off');
else
relay.classList.add('on');
}
}
request.send();
}
значение переменной с контроллера "Sec" отображается на странице, но оно не обновляется.
полагаю request.open('GET','/Sec',true); тут нужно что то иное прописывать. может еще где то.
- есть ли пример как читать значения например с веб страниц типа <input type="range"> и транслировать их на контроллер в переменную.
из возможностей стандартного блока не не нашел ничего кроме передачи булена
- так же прошу помощи как минимальным кодом обновлять локальные динамические данные на странице. (без CCS и прочих стилей только минимальный набор скрипта)
как это сделано с часами в одном из примеров.
<!-- АВТО ОБНОВЛЕНИЕ ВЫБРАННЫХ ДАННЫХ -->
<input type="text" value="Sec" id="gz" class="" />
<script>
var relay = document.getElementById("gz");
var relay_status = 0;
function relay_state() {
var request = new XMLHttpRequest();
request.open('GET','/Sec',true);
request.onload = function() {
if (request.readyState == 4 && request.status == 200) {
var response = request.responseText;
relay_status = Number.parseInt(response);
if (relay_status == 0)
relay.classList.add('off');
else
relay.classList.add('on');
}
}
request.send();
}
значение переменной с контроллера "Sec" отображается на странице, но оно не обновляется.
полагаю request.open('GET','/Sec',true); тут нужно что то иное прописывать. может еще где то.
Спасибо
Здравствуйте Alex
В блоке "Веб сервер" нет возможности, "по умолчанию", транслировать значения на контроллер в переменную, кроме передачи булена.
Сам долго мучался, пока не разобрался в коде
Но есть метод где нужно будет вручную вставлять в скетч строки кода.
<script>
function sendKn(url){
var xhttp=new XMLHttpRequest();
var body = "InputText="+document.getElementById("input_text1").value+"&InputNumber="+document.getElementById("input_number1").value;
console.log(body);
xhttp.open("HEAD",url+"?"+body,true);
xhttp.send();}
</script>
2. В коде "int _parseWebServerReqest(String reqestAddres)" дописываем (где комментарии)
int _parseWebServerReqest(String reqestAddres)
{
String reqestAddresCopy=reqestAddres;//Копируем переменную reqestAddres
int index;
int result=0;
index=reqestAddres.indexOf("/");
reqestAddres =reqestAddres.substring(index+1);
if (reqestAddres.indexOf("?")==-1){//Если в строке не находим "?"
index=reqestAddres.indexOf(" ");}//Идем до конца стори
else{index=reqestAddres.indexOf("?");}//Если нашли "?", то заканчиваес строку на ?
reqestAddres =reqestAddres.substring(0, index);
if (reqestAddres=="")
{
result= 1;
}
if (reqestAddres=="sendsave")
{
reqestAddres =reqestAddresCopy;//Восстанавливаем начальное значение переменной
index=reqestAddres.indexOf("?");//Ищем индекс "?"
reqestAddres =reqestAddres.substring(index+1);//Извлекаем строку начиная с "?"
index=reqestAddres.indexOf(" ");//Ищем индекс конца строки
reqestAddres =reqestAddres.substring(0, index);//Извлекаем строку с ? до конца
_gtv10 =reqestAddres;//Записываем строку в переменную
result= 1;
}
В итоге, в проекте, в переменной "TEXT" получаем строку "InputText=(слово введенное в поле Текст)&InputNumber=(цифра введенная в поле Число)"
Пример: InputText=on&InputNumber=1.
int _parseWebServerReqest(String reqestAddres)
{
String index2=reqestAddres;
int index;
int result=0;
index=reqestAddres.indexOf("/");
reqestAddres =reqestAddres.substring(index+1);
if (reqestAddres.indexOf("?")==-1){
index=reqestAddres.indexOf(" ");}
else{index=reqestAddres.indexOf("?");}
reqestAddres =reqestAddres.substring(0, index);
if (reqestAddres=="")
{
result= 1;
}
if (reqestAddres=="sendsave")
{
reqestAddres=index2;
index=reqestAddres.indexOf("?");
reqestAddres =reqestAddres.substring(index+1);
index=reqestAddres.indexOf(" ");
reqestAddres =reqestAddres.substring(0, index);
_gtv1 =reqestAddres;
result= 1;
}
return result;
}
В Поле "Текст" - on
В Поле "Число" - время свечение светодиода.
ВЕБ сервер в программе FLProg
Добавлено: 25.09.2021{, 23:39}
Qwert855
Спасибо, попробую разобраться.
я смотрел в сторону JSON, ваш пример думаю чем то схож по принципу.
В голове концепт - собирать данные с одной страницы, скидывать на другую и там их парсить.
Отправлено спустя 11 минут 15 секунд:
Вопрос к уважаемому автору темы- предположим что есть некий веб сервер (от флпрог или espui) который виден в веб браузере, можно ли создать на есп веб клиента позволяющий считывать из сервера предназначенные только для него данные . То есть в сервере есть N (значений- int или float регистров ) поступающих по UART) , предназначенных для N клиентов и каждый из этих клиентов(веб) имеет доступ только к своим данным????
В итоге получим возможность в браузере ПК(мобилки) видеть все данные (для всех клиентов) ,но каждый из веб клиентов (на есп) будет получать (отдавать) только свои данные .
ВЕБ сервер в программе FLProg
Добавлено: 22.04.2022{, 08:44}
Phazz
Rovki, это и сейчас можно в 751 вообще без проблем. Теперь там появилось полноценное api. На запрос придет json со всеми параметрами что есть на странице. А дальше хоть на страницу выводите, хоть в базу данных пишите
Rovki, это и сейчас можно в 751 вообще без проблем. Теперь там появилось полноценное api. На запрос придет json со всеми параметрами что есть на странице. А дальше хоть на страницу выводите, хоть в базу данных пишите
Проблем не будет когда блоки появятся Интересно сколько web клиентов один веб сервер потянет одновременно при не большой интенсивности обмена данными?
ВЕБ сервер в программе FLProg
Добавлено: 23.04.2022{, 03:50}
support
Сейчас работаю над полноценным Вэб АПИ там будет и клиент и сервер. Постараюсь за недели 2-3 сделать.
ВЕБ сервер в программе FLProg
Добавлено: 23.04.2022{, 10:17}
Di123
support, а почему не хотите сделать на асинхроном библиотеке
а то что вы хотите уже пройденый вариант тормозной