Меню Закрыть

Принимаем GET данные с NodeMcu на свой сайт

Примерно так будут выглядеть данные отправленные на сайт с Nodemcu
Примерно так будут выглядеть данные отправленные на сайт с Nodemcu

Конечно сразу после настройки Nodemcu для отправки на thingspeak.com захотелось сделать отправку к себе на сайт, что бы не было никаких ограничений.

Напишем не большой php скрипт для приема данных и записи их в файл. Это подойдет для хостингов без mysql к тому же я его пока так и не освоил.

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

Для отправки данных на сайт будем использовать вот такую функцию:

const char* host = "kno.su"; //адрес сайта int value = 0; //переменная для счётчика попыток подключения(если не получилось подключится с первого раза) void sendHttp (float temp){ ++value; const int httpPort = 80; //порт int count = 0; Serial.print("connecting to "); Serial.println(host); WiFiClient client; while(!client.connect(host, httpPort)){ Serial.print("("); Serial.print(count); Serial.println(")Connect to server."); delay(1000); } String url = "/sensor/sensor.php"; //путь к скрипту от корня url += "?api="; url += "DEY7kMFdpOCQTuAvsDbu"; //API код который должен совпадать с кодом в php скрипте иначе он данные не примет url += "&field1="; // название ключа, его нужно будет указать в функциях построения графика и последнего значения, может быть любой ключ главное задать его здесь и указать в функциях. url += String(temp); // Сама температура Serial.print("Requesting URL: "); Serial.println(url); // This will send the request to the server client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); Serial.println(); Serial.println("closing connection"); }
Code language: Arduino (arduino)

Ключей-значений может быть сколько угодно, их нужно будет добавить по аналогии в void sendHttp (float temp, float название_переменной_с_данными) и в текст url:

String url = "/sensor/sensor.php"; //путь к скрипту от корня url += "?api="; url += "DEY7kMFdpOCQTuAvsDbu"; //API код который должен совпадать с кодом в php скрипте иначе он данные не примет url += "&field1="; // название ключа, его нужно будет указать в функциях построения графика и последнего значения, может быть любой ключ главное задать его здесь и указать в функциях. url += String(temp); // Сама температура url += "&название_ключа_для_новой_переменной="; url += String(название_переменной_с_данныминной_с_даннымианнымиыми;
Code language: Arduino (arduino)

Саму функцию запускаем так:

float temperature = dht.readTemperature(); float humidity = dht.readHumidity(); //сначала опрашиваем ваши датчики в переменные temperature и humidity потом отправляем их значения в функцию, верхние две строчки для ясности, у вас должны будут быть вместо них опросы ваших датчиков возвращаемые в переменные которые в свою очередь передаем в функцию. sendHttp(temperature, humidity);
Code language: Arduino (arduino)

Целиком скетч будет выглядеть примерно так:

#include <ESP8266WiFi.h> const char* ssid = "KV3"; const char* password = "qweasd12345678"; unsigned long timing_http; // Переменная для хранения точки отсчета void setup() { Serial.begin(115200); delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); //works! while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } int value = 0; void loop() { int timer_http = 10 * 60 * 1000; //Таймер отправки (каждые 10 мин) if (millis() - timing_http > timer_http){ // Если настало время(таймер из переменной timer), то отправляем данные timing_http = millis(); Serial.println ("otpravka na kno.su"); float temperature = dht.readTemperature(); //у меня опрос dht 22 у вас может быть что угодно float humidity = dht.readHumidity(); //у меня опрос dht 22 у вас может быть что угодно float ppm = gasSensor.getPPM(); //у меня опрос mq135 у вас может быть что угодно float rzero = gasSensor.getRZero(); //у меня опрос mq135 у вас может быть что угодно //пинг смартфонов на предмет присутствия, эксперимент, нужна библиотека https://github.com/dancol90/ESP8266Ping int ping1 = 0; int ping2 = 0; int ping3 = 0; const IPAddress remote_ip_1(192, 168, 100, 201); if(Ping.ping(remote_ip_1)) {ping1 = 1;} else{ping1 = 0;} const IPAddress remote_ip_2(192, 168, 100, 202); if(Ping.ping(remote_ip_2)) {ping2 = 1;} else{ping2 = 0;} const IPAddress remote_ip_3(192, 168, 100, 203); if(Ping.ping(remote_ip_3)) {ping3 = 1;} else{ping3 = 0;} sendHttp(temperature, humidity, ppm, rzero, ping1, ping2, ping3); //Функция отправки, код функции ниже } } //Функция отправки с 7 значениями const char* host = "kno.su"; int value = 0; void sendHttp (float temp, float humidity, float ppm, float rzero, int ping1, int ping2, int ping3){ ++value; const int httpPort = 80; int count = 0; Serial.print("connecting to "); Serial.println(host); // Use WiFiClient class to create TCP connections WiFiClient client; while(!client.connect(host, httpPort)){ Serial.print("("); Serial.print(count); Serial.println(")Connect to kno.su."); delay(1000); } // We now create a URI for the request String url = "/sensor/sensor.php"; url += "?api="; url += "DEY7kMFdpOCQTuAvsDbu"; url += "&field1="; url += String(temp); url += "&field2="; url += String(humidity); url += "&field3="; url += String(ppm); url += "&field4="; url += String(rzero); url += "&ping1="; url += String(ping1); url += "&ping2="; url += String(ping2); url += "&ping3="; url += String(ping3); Serial.print("Requesting URL: "); Serial.println(url); // This will send the request to the server client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); Serial.println(); Serial.println("closing connection"); }
Code language: Arduino (arduino)

Вот скрипт приема и записи данных в файл с комментариями:

<?php date_default_timezone_set("Europe/Minsk"); //часовой пояс //Сравниваем ключ API с тем что прислан, если все сходится продолжаем: if(isset($_GET['api']) && $_GET['api'] == "DEY7kMFdpOCQTuAvsDbu"){ unset($_GET['api']); //удаляем api т.к. он нужен был только для проверки подлинности $sensors_data = $_GET; //Все данные из $_GET переносим в $sensor_data $date_sensor = date("Y-m-d H:i"); // Дата, в таком формате что бы потом можно было использовать со js скриптом графика $sensors_write ="date=$date_sensor::"; //Переменная с данными которые будут записаны в файл $filename = "nodemcu.dat"; //имя файла foreach($sensors_data as $key => $value){//цикл который запишет все ключи и их значения которые пришли $sensors_write .= "$key=$value::"; } $sensors_write .= "]||[\n";//разделитель между записями $text = $sensors_write; //Итоговый текст для записи в файл if(file_exists($filename)) //Проверка наличия файла { echo "<b>Файл есть</b><br>"; } else{ echo "<b>Файл не найден</b></br>"; } $fh = fopen($filename, 'a+'); //Переменная для открытия файла fwrite($fh, $text) or die ("Ошибка записи файла"); // Запись файла fclose($fh); // Закрытие файла echo "Запись добавлена"; } ?>
Code language: PHP (php)

Дальше нужно эти данные считать и показать. Для этого напишем три функции: функцию чтения из файла в массив вида ключ = значение, функцию которая с этого массива берет один ключ и строит по нему график на основе dygraphs, и функцию которая будет выводит последнее поступившее значение по определенному ключу.

Функция чтения:

function sensor_read($filename){ $sensors_read = file_get_contents($filename); $sensors_read = explode("]||[\n", $sensors_read); foreach($sensors_read as $key => $value){ $sensors_temp = explode("::", $value); $n = 0; foreach($sensors_temp as $key_ => $value){ if($value != ""){ $sensors_data[$key][$key_] = explode("=", $value); }} } foreach ($sensors_data as $key => $value){ //test_print($value); //$sensors[$value[0]] = $value[1]; foreach($value as $key_ => $sensor){ //test_print($sensor); $sensors[$key][$sensor[0]] = $sensor[1]; } } return $sensors; }
Code language: PHP (php)

Функция построения графика:

function sensor_graph($sensor_id, $sensor_id_description, $sensors){ echo' <div id="'.$sensor_id.'_graph" class="graph" style="width: 90%; height: 100px; margin: 5px auto;"></div><script type="text/javascript"> g = new Dygraph( // containing div document.getElementById("'.$sensor_id.'_graph"), "Дата,'.$sensor_id_description.'\n" + '; $sensor_count = 0; foreach($sensors as $key => $value){ if(isset($value[$sensor_id]) && $value[$sensor_id] != ""){ $sensor_count++; } } $count = 0; foreach($sensors as $key => $value){ if(isset($value[$sensor_id]) && $value[$sensor_id] != ""){ $count++; if($count < $sensor_count){ echo '"'.$value['date'].",".$value[$sensor_id].'\n'.'" +'."\n"; } else{ echo '"'.$value['date'].",".$value[$sensor_id].'"'."\n".");\n"; } } } echo '</script>'; }
Code language: PHP (php)

Для того что бы график работал нужно подключить библиотеку dygraph:

<script type="text/javascript" src="dygraph.js"></script>
Code language: HTML, XML (xml)

Саму библиотеку можно скачать и ознакомится с ней на сайте dygraphs.com.

Функция вывода последнего значения:

function sensor_latest($sensor_id, $sensors){ foreach($sensors as $key => $value){ foreach($value as $key_ => $value_){ if(isset($value[$sensor_id]) && $value[$sensor_id] !=""){ $sensor_latest['sensor'] = $value[$sensor_id]; $sensor_latest['date'] = $value['date']; } } } return $sensor_latest; }
Code language: PHP (php)

Последнее значение будет в виде массива, где ключ sensor — само значение, а ключ date — дата когда оно поступило.

В итоге файл с вызовом этих функций должен выглядеть примерно так:

<?php include "functions.php"; echo ' <html> <head> <title>Датчики</title> <meta charset="utf-8"> <meta name="robots" content="nofollow" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <link rel="stylesheet" href="style.css"> <script type="text/javascript" src="dygraph.js"></script> </head> <body> '; $filename = "nodemcu.dat"; //имя файла $sensors = sensor_read($filename); //массив с данными для функций $field1_latest = sensor_latest("field1", $sensors);//последнее значение echo "<h4>Температура ".$field1_latest['sensor']." °C</h4>"; //вывод последнего значения sensor_graph("field1", "Температура", $sensors); //вывод графика echo'</body> </html>'; ?>
Code language: HTML, XML (xml)

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

З.Ы. Как ни странно но долетают данные иногда реже чем на thingspeak и от чего такие затупы так и не понял, возможно дело в хостинге.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Капча загружается...