• Обратная связь
  • Карта сайта
  • Отзыв
  • Комментарии
  • Форум
discord
Технические заметки
  • Главная
  • Лекции
  • Практикум
  • Обзоры
  • Сравнение
  • Нормы
  • События
  • Вход
ГлавнаяMaxSite CMSArduinoМониторинг
Плагин My_ESP8266 для MaxSiteCMS.
Болид или Рубеж: причины негативного отношения к Рубеж

Отправка данных из ESP8266WiFi на сервер с CMS MaxSite

5 февраля 2019 г.Просмотров: 4665Комментарии: 0
MaxSite CMSArduinoМониторингArduinoESP8266MaxSiteMy_ESP8266WiFiАвтоматикаИнтернет ВещейМониторингОблачный Сервис

Относительно легко получилось сделать из платы ESP8266 WiFi WEB-сервер.

Попробуем теперь сделать WEB-клиента, периодически отправляющего данные о состоянии чего-нибудь на сервер. В качестве сервера будем использовать MaxSiteCMS.

Формат данных для отправки на сервер.

Для начала определимся - что и как будем отправлять на сервер.

Данные в запросе POST будут представлены в таком виде:

secret=0000&name=ESP_8266WiFi&temp=23.00&hum=63.00&gas=478&mac=F485452DE6B4&ram=960&rssi=-79

Обязательным будет наличие полей: secret и name - ключ доступа и имя платы.

Необязательные поля: ram, mac, date, rssi.

Остальные поля будут восприниматься как показания сенсоров 'sensor'=>'value'.

В полученном с сервера результате будет JSON массив с кодом ошибки или количеством добавленных сигналов.

Обработка AJAX в CMS MaxSite.

Для того чтобы POST-запрос от платы ESP8266 WiFi попал на обработку в плагин my_esp8266 стоит обратить внимание на то, как обрабатывается AJAX в CMS MaxSite.

Обработка AJAX запроса происходит в файле \application\views\ajax.php, в котором проверяются несколько условий безопасности, которым должно соответствовать обращение к MaxSite CMS. Если изучить этот файл, то можно увидеть проверки:

1. if (!isset($_SERVER['HTTP_X_REQUESTED_WITH'])).
2. mso_checkreferer()- функция, которая содержит проверки: if (!isset($_SERVER['HTTP_REFERER']))
и if ($p != $_SERVER['HTTP_HOST']).
3. $fn = $MSO->config['base_dir'] . base64_decode($MSO->data['uri_segment'][2]) - имя файла, принимающего POST и путь к нему должно быть закодировано соответствующим образом.
4. if (strpos($fn, '-ajax.php') !== false ) - имя файла должно заканчиваться на '-ajax.php'.

Все это нужно учесть и видно, что необходимый заголовок HTTP-запроса получается немаленький.

Плагин для MaxSite CMS.

Сервер должен уметь принять данные и что-то с ними сделать.

Напишем плагин my_esp8266 для MaxSiteCMS, который принимает данные. Воспользуемся встроенной в CMS возможностью принимать AJAX-запросы.

Плагин будет принимать данные и заносить их в базу данных.

Напрашиваются три таблицы:

esp_shields - таблица устройств (плат);
esp_sensors - таблица сенсоров (датчиков);
esp_signals - таблица сигналов (значений сенсора платы в момент времени).

Если пришел сигнал от неизвестного устройства - будет добавлено устройство в таблицу устройств с идентификатором mac или name. Если POST содержит значения неизвестного сенсора - будет добавлен сенсор с идентефикатором по устройству и имени сенсора.

На странице "Логи" админ-панели плагина выведем отладочные инструменты:

1. Строка из которой можно копировать кодированную ссылку на файл-обработчик и вставлять в запрос.
2. Кнопка для отправки тестового запроса для проверки работы.
3. Информация с последними параметрами POST-запроса, который попал в файл-обработчик.

Элементарные настройки функционирования:

Подробнее о плагине: Плагин my_esp8266 для MaxSiteCMS.

Отправка POST-запроса с ESP8266WiFi на сервер.

Для этого эксперимента соединим плату Arduino UNO R3 и ESP8266 ESP-12 ESP-12E UART Wi-Fi, как делали в эксперименте с WEB-сервером.

Воспользуемся библиотекой Arduino WiFi library for ESP8266 modules.

Имеется пример, в котором происходит запрос к серверу.

Вероятно, мы должны составить что-то вроде этого (заменив esp8266.mysite.ru на свой домен):

jsonString = "secret=0000&name=ESP_8266WiFi&temp=" + String(temp) + "&hum=" + String(hum) + "&gas=" +  tring(gas) + "&mac=" + String(mac)+ "&ram=" + String(freeRam()) + "&rssi=" + String(WiFi.RSSI());
client.println(F("POST /ajax/cGx1Z2lucy9teV********************WpheC5waHA= HTTP/1.1"));
  client.println(F("Host: esp8266.mysite.ru:80"));
  client.println(F("User-Agent: ESP8266WiFi")); 
  client.println(F("Accept: application/xml")); 
  client.println(F("Content-Type: application/x-www-form-urlencoded"));  
  client.println(F("X-Requested-With: XMLHttpRequest"));  
  client.println(F("Referer: http://esp8266.mysite.ru"));
  client.println(F("Connection: close"));
  client.println("Content-Length: " + String(jsonString.length()));
  client.println();
  client.println(jsonString);
  client.println();
  client.println();

Так и не удалось добиться, чтобы скетч, содержащий этот код, работал.

Для того чтобы разобраться что к чему соединим платы так, чтобы видеть что происходит, выводя информацию при помощи Serial.println() в консоль Arduino IDE.

Эксперименты показали, что передать данные удается только когда весь заголовок передается за один вызов функции client.println().

Впервые заработал такой скетч.

Показать скетч

#include "WiFiEsp.h"    // Библиотека для работы с платой
#include <dht11.h>      // Добавляем библиотеку DHT11
dht11 DHT;              // Объявление переменной класса dht11
#define DHT11_PIN 4     // Датчик DHT11 подключен к цифровому пину номер 4
// эмулируем серийный порт на pin 6/7 чтобы видеть обмен данными
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(6, 7); // RX, TX
#endif
const char ssid[] = "Keenetic-0138";   // SSID
const char pass[] = "********";        // пароль
int status = WL_IDLE_STATUS;     // статус Wifi-радиомодуля
String jsonString; // данные
String PostHeader; // заголовок
const char server[] = "esp8266.mysite.ru";
unsigned long lastConnectionTime = 0;   
unsigned long lastInfoTime = 0;
const unsigned long postingInterval = 1200000; // 20 минут 
const unsigned long infoInterval = 60000;      // 1 минута
// Инициализация объекта wi-fi клиент
WiFiEspClient client;
void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);  
  WiFi.init(&Serial1);
  if (WiFi.status() == WL_NO_SHIELD) {
     Serial.println("No WiFi shield");
    while (true);
  }
  while ( status != WL_CONNECTED) {
    Serial.print("Connectid to: ");
    Serial.println(ssid);    
    status = WiFi.begin(ssid, pass);
  }
  httpRequest();
}
void loop()
{
 if (millis() - lastConnectionTime > postingInterval) { httpRequest(); }
 if (millis() - lastInfoTime > infoInterval) 
 {
    lastInfoTime = millis();
 }
}
void httpRequest()
{
Serial.println();
client.stop();
if (client.connect(server, 80)) {
  Serial.println("Connection to server...");
  jsonString = "secret=0000&name=ESP_8266WiFi&temp=28&hum=45&gas=32";
  Serial.println(String(jsonString.length()));
  client.println(F("POST /ajax/cGx1Z2lucy9t**********************pheC5waHA= HTTP/1.1\r\nHost: esp8266.mysite.ru:80\r\nX-Requested-With: XMLHttpRequest\r\nReferer: http://esp8266.mysite.ru\r\nConnection: close\r\nContent-Length: 51\r\n\r\nsecret=0000&name=ESP_8266WiFi&temp=28&hum=45&gas=32\r\n\r\n\r\n"));
 }
  while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }
  
   if (!client.connected()) {
    Serial.println();
    Serial.println("Disconnecting.");
    client.stop();
   }  
   lastConnectionTime = millis();
}

Размер передаваемых данных мы измерили вручную и сформировали константу. Такой скетч работает без проблем. Получаем ответ от сервера в виде JSON-массива, который формирует плагин. С ответом можно тоже что-то сделать - например зажечь светодиод, если нет ошибки.

Но нам же нужно передавать динамически изменяемые данные, поэтому мы не можем заранее знать результат работы функции jsonString.length().

Оказывается, что данные POST запроса можно передавать отдельным от передачи заголовка вызовом client.println().

Поэтому, мы сперва формируем переменную POST параметров, а затем формируем заголовок, включая эту длину.

Этот скетч работает уже с живыми данными.

Показать скетч

#include "WiFiEsp.h"    // Библиотека для работы с платой
#include <dht11.h>      // Добавляем библиотеку DHT11
dht11 DHT;              // Объявление переменной класса dht11
#define DHT11_PIN 4     // Датчик DHT11 подключен к цифровому пину номер 4
 // эмулируем серийный порт на pin 6/7 чтобы видеть обмен данными
#ifndef HAVE_HWSERIAL1
 #include "SoftwareSerial.h"
 SoftwareSerial Serial1(6, 7); // RX, TX
#endif
const int analogSignal = A3; //подключение аналогового сигналоьного пина
const int digitalSignal = 8; //подключение цифрового сигнального пина
float hum = 0; //переменная для хранения влажности
float temp = 0; //переменная для хранения температуры
char mac[18] = { 0 };
int chk; //переменная для хранения ошибки DHT
const char ssid[] = "Keenetic-0138";   // SSID
const char pass[] = "********";        // пароль
int status = WL_IDLE_STATUS;     // статус Wifi-радиомодуля
String jsonString; // данные
String PostHeader; // заголовок
const char server[] = "esp8266.mysite.ru";
unsigned long lastConnectionTime = 0;   
unsigned long lastInfoTime = 0;
     
const unsigned long postingInterval = 60000; // 1 минута 
const unsigned long infoInterval = 60000;      // 1 минута
// Инициализация объекта wi-fi клиент
WiFiEspClient client;
void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);  
  
  WiFi.init(&Serial1);
     
  if (WiFi.status() == WL_NO_SHIELD) {
     Serial.println("No WiFi shield");
    while (true);
  }
  while ( status != WL_CONNECTED) {
    Serial.print("Connectid to: ");
    Serial.println(ssid);    
    status = WiFi.begin(ssid, pass);
  }
  uint8_t macH[6];
  WiFi.macAddress(macH);
  sprintf(mac, "XXXXXX", macH[0], macH[1], macH[2], macH[3], macH[4], macH[5]);
  httpRequest();
}
void loop()
{
 if (millis() - lastConnectionTime > postingInterval) { httpRequest(); }
 if (millis() - lastInfoTime > infoInterval) 
 {
  // Чтобы не скучно было ждать
    long rssi = WiFi.RSSI();
    Serial.print("(RSSI): ");
    Serial.print(rssi);
    Serial.print("  FREE RAM: ");
    Serial.println(freeRam());
    lastInfoTime = millis();
 }
}
void httpRequest()
{
    chk = DHT.read(DHT11_PIN); 
    hum = DHT.humidity;
    temp = DHT.temperature;
    
    Serial.println();
    client.stop();
if (client.connect(server, 80)) {
 Serial.println("Connection to server...");
 
  jsonString = "secret=0000&name=ESP_8266WiFi&temp=" + String(temp) + "&hum=" + String(hum) + "&mac=" + String(mac)+ "&ram=" + String(freeRam()) + "&rssi=" + String(WiFi.RSSI());
  PostHeader = "POST /ajax/cGx1Z2lucy9t***********************heC5waHA= HTTP/1.1\r\n"; 
  PostHeader += "Host: esp8266.mysite.ru:80\r\n";
  PostHeader += "User-Agent: ESP8266WiFi\r\n"; 
  PostHeader += "Accept: application/xml\r\n";
  PostHeader += "Content-Type: application/x-www-form-urlencoded\r\n"; 
  PostHeader += "X-Requested-With: XMLHttpRequest\r\n";  
  PostHeader += "Referer: http://esp8266.mysite.ru\r\n";
  PostHeader += "Accept: application/xml\r\n";  
  PostHeader += "Connection: close\r\n";
  PostHeader += "Content-Length: " + String(jsonString.length()) + "\r\n";
  jsonString += "\r\n\r\n\r\n";
  
  Serial.println(PostHeader);
  Serial.println(jsonString);
 }
 else {
    Serial.println("Сonnection failed");
 }
  while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }
   if (!client.connected()) {
    Serial.println();
    Serial.println("Disconnecting.");
    client.stop();
   }  
   lastConnectionTime = millis();
}
int freeRam () {
 extern int __heap_start, *__brkval;  int v;  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); }

Это максимальный объем данных с которыми скетч еще работает.

Дальнейшее увеличение объема приводит к тому, что правильно передача проходит один раз, а затем происходит срыв работы.

Несмотря на то что в консоль выведен битый заголовок - на сервер отправляются правильные данные. У нас почему-то при выводе в один серийный порт попадают данные, которые крутятся в другом. Строка параметров же отправляется такая же искореженная, как и выводится в консоль.

Видно что совсем мало памяти остается.

Разбираться не будем потому что стабильной работы удается достичь, если не использовать эмуляцию серийного порта для наблюдения за работой - нам это и не нужно уже.

Снова помещаем одну плату на другую и добавляем светодиод, чтобы отображать процесс передачи запроса на сервер.

Заливаем такой скетч.

Показать скетч

#include "WiFiEsp.h"    // Библиотека для работы с платой
#include <dht11.h>      // Добавляем библиотеку DHT11
dht11 DHT;              // Объявление переменной класса dht11
#define DHT11_PIN 4     // Датчик DHT11 подключен к цифровому пину номер 4
const int analogSignal = A3; //подключение аналогового сигналоьного пина
const int digitalSignal = 8; //подключение цифрового сигнального пина
boolean noGas; //переменная для хранения значения о присутствии газа
int gas = 0; //переменная для хранения количества газа
float hum = 0; //переменная для хранения влажности
float temp = 0; //переменная для хранения температуры
char mac[18] = { 0 }; // переменная для mac адреса
int chk; //переменная для хранения ошибки DHT
const char ssid[] = "Keenetic-0138";   // SSID
const char pass[] = "********";        // пароль
int status = WL_IDLE_STATUS;     // статус Wifi-радиомодуля
String jsonString; // данные
String PostHeader; // заголовок
const char server[] = "esp8266.mysite.ru";
unsigned long lastConnectionTime = 0;   
unsigned long lastInfoTime = 0;
const unsigned long postingInterval = 1200000; // 20 минут 
const unsigned long infoInterval = 60000;      // 1 минута
// Инициализация объекта wi-fi клиент
WiFiEspClient client;
void setup()
{
  pinMode(12, OUTPUT);  
  Serial.begin(9600);
  WiFi.init(&Serial);
     
  if (WiFi.status() == WL_NO_SHIELD) {
    while (true);
  }
  while ( status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
  }
 
  uint8_t macH[6];
  WiFi.macAddress(macH);
  sprintf(mac, "XXXXXX", macH[0], macH[1], macH[2], macH[3], macH[4], macH[5]);
  httpRequest();
}
void loop()
{
 if (millis() - lastConnectionTime > postingInterval) { httpRequest(); }
 if (millis() - lastInfoTime > infoInterval) 
 {
     lastInfoTime = millis();
 }
}
void httpRequest()
{
    noGas = digitalRead(digitalSignal); //считываем значение о присутствии газа
    gas = analogRead(analogSignal);     // и о его количестве
    chk = DHT.read(DHT11_PIN); 
    hum = DHT.humidity;
    temp = DHT.temperature;
    
if (client.connect(server, 80)) {
  digitalWrite(12, HIGH);
  jsonString = "secret=0000&name=ESP_8266WiFi&temp=" + String(temp) + "&hum=" + String(hum) + "&gas=" + String(gas) + "&mac=" + String(mac)+ "&ram=" + String(freeRam()) + "&rssi=" + String(WiFi.RSSI());
  PostHeader = "POST /ajax/cGx1Z2lucy9t************************eC5waHA= HTTP/1.1\r\n"; 
  PostHeader += "Host: esp8266.mysite.ru:80\r\n";
  PostHeader += "User-Agent: ESP8266WiFi\r\n"; 
  PostHeader += "Accept: application/xml\r\n";
  PostHeader += "Content-Type: application/x-www-form-urlencoded\r\n"; 
  PostHeader += "X-Requested-With: XMLHttpRequest\r\n";  
  PostHeader += "Referer: http://esp8266.mysite.ru\r\n";
  PostHeader += "Connection: close\r\n";
  PostHeader += "Content-Length: " + String(jsonString.length()) + "\r\n";
  jsonString += "\r\n\r\n\r\n";
  client.println(PostHeader);
  client.println(jsonString);
 }
  while (client.available()) {
    char c = client.read();
  }
   if (!client.connected()) {
    client.stop();
    digitalWrite(12, LOW);
   }  
   lastConnectionTime = millis();
}
int freeRam () {
 extern int __heap_start, *__brkval;  int v;  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); }

Переданные значения сигналов, измеренных сенсорами можно видеть в админке плагина:

Загрузить исходники.

Скетч для отправки данных из ARDUINO esp8266wifi в MaxSite CMS

Плагин my_esp8266 для MaxSite CMS

Еще записи по теме

Мониторинг по интернет загазованности помещения с Arduino UNO и ESP8266 ESP-12E
Мониторинг по интернет загазованности помещения с Arduino UNO и ESP8266 ESP-12E
Отправляем состояния теплых полов из Arduino UNO ESP8266 WiFi на сервер ThingSpeak
Отправляем состояния теплых полов из Arduino UNO ESP8266 WiFi на сервер ThingSpeak
Плагин My_ESP8266 для MaxSiteCMS.
Плагин My_ESP8266 для MaxSiteCMS.
Подключаем Arduino UNO при помощи ESP8266-12E  к облаку Cayenne
Подключаем Arduino UNO при помощи ESP8266-12E к облаку Cayenne
Сравнение показаний двух датчиков DHT11 в динамике.
Сравнение показаний двух датчиков DHT11 в динамике.
Версия 02 плагина My_ESP8266 для MaxSiteCMS.
Версия 02 плагина My_ESP8266 для MaxSiteCMS.
Оставьте комментарий.

grin LOL cheese smile wink smirk rolleyes confused surprised big surprise tongue laugh tongue rolleye tongue wink raspberry blank stare long face ohh grrr gulp oh oh downer red face sick shut eye hmmm mad angry zipper kiss shock cool smile cool smirk cool grin cool hmm cool mad cool cheese vampire snake excaim question


Выберите для анонимного комментирования (комментарий будет опубликован после проверки).

     

  

Выберите если нужно войти или зарегистрироваться и оставить комментарий от своего аккаунта.

Войти, используя

(обязательно)

Подписка на новости
discord

Email:

Регистрация

Вход через
Разделы
  • Пожарная сигнализация123
    • Инструкции13
    • Проекты1
  • Автоматика52
  • Отопление33
  • Мониторинг30
  • Электрика16
  • Пожаротушение29
  • Умный дом32
  • Arduino12
  • Гаджеты32
  • MaxSite CMS26
Актуальное
  • СП 484
  • Автоматизация теплого пола
  • Болид vs Рубеж
  • С2000-АСПТ
  • ПЦН в кармане
  • Системы противопожарной зашиты
  • Cloud IoT
  • Проектирование
  • Программирование
  • Ссылки
Последние комментарии
Можно ли заставить работать "C2000-Ethernet"?
  • Вячеслав » Спасибо добрый человек! Строчки "Я не увидел здесь информации, что в прозрачном режиме система со структурой C2000M-Ethernet-Приб оры работать в прозрачном...
  • Андрей » Строчки ... меня спасли от долгих мучений! Я думаю для службы поддержки это само собой разумеющаяся информация.
Требуется ли контроль нормально-замкнутых линий управления СППЗ согласно СП 484.
  • Алексей » Добрый день! П.5.17 СП484: компоненты СПА и инженерные системы - это, наверное, разные вещи. Так, например, между какими-либо ППКиУ и...
Тестирование новых СП 484 на сложном объекте
  • Андрей » Да с охранкой вообще нет никаких проблем сейчас.
Как настроить байпас смесительного узла TIM JH-1036
  • Андрей » Я бы пробовал повращать регулировочный цилиндр байпаса. В разных положениях посмотреть как меняется температура. Вдруг там наклейка неправильно. И ещё проверить...
Последние загрузки
Все загрузки
Дискуссии на форуме
  • Пожарные системы
  • Проблемы совместимости речевых оповещателей со встроенными конденсаторами
  • Противопожарные шторы.
Реклама

(10pcs/lot) PCT-212/213/214/215 Universal Compact Wire Wiring Connector 2/3/4/5/8 pin Conductor Terminal Block Lever 0.08-2.5mm2

Mini PC Intel Core i7 7500U 8650U Computer Windows 10 2*DDR4 M.2 SSD 8*USB DP Type-C 2*LAN WiFi 4K HTPC Micro Desktop NUC Minipc

Newest release Garage door opener receiver wifi smart receiver use for galo brand swing sliding gate opener TX car

Пожарка 120 Проектирование 93 Болид 63 Лекции 58 Социальное 52 Рубеж 48 Обзор 46 Автоматика 44 Инженерные системы 38 Адресные системы 34 Отопление 33 Курьез 32 Практикум 32 Пожаротушение 31 Интернет Вещей 29 MaxSite 28 Терморегуляторы 24 Облачный Сервис 24 ГОСТ 24 Мониторинг 22 Плагин 21 Теплый пол 21 Сравнение 20 ППУ 20 AliExpress 20 Законы Ома 19 СП 484 19 Техобслуживание 18 Эксплуатация 17 Астра 17 ППК 17 Вентиляция 16 Электрика 14 Клапана 14 Оповещение 13 Рубикон 13 С2000-АСПТ 13 Arduino 13 С2000М 12 WiFi 12 Датчики 11 Гранд Магистр 11 Ritm 11 ESP8266 10 Юнитест 10 Насосная Станция 10 ВЭРС 9 ПЦН 9 Сценарии 8 Авария 8 Жилой дом 8 Диспетчеризация 7 Taggallery 7 Сообщества 7 Отзыв 7 Программирование 7 Плазма-Т 6 Освещение 6 Гаджеты 5 Спрут-2 5 ПО 5 С2000-СП4 5 GeoRITM 4 Радиоканал 4 МПТ 4 МПН 4 ИПДЛ 3 Гранит 3 Navigard 3 Учет ресурсов 3 Баня 3 Visio 3 Версет 3 My_ESP8266 3 Рубеж-2ОП 3 Firesec3 3 РИП 3 Zigbee 2 ТО 2 Security Hub 2
  • Обратная связь
  • Карта сайта
  • Отзыв
  • События
  • Комментарии
  • Форум
© Технические заметки 2023. Работает на MaxSite CMS. ( Вход )
Автор не несет ответственность за последствия применения материалов сайта на практике.