http сервер на макросах своими руками (MT серия)

Модераторы: kiv, 8bit, VanMo

http сервер на макросах своими руками (MT серия)

Сообщение 8bit » 09 июн 2022, 16:16

Отправку http сообщений уже рассматривали тут.

А можно ли реализовать http сервер НА панели, чтобы она отвечала на запросы обычного веб-браузера ?

Оставим за рамками вопросы применимости. Каждый сам на него может ответить.

Рассмотрим саму возможность реализовать свой собственный web сервер на самых простых моделях панелей Weintek.

Для этого нам понадобятся:
1) панель MT серии (в примере использована MT8071iE)
1) устройство Free Protocol Server (Ethernet)
2) EasyBuilder Pro


Условимся, что:
1) наш web сервер будет на все запросы (парсить ничего не будем, на макросах это весьма трудоёмко)
2) отвечать одинаково, жестко заданным ответом (мы будем возвращать значения четырех локальных регистров панели LB-1, LB2, LW-1, LW-2)
3) автоматическое обновление данных на html странице реализуем через тег <meta>
4) общий объеём всех переменных в одном макросе не мбодет быть более 4 килобайт.

Реализация:
1) создадим проект для нужной модели
2) в Системных настройках проекта добавим устройство Free Protocol Server (Ethernet)
3) TCP порт для устройства Free Protocol Server (Ethernet) укажем отличный от 80 (даже на MT серии этот порт оказался занят системой), в нашем примере это 8080
4) создадим макрос, дадим ему имя server, поставим флажок "Период вып." и укажем 1*100 ms
5) в тело макроса добавим следующий код:

Код: Выделить всё

macro_command main()

unsigned char http_request[400] = {0} // http запрос GET, POST  и т.д.
   FILL(http_request[0], 0x0, 400)

unsigned short http_request_len = 0 // длина http запроса

unsigned short read_count = 100

unsigned short input_result = 0
unsigned short requests_count = 0

unsigned short wait_time = 50 // время ожидания завершения запроса в OUTPORT

unsigned char http_header[300] // http заголовок
   FILL(http_header[0], 0x0, 300)

unsigned char http_status[17] = "HTTP/1.1 200 OK" // http заголовок: статус
unsigned char http_date[13] = "Date: Monday"
unsigned char http_srv[16] = "Server: Weintek"
unsigned char http_len[30] = "Content-Length: "
unsigned char http_type[50]= "Content-Type: text/html; charset=windows-1251"

unsigned char html_start[200]= "<!DOCTYPE html><html><head><title>Weintek HMI</title><link rel=\"icon\" type=\"image/png\" href=\"data:image/png;base64,iVBORw0KGgo=\"><meta http-equiv=\"refresh\" content=\"1\"></head><body>"
//unsigned char html_start[200]= "<!DOCTYPE html><meta http-equiv=\"refresh\" content=\"1\"><body>"
unsigned char html_end[14]= "</body></html>"
unsigned char html_body[200] // тело страницы , всё что между <body>...</body>
   FILL(html_body[0], 0x0, 1000)
unsigned char html_page[500] // html страницы
   FILL(html_page[0], 0x0, 500)

unsigned char http_response[800] // тело ответа = http_заголовок + html_страница
   FILL(http_response[0], 0x0, 8000)

unsigned int http_response_len = 0       // кол-во символов в ответе сервера - числом
unsigned char http_response_len_txt[5]    //  кол-во символов в ответе сервера - текстом
   FILL(http_response_len_txt[0], 0x0, 5)

unsigned int html_len = 0       // кол-во символов в html странице - числом
unsigned char html_len_txt[5]   // кол-во символов в html странице - текстом
   FILL(html_len_txt[0], 0x0, 5)

//unsigned char text6_doc[200]= "<!DOCTYPE html><head><link rel=\"icon\" type=\"image/png\" href=\"data:image/png;base64,iVBORw0KGgo=\"></head><html>HMI works!</html>"
//unsigned char text6[100]= "<!DOCTYPE html><html><head><link rel=\"icon\" href=\"data:,\"></head><body>HMI works !</body></html>"
//unsigned char no_favicon[50] = "<link rel=\"icon\" href=\"data:;base64,=\">"
//unsigned char text7[80]= "<!DOCTYPE html><html><head><link rel=\"icon\" href=\"data:,\"></head></html>"

unsigned char new_line[2] = {0x0D, 0x0A} // ASCII коды перехода на новую строку




// получаем http запрос
INPORT2(http_request[0], "Free Protocol Server (Ethernet)", http_request_len, wait_time)

// если запрос не 0 длины, то формируем ответ
if http_request_len > 0 then

   // объявляем переменные панели, которые надо мониторить
          short   lw_1      // размер в регистр
   unsigned short    lw_2      // размер в регистр
           bool   lb_1, lb_2   // размером в бит

   char lw_1_txt[6] = {0,0,0,0,0,0}    // для текстового представления числа
   char lw_2_txt[6] = {0,0,0,0,0,0}    // для текстового представления числа
   char lb_1_txt[2] = {0,0}          // для текстового представления числа
   char lb_2_txt[2] = {0,0}         // для текстового представления числа
   
   char thml_br[5] = "<br>"   // html переход на новую строку
   
   // считываем значение тегов
   GetData(lw_1, "Local HMI", LW, 1, 1)
   GetData(lw_2, "Local HMI", LW, 2, 1)
   
   GetData(lb_1, "Local HMI", LB, 1, 1)
   GetData(lb_2, "Local HMI", LB, 2, 1)

   // преобразуем числовые значение тегов в текст
   StringBin2DecAsc(lw_1, lw_1_txt[0])
   StringBin2DecAsc(lw_2, lw_2_txt[0])
   StringBin2DecAsc(lb_1, lb_1_txt[0])
   StringBin2DecAsc(lb_2, lb_2_txt[0])
   
   // формируем блок <body>
   StringCopy("LB-1: ", html_body[0])
   StringCat(lb_1_txt[0], html_body[0])
   StringCat("<br>", html_body[0])
      //StringCat(new_line[0], html_body[0])
   
   StringCat("LB-2: ", html_body[0])
   StringCat(lb_2_txt[0], html_body[0])
   StringCat("<br>", html_body[0])
      //StringCat(new_line[0], html_body[0])

   StringCat("LW-1: ", html_body[0])
   StringCat(lw_1_txt[0], html_body[0])
   StringCat("<br>", html_body[0])
      //StringCat(new_line[0], html_body[0])   

   StringCat("LW-2: ", html_body[0])
   StringCat(lw_2_txt[0], html_body[0])
   StringCat("<br>", html_body[0])
      //StringCat(new_line[0], html_body[0])
      
   // формируем html страницу
   StringCat(html_start[0], html_page[0])
   StringCat(html_body[0], html_page[0]) // приклеиваем к началу html документа блок <body>
   StringCat(html_end[0], html_page[0])
   
   // считаем размер html страницы
   unsigned int html_page_len = 0
   char html_page_len_txt[10]
   FILL(html_page_len_txt[0], 0x0, 8)
   
   html_page_len = StringLength(html_page[0])
   StringBin2DecAsc(html_page_len, html_page_len_txt[0]) // преобразуем длину html страницы в текст
   
   // формируем http заголовок   
   StringCat(http_status[0], http_header[0])
         StringCat(new_line[0], http_header[0]) // добавляем символы перехода на новую строку
   StringCat(http_date[0], http_header[0])
         StringCat(new_line[0], http_header[0])
   StringCat(http_srv[0], http_header[0])
         StringCat(new_line[0], http_header[0])
   StringCat(http_type[0], http_header[0])
         StringCat(new_line[0], http_header[0])
   
   StringCat(html_page_len_txt[0], http_len[0])      
   StringCat(http_len[0], http_header[0])
         StringCat(new_line[0], http_header[0])
         StringCat(new_line[0], http_header[0])
         
   // формируем http ответ: склеиваем заголовк с html страницей
   StringCat(http_header[0], http_response[0])
   StringCat(html_page[0], http_response[0])
   
   // определяем размер ответа
   http_response_len = StringLength(http_response[0])
   
   // отправляем http ответ в порт
   OUTPORT(http_response[0], "Free Protocol Server (Ethernet)", http_response_len)

   // диагностическая информация по запросам-ответам
   http_request_len = StringLength(http_request[0])
   SetData(http_request_len, "Local HMI", LW, 999, 1) // выводим кол-во символов в запросе   
   SetData(http_request[0], "Local HMI", LW, 300, http_request_len) // выводим текст запроса
   

   SetData(http_response_len, "Local HMI", LW, 340, 1) // выводим кол-во символов в ответе   
   SetData(http_response[0], "Local HMI", LW, 500, http_response_len) // выводим текст ответа


      // счетчик http запросов
   GetData(requests_count, "Local HMI", LW, 888, 1) // считываем кол-во запросов
   requests_count = requests_count + 1
   SetData(requests_count, "Local HMI", LW, 888, 1) // выводим кол-во запросов
   


end if


end macro_command



В строке 25 макроса мы оформили html страницу по всем правилам, но если вам надо покорочи и понагляднее, то закомментируйте 25 строку и раскомментируйте 26.

В конце макроса мы добавили вывод некоторой отладочной информации (текст запроса, кол-во символов в запросе и т.п.). Когда макроса отлажен всё это можно не выводить.

http server in macro MT series 2.png
http server in macro MT series 2.png (72.87 КБ) Просмотров: 2297



5) Загружаем проект в панели и в браузере обращаемся к ней по IP адресу и порту 8080

http server in macro MT series.png
http server in macro MT series.png (73.86 КБ) Просмотров: 2297


Естественно такое же можно реализовать и в cMT/cMT_X серии.

http server in macro cMT series.png
http server in macro cMT series.png (90.36 КБ) Просмотров: 2297
Вложения
http server in macro.7z
Проект для MT8071iE
(4.35 МБ) Скачиваний: 245
Хороший вопрос содержит половину ответа - A good question contains half the answer
Аватара пользователя
8bit
 
Сообщения: 1108
Зарегистрирован: 20 апр 2020, 19:07

Вернуться в Как это сделать ? ( How to...?)

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

cron