ESP32 jako Wi-Fi webový klient
V minulém článku jsme si ukázali, jak může modul ESP32 fungovat jako jednoduchý webový server. Takové řešení je vhodné například tehdy, když se k ESP32 připojuje webový prohlížeč nebo jiný klient a požaduje data či ovládání zařízení.
V praxi se však velmi často setkáme s opačnou situací. Modul ESP32 nevystupuje jako server, ale jako klient, který aktivně navazuje spojení s jinými servery na internetu nebo v lokální síti. Typickými příklady jsou:
- načtení textového souboru z konkrétní URL adresy,
- získání aktuálního času z internetového serveru,
- komunikace s REST API (Representational State Transfer Application Programming Interface – webové rozhraní umožňující vzájemnou výměnu dat mezi aplikacemi),
- načtení meteorologických dat ve formátu JSON (JavaScript Object Notation – lehký textový formát určený pro výměnu strukturovaných dat mezi aplikacemi,
- odesílání naměřených hodnot do cloudových služeb,
- komunikace se systémy chytré domácnosti.
Právě na tuto roli ESP32 se zaměříme v tomto článku.
Klient a server
Komunikace na webu je založena na modelu klient–server.
Klient je zařízení nebo aplikace, která iniciuje komunikaci a odesílá požadavky. Server naopak na tyto požadavky reaguje a poskytuje požadované služby nebo data.
V našem případě bude klientem modul ESP32:
- ESP32 (klient) odešle HTTP požadavek na server.
- Server požadavek zpracuje.
- Server vrátí HTTP odpověď.
- ESP32 (klient) odpověď přečte a případně zpracuje získaná data.
Odpověď serveru kromě samotných dat obsahuje také takzvaný stavový kód HTTP, který informuje o výsledku požadavku.
Například:
- 200 OK – požadavek byl úspěšně zpracován,
- 404 Not Found – požadovaný zdroj nebyl nalezen,
- 500 Internal Server Error – na serveru došlo k chybě.
Jak vypadá HTTP požadavek
Ať už ESP32 komunikuje se serverem pomocí metody GET, POST nebo jiné HTTP metody, vždy se vytváří a odesílá HTTP požadavek. Ten má přesně definovanou strukturu.
HTTP požadavek se skládá ze čtyř částí:
- startovní řádka dotazu (Request Line),
- hlavičky (Headers),
- prázdný řádek oddělující hlavičky od těla (dat),
- tělo zprávy (Body).
Kde končí hlavička a kde tělo požadavku?
Důležitou součástí HTTP protokolu je způsob oddělení hlaviček od vlastních přenášených dat. Po poslední hlavičce následuje vždy prázdný řádek (přesněji sekvence CRLF, tedy \r\n). Tím server pozná, že hlavičky skončily. Pokud požadavek obsahuje tělo zprávy (body), nachází se za tímto oddělovačem vlastní data.
Příklad požadavku POST, který má data v těle zprávy – prázdný řádek mezi hlavičkami a JSON daty je zde povinný:
POST /update-sensor HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 32
{"temperature":23.5,"humidity":54}
Ale například jednoduchý požadavek GET může vypadat následovně: První řádek (GET ...) představuje tzv. Request Line (řádku dotazu), druhý (Host: ...) a třetí (User-Agent: ...) představují hlavičky, které předávají určité informace. V tomto případě není potřeba přenášet žádná data, a proto tělo zprávy zcela chybí.
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: ESP32
Požadavky GET většinou žádné tělo zprávy neobsahují. V takovém případě HTTP zpráva končí ihned za prázdným řádkem oddělujícím hlavičky.
Za hlavičkou User-Agent následuje jeden prázdný řádek, který současně:
- ukončuje hlavičky,
- oznamuje, že žádné tělo zprávy nenásleduje.
Není tedy potřeba přidávat další prázdný řádek představující prázdné tělo. Tělo prostě neexistuje.
Jak server pozná konec těla zprávy?
- Nejčastěji pomocí hlavičky:
Content-Length.
Hlavička Content-Length udává počet bajtů v těle požadavku. Server tedy po přečtení ví, že tělo zprávy po zadaném počtu bajtů skončilo. Například ve výše uvedeném POST požadavku bylo uvedeno: Content-Length: 32, což serveru říkalo, že tělo {"temperature": zabírá 32 bajtů (32 ASCII znaků). Přidáme-li mezeru za čárku mezi jednotlivé parametry, musíme Content-Length zvýšit na 33.
- Poznámka: (jen tak trochu mimo)
- U některých typů komunikace lze použít také mechanismus Chunked Transfer Encoding (nastaveno hlavičkou
Transfer-Encoding: chunked), kdy jsou data přenášena po částech (blocích) – tzv. chunks. Tento způsob posílání se používá v situacích, kdy klient neví (nebo nechce předem počítat) celkovou velikost zprávy pro hlavičkuContent-Length. - Hlavička
Transfer-Encoding: chunkedříká serveru: „Nehledej hlavičku Content-Length. Data ti budu posílat po kusech a na konci ti dám vědět, že jsem skončil.“ Každý datový blok se skládá ze dvou řádků: Na prvním je uvedena velikost bloku v hexadecimální soustavě (zakončenáCRLF), na druhém jsou samotná data (rovněž zakončenáCRLF). - Jak pak server pozná konec? Jakmile jsou odeslána všechna data, pošle se závěrečný chunk s nulovou délkou. Za touto nulou následuje
CRLF(\r\n) a hned po něm ještě jednoCRLF, které označuje absolutní konec celého těla HTTP požadavku (0\r\n\r\n). - Například: Nejprve se odešlou HTTP hlavičky a první blok dat.
POST /update-sensor HTTP/1.1
Host: www.example. com
Content-Type: application/json
Transfer-Encoding: chunked
11
{"temperature":23.5, - Spojení zůstává otevřené a čeká se například na pomalejší čidlo. Jakmile je naměřená hodnota známá, odešle se do stále aktivního streamu druhý blok dat:
11
"humidity":54} - Jakmile je tělo zprávy kompletní, odesílání se završí nulovým blokem:
0 - I když se s tímto při běžném programování ESP32 setkáme jen spíše výjimečně, dovolili jsme si to zde zmínit, neboť o to překvapivější to může být setkání. Nám to třeba docela zamotalo hlavu při psaní článku: ESP32: Načtení JSON dat z internetu v MicroPythonu.
- Zavření TCP spojení (
Connection: close).
Pokud nepoužijeme Content-Length ani Transfer-Encoding, server přijímá data tak dlouho, dokud klient fyzicky neuzavře TCP socket (posláním FIN paketu). Jak server pozná konec? Připojení se ukončí (EOF – End of File). To je možné, ale velmi neefektivní. Spojení nelze znovu použít pro další požadavek (vypne se tzv. Keep-Alive).
Pokud na mikrokontroléru typu ESP32/Arduino chceme po odeslání požadavku a přijetí odpovědi socket hned zavřít (abychom šetřili paměť RAM), je dobré Connection: close přidat. Serveru tím řekneme, že po poslání odpovědi může spojení rovnou utnout.
Např.:
POST /update-sensor HTTP/1.1
Host: www.example.com
Content-Type: application/json
Connection: close
{"temperature":23.5,"humidity":54}
Po odeslání dat a přijetí odpovědi od serveru klient spojení hned zavře.
- UPOZORNĚNÍ:
- I v tomto případě bychom přidáním hlavičky
Content-Lengthdoporučovali! - Některé servery (a webové frameworky) požadavek bez
Content-Lengthrovnou odmítnou s chybou:411 Length Required.
- Přechod na
HTTP/2neboHTTP/3.
V modernějších protokolech HTTP/2 a HTTP/3 hlavičku Content-Length není třeba vůbec posílat (je zcela volitelná). Jak server pozná konec? Protokol rozděluje data do tzv. rámců (frames). Poslední datový rámec jednoduše obsahuje speciální příznak END_STREAM. Jakmile server uvidí tento příznak, ví, že požadavek je kompletní.
Tím se zde ale zabývat nebudeme. Držíme se specifikace HTTP/1.1
- POZNÁMKA:
- V běžné praxi většinou nemusíme jednotlivé části HTTP požadavku sestavovat ručně. Knihovny pro ESP32 (například
HTTPClient) vytvářejí HTTP zprávy automaticky. Přesto je dobré znát jejich strukturu, protože usnadňuje pochopení rozdílů mezi metodami GET a POST i následné zpracování odpovědí serveru.
Nyní, když trochu tušíme, jak je HTTP požadavek sestaven, podívejme se na dva nejčastěji používané typy požadavků, se kterými se při programování ESP32 setkáme – GET a POST.
HTTP metody – GET a POST
Jakmile má ESP32 navázané připojení k síti Wi-Fi, může začít komunikovat s webovými servery. Samotné navázání spojení však ještě nestačí. Modul musí serveru také sdělit, co vlastně požaduje. K tomu slouží HTTP metody.
HTTP (Hypertext Transfer Protocol) definuje několik typů požadavků, které určují způsob komunikace mezi klientem a serverem. Každý požadavek začíná názvem metody, podle které server pozná, zda klient požaduje pouze data, chce je odeslat, aktualizovat nebo například odstranit.
Mezi nejpoužívanější HTTP metody patří:
- HEAD – získání pouze informací o zdroji bez jeho obsahu.
- GET – získání dat ze serveru.
- POST – odeslání dat serveru ke zpracování.
- PUT – vytvoření nebo úplná aktualizace zdroje.
- DELETE – odstranění zdroje.
Při programování modulu ESP32 se však ve většině případů setkáme především s metodami GET a POST. Pomocí GET budeme nejčastěji data ze serveru získávat, zatímco pomocí POST je budeme na server odesílat.
HTTP metoda GET
Metoda GET představuje nejběžnější způsob získávání dat ze serveru. Používá se například při načtení webové stránky v internetovém prohlížeči, stažení souboru, získání hodnot ze senzoru nebo při načtení odpovědi z nějakého API rozhraní.
Typickým znakem metody GET je skutečnost, že všechny parametry požadavku jsou součástí URL adresy. Pokud tedy potřebujeme serveru předat nějaké informace, připojují se přímo za adresu požadovaného zdroje.
Příklad:
GET /update-sensor.php?temperature=10&unit=C
V tomto případě klient požaduje stránku nebo skript update-sensor.php, současně však předává dva parametry:
temperature=10
unit=C
Parametry začínají za znakem ? a jednotlivé dvojice název=hodnota jsou odděleny znakem &.
Pokud bychom tento požadavek přepsali do běžné URL adresy, vypadal by takto:
http://
Server z adresy snadno zjistí, že klient předává hodnotu teploty 10 °C.
Kódování speciálních znaků
Protože adresa URL může obsahovat pouze omezenou sadu znaků, musí být některé znaky převáděny do speciálního kódování označovaného jako URL Encoding nebo Percent Encoding.
- Například:
- mezera → %20
- čárka → %2C
- # → %23
V některých formulářových datech se mezera může zapisovat také pomocí znaku +.
Pokud tedy předáváme textové údaje obsahující mezery nebo speciální znaky, musí být před odesláním tímto způsobem zakódovány.
Výhody a nevýhody metody GET
Metoda GET je jednoduchá, přehledná a velmi snadno se testuje. Stačí zadat URL do prohlížeče a požadavek je okamžitě odeslán. Proto se používá především pro získávání informací.
Nevýhodou je skutečnost, že všechny předávané parametry jsou součástí URL adresy. Mohou se tedy objevit v historii prohlížeče, serverových logách nebo diagnostických nástrojích. Současně není vhodné přenášet tímto způsobem větší množství dat, protože délka URL bývá omezena použitým serverem nebo klientem.
V našich projektech s ESP32 budeme metodu GET používat zejména pro:
- načítání webových stránek,
- stahování textových souborů,
- získávání dat z REST API,
- načítání JSON dat,
- jednoduché předávání několika měřených hodnot.
HTTP metoda POST
Zatímco metoda GET se používá převážně pro získávání dat, metoda POST slouží především k jejich odesílání serveru.
Typickým příkladem může být odeslání naměřených hodnot do databáze, registrace uživatele, uložení konfigurace zařízení nebo nahrání souboru na server.
Hlavní rozdíl oproti metodě GET spočívá v tom, že odesílaná data nejsou součástí URL adresy. Nacházejí se až v těle HTTP požadavku (body).
Příklad jednoduchého POST požadavku:
POST /update-sensor HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 62
api_key=api&sensor_name=name&temperature=23.5&humidity=54&pressure=1012
Samotná URL přitom zůstává stále stejná:
http://
Bez ohledu na to, kolik dat klient odesílá. To je jeden z důvodů, proč se POST používá pro rozsáhlejší komunikaci mezi aplikacemi.
Odesílání dat ve formátu JSON
V současnosti řada webových služeb používá místo klasických formulářových dat formát JSON (JavaScript Object Notation). JSON představuje jednoduchý textový formát určený pro ukládání a výměnu strukturovaných dat. Je dobře čitelný jak pro člověka, tak pro program. JSON je dnes standardní formát pro komunikaci.
S podobnou strukturou se budeme setkávat při komunikaci s REST API službami, například při získávání meteorologických dat, informací o kurzech měn nebo při komunikaci s cloudovými IoT platformami.
Stejný požadavek jako v předešlé ukázce může být zapsán pomocí JSON kupříkladu takto:
POST /update-sensor HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 114
{
"api_key": "api",
"sensor_name": "name",
"temperature": 23.5,
"humidity": 54,
"pressure": 1012
}
- Poznámka ke
Content-Length - Pokud budeme trvat na zachování mezer a odřádkování jako je ve výše uvedené ukázce, musíme do délky těla započítat i tyto mezery a neviditelné znaky (např. odřádkování
\r\n= 2 bajty). - Na mikrokontrolérech se vyplatí vymazat z JSONu všechny zbytečné mezery a odřádkování, aby se ušetřila paměť a i přenesená data. Tělo požadavku by pak spíše vypadalo:
{"api_key":, což bude mít jen 82 bajtů."api", "sensor_name": "name", "temperature": 23.5, "humidity": 54, "pressure": 1012}
V předchozích ukázkách jsme si možná všimli nejen rozdílného formátu odesílaných dat, ale i rozdílné hlavičky Content-Type. Hlavička Content-Type informuje server o formátu dat uložených v těle požadavku. Server tak ví, jak má přijatá data interpretovat. Pokud je uvedeno application/, očekává server JSON dokument. Naopak u formulářových dat bývá použita hodnota application/.
Výhody a nevýhody metody POST
Metoda POST umožňuje přenášet podstatně větší objem dat než GET. Současně podporuje různé datové formáty – od klasických formulářových dat přes JSON až po binární soubory.
Její typické použití zahrnuje:
- ukládání dat do databází,
- odesílání měřených hodnot,
- konfiguraci zařízení,
- přenos JSON objektů,
- nahrávání souborů a obrázků,
- aktualizace firmware.
Na druhou stranu je komunikace pomocí POST o něco složitější na implementaci i diagnostiku, protože odesílaná data nejsou přímo viditelná v URL adrese.
Je metoda POST bezpečnější?
Častým omylem je přesvědčení, že POST automaticky zajišťuje vyšší bezpečnost než GET.
Ve skutečnosti tomu tak není. Data sice nejsou součástí URL adresy, ale stále jsou přenášena jako obyčejný text v těle požadavku. Pokud je komunikace vedena prostřednictvím nešifrovaného protokolu HTTP, může být obsah zachycen stejně snadno jako u metody GET.
Skutečnou ochranu poskytuje až použití protokolu HTTPS (HTTP Secure) využívajícího šifrování TLS. V takovém případě jsou chráněny nejen odesílané hodnoty, ale i samotná URL adresa, hlavičky a většina dalších přenášených informací.
Na metodu POST je proto vhodné pohlížet především jako na nástroj pro přenos většího množství dat, nikoliv jako na bezpečnostní mechanismus.
Vytvoření Wi-Fi klienta
- DŮLEŽITÉ UPOZORNĚNÍ:
- Prakticky každý z následujících kódů by měl začínat stejnou úvodní sekvencí programu, která zajistí připojení k bezdrátové síti. Přítomnost tohoto kódu by nejen zbytečně prodlužovala kód, ale především zastiňovala to hlavní, co bychom si chtěli v programu ukázat.
- Veškerý kód související s připojením k Wi-Fi síti je tedy přesunut do vlastního modulu
WI-FI-moje, který jsme si zavedli v úvodním článku: Wi-Fi přístup k modulu ESP32. - Doporučujeme tento článek navštívit a pro níže uvedené ukázky, ve kterých se v úvodu objeví:
#include "WI-FI-moje.h", doplnit k ukázkám i soubory tohoto modulu.
Po připojení modulu ESP32 k Wi-Fi síti můžeme začít komunikovat se servery na internetu. ESP32 nabízí několik způsobů, jak vytvořit HTTP klienta. Od velmi jednoduchého řešení, které připomíná klasické Arduino a práci se socketem, až po komfortní použití knihovny HTTPClient.h, která většinu práce provede za nás.
„Arduinovský“ přístup s třídou WiFiClient
Nejnižší vrstvou je třída WiFiClient, která je součástí vestavěné knihovny WiFi a představuje TCP klienta. V tomto případě musíme sami navázat spojení, odeslat HTTP požadavek a následně postupně číst odpověď serveru.
Výhodou tohoto přístupu je, že dobře ukazuje, jak vlastně protokol HTTP funguje. V následující ukázce načteme ukázkový textový soubor z URL:http://
#include <WiFi.h>
#include "WI-FI-moje.h"
const char* ssid = "nazev wi-fi site";
const char* password = "heslo wi-fi site";
void setup() {
Serial.begin(115200);
if (!connectWiFi(ssid, password)) {
while (true);
}
WiFiClient client;
if (client.connect("esp32.fyzika.net", 80)) {
client.println("GET /Arduino-IDE/jsem-tu.txt HTTP/1.1");
client.println("Host: esp32.fyzika.net");
client.println("Connection: close");
client.println();
while (client.connected() || client.available()) {
if (client.available()) {
char c = client.read();
Serial.print(c);
}
}
client.stop();
} else {
Serial.println("Pripojeni k serveru selhalo.");
}
}
void loop() {
}
Tento příklad pěkně navazuje na předchozí část článku věnovanou HTTP komunikaci. Na rozdíl od knihovny HTTPClient.h (viz dále) zde totiž můžeme přímo vidět, jak HTTP požadavek skutečně vzniká. Řádek GET / představuje první řádek HTTP požadavku, kterým server žádáme o zaslání souboru umístěného na adrese /Arduino-IDE/. Následující hlavička Host: esp32. určuje cílový server a hlavička Connection: close říká serveru, že po odeslání odpovědi může spojení ukončit. Poslední prázdný řádek je velmi důležitý, protože odděluje hlavičky od případného těla požadavku. V našem případě žádné tělo neposíláme, protože používáme metodu GET. Tento „nízkoúrovňový“ způsob komunikace nám umožňuje lépe pochopit fungování protokolu HTTP a ukazuje, že knihovny vyšší úrovně ve skutečnosti pouze automatizují vytváření a zpracování podobných textových zpráv.
Všimněte si několika důležitých detailů:
- Připojujeme se přímo na TCP port
80. - HTTP požadavek skládáme ručně po jednotlivých řádcích.
- Odpověď čteme znak po znaku.
- Musíme sami zajistit ukončení spojení. (
client.stop())
Právě tento způsob připomíná řadu starších příkladů pro Arduino Ethernet Shield nebo ESP8266.
Následující obrázek č. 3 ukazuje výpis načteného souboru v Serial monitoru prostředí Arduino IDE. Vidíme, že tam je kompletní odpověď včetně stavového kódu, hlaviček oddělovacího řádku a těla – tak jak jej protokol http zaslal.
WiFiClientČtení po řádcích
Praktičtější variantou je načítat odpověď po celých řádcích:
while (client.connected() || client.available()) {
String line = client.readStringUntil('\n');
Serial.println(line);
}
Výpis je sice přehlednější a lépe se s ním pracuje, ale stále musíme sami řešit HTTP komunikaci.
Klient s využitím knihovny HTTPClient
Knihovna HTTPClient představuje vyšší vrstvu nad třídou WiFiClient. Postará se za nás o sestavení HTTP požadavku, zpracování odpovědi i kontrolu návratových kódů. Oproti předchozí knihovně WiFi, která je již součástí balíku pro modul ESP32, musíme tentokráte knihovnu HTTPClient doinstalovat. To provedeme zcela běžně v manažeru knihoven vývojového prostředí Arduino IDE, jako jsme již dělali v mnoha jiných případech. K tomu je dobré jen poznamenat, že instalujeme knihovnu HTTPClient, jejímž autorem je Adrian McEwen.
Ve většině běžných aplikací je právě toto doporučený způsob komunikace.
#include <WiFi.h>
#include <HTTPClient.h>
#include "WI-FI-moje.h"
const char* ssid = "nazev wi-fi site";
const char* password = "heslo wi-fi site";
void setup() {
Serial.begin(115200);
if (!connectWiFi(ssid, password)) {
while (true);
}
HTTPClient http;
http.begin("http://esp32.fyzika.net/Arduino-IDE/jsem-tu.txt");
int httpCode = http.GET();
if (httpCode > 0) {
Serial.print("HTTP kod: ");
Serial.println(httpCode);
String response = http.getString();
Serial.println("Obsah souboru:");
Serial.println(response);
} else {
Serial.print("Chyba: ");
Serial.println(http.errorToString(httpCode));
}
http.end();
}
void loop() {
}
Oproti předchozímu řešení založenému na třídě WiFiClient je tento program výrazně jednodušší. Nemusíme zde ručně sestavovat HTTP požadavek ani řešit jednotlivé hlavičky. Stačí předat metodě begin() úplnou URL adresu požadovaného zdroje a knihovna HTTPClient sama zjistí název serveru i cestu k souboru, vytvoří odpovídající HTTP požadavek, odešle jej a zpracuje přijatou odpověď. Programátor tak může pracovat na podstatně vyšší úrovni a soustředit se především na data, která chce ze serveru získat.
Všimněme si:
- Návratová hodnota
httpCodeobsahuje HTTP stavový kód (např. 200, 404 nebo 500). - Metoda
getString()vrátí celé tělo odpovědi jako objektString.
Výstup vidíme na obrázku č. 4 opět v okně sériového monitoru:
HTTPClientPřístup k HTTP hlavičkám
Někdy nás zajímá nejen obsah stránky, ale také HTTP hlavičky, ty v případě použití HTTPClient získáme metodou header objektu http.
Pojďme to tedy zkusit:
#include <WiFi.h>
#include <HTTPClient.h>
#include "WI-FI-moje.h"
const char* ssid = "nazev wi-fi site";
const char* password = "heslo wi-fi site";
void setup() {
Serial.begin(115200);
if (!connectWiFi(ssid, password)) {
while (true);
}
HTTPClient http;
http.begin("http://esp32.fyzika.net/Arduino-IDE/jsem-tu.txt");
int httpCode = http.GET();
if (httpCode > 0) {
Serial.print("Content-Type: ");
Serial.println(http.header("Content-Type"));
Serial.print("Content-Length: ");
Serial.println(http.header("Content-Length"));
}
http.end();
}
void loop() {
}
Výsledek v sériovém monitoru ale bude vypadat takto (viz obr. 5):
Tak tady je asi něco špatně! Copak předání pouhého řetězce metodě header nestačí?
Právě v podobných situacích se vyplatí nechat si poradit. Stačí se zeptat některého AI chatbota a hned se dozvíme, že knihovna HTTPClient
na ESP32 automaticky nezpřístupňuje všechny hlavičky HTTP odpovědi. Ty, které nás zajímají, si musíme předem „objednat“, tedy zaregistrovat ještě před odesláním požadavku.
Následující část kódu ukazuje, co je třeba do předchozího kódu doplnit, aby metoda header začala vracet požadované hlavičky.
// ...
HTTPClient http;
const char* headerKeys[] = {
"Content-Type",
"Content-Length"
};
http.collectHeaders(headerKeys, 2);
http.begin("http://esp32.fyzika.net/Arduino-IDE/jsem-tu.txt");
// ...atd...
Tímto způsobem lze pak získat hlavičky, které chceme – například typ přenášených dat nebo jejich velikost – viz obrázek č. 6:
Kdy použít třídu WiFiClient a kdy modul HTTPClient?
Třída WiFiClient je vhodná tehdy, když:
- chcete pochopit princip HTTP komunikace,
- potřebujete implementovat vlastní síťový protokol,
- potřebujete maximální kontrolu nad přenášenými daty.
Knihovna HTTPClient.h je vhodná prakticky ve všech běžných projektech:
- výrazně zjednodušuje kód,
- automaticky zpracovává HTTP komunikaci,
- poskytuje přístup ke stavovým kódům i hlavičkám,
- umožňuje snadno realizovat požadavky GET, POST, PUT a další.
Třídu WiFiClient je ale dobré znát, protože právě na ní jsou vyšší síťové knihovny postaveny a občas se hodí pro speciální případy, kdy potřebujeme mít komunikaci plně pod kontrolou.
Odesílání parametrů metodou GET
V předchozích ukázkách jsme pomocí metody GET pouze stahovali obsah souborů ze serveru. Kromě získávání dat můžeme pomocí metody GET serveru předávat i parametry. Jak jsme si vysvětlili dříve, zapisují se za znak ? a jednotlivé položky se oddělují znakem &.
Takové parametry pak může zpracovat skript běžící na serveru.
PHP skript pro zpracování parametrů
Pro následující ukázku na našem serveru již máme připravený zkušební skript parametry-GET.php, který načte předané parametry a vypíše je do výsledné webové stránky.
<?php
$jmeno = $_GET["jmeno"];
$teplota = $_GET["teplota"];
$vlhkost = $_GET["vlhkost"];
echo "<h2>Prijate hodnoty</h2>";
echo "Jmeno: " . $jmeno . "<br>";
echo "Teplota: " . $teplota . " °C<br>";
echo "Vlhkost: " . $vlhkost . " %<br>";
?>
Nyní není nutné podrobně rozumět jazyku PHP. Pro naše účely stačí vědět, že pole $_GET obsahuje všechny parametry předané metodou GET.
Pokud tedy v URL existuje parametr teplota, můžeme jeho hodnotu získat pomocí výrazu:
$_GET["teplota"]
A tento skript nedělá nic jiného, než že tyto hodnoty parametrů vypisuje. Můžete to vyzkoušet kliknutím na následující tlačítko, které odešle stejný GET požadavek jako za chvíli náš modul ESP32. V šedém okně pod tlačítkem by se měl tento požadavek zobrazit v podobě výpisu náhodných tří znaků (jméno) a náhodné hodnoty teploty a vlhkosti (obojí v rozmezí 0–100).
Odeslání parametrů z ESP32
Následující program pro modul ESP32 odešle na server tři parametry: jméno zařízení, naměřenou teplotu a vlhkost. Udělá tedy totéž, co naše tlačítko výše.
#include <WiFi.h>
#include <HTTPClient.h>
#include "WI-FI-moje.h"
const char* ssid = "nazev wi-fi site";
const char* password = "heslo wi-fi site";
void setup() {
Serial.begin(115200);
if (!connectWiFi(ssid, password)) {
while (true);
}
randomSeed(micros());
// Náhodné třípísmenné jméno
char jmeno[4];
jmeno[0] = 'A' + random(26);
jmeno[1] = 'A' + random(26);
jmeno[2] = 'A' + random(26);
jmeno[3] = '\0';
// Náhodné hodnoty 0 až 100
int teplota = random(101);
int vlhkost = random(101);
String url = "http://esp32.fyzika.net/Arduino-IDE/parametry-GET.php?";
url += "jmeno=" + String(jmeno);
url += "&teplota=" + String(teplota);
url += "&vlhkost=" + String(vlhkost);
Serial.println(url);
HTTPClient http;
http.begin(url);
int httpCode = http.GET();
if (httpCode > 0) {
Serial.println(http.getString());
} else {
Serial.println("Chyba komunikace.");
}
http.end();
}
void loop() {
}
Po spuštění programu se odešle požadavek, např.: http://
Server následně vypíše přijaté hodnoty v odpovědi, která se zobrazí v sériovém monitoru (viz obr. č. 7).
V ukázce také vidíme, že ve skutečném programu pochopitelně nejsou hodnoty zapsány přímo v textovém řetězci, ale že dochází k sestavení dotazu z naměřených dat.
String url = "http://esp32.fyzika.net/Arduino-IDE/parametry-GET.php?";
url += "jmeno=" + String(jmeno);
url += "&teplota=" + String(teplota);
url += "&vlhkost=" + String(vlhkost);
Takto lze do požadavku snadno doplnit aktuální hodnoty získané ze senzorů.
Praktické využití: odesílání meteorologických dat na Weather Underground
Odesílání parametrů metodou GET se často používá při vytváření jednoduchých IoT zařízení. Typickým příkladem je domácí meteostanice založená na ESP32.
ESP32 pravidelně měří například:
- teplotu,
- vlhkost vzduchu,
- atmosférický tlak,
- rychlost a směr větru,
- množství srážek.
Naměřené hodnoty následně odešle na vzdálený server jako parametry HTTP požadavku. Server data uloží do databáze a umožní jejich grafické zobrazení.
Zatímco náš ukázkový PHP skript pouze vypisuje přijaté parametry, v reálných IoT aplikacích bývá cílem předat data specializované internetové službě. Jednou z nejznámějších platforem pro sdílení údajů z domácích meteostanic je Weather Underground (WU). Tato služba umožňuje sbírat data z tisíců soukromých meteorologických stanic po celém světě a zobrazovat je na mapách, v grafech nebo ve formě historických statistik.
Chceme-li, aby naše domácí meteostanice s tímto serverem spolupracovala, je nejprve nutné vytvořit si na tomto webu bezplatný účet a svou meteostanici zaregistrovat. Po registraci získá uživatel dva důležité údaje:
- ID stanice (ID), například
IPRAHA123 - Station Key (PASSWORD), tedy tajný přístupový klíč
Tyto údaje slouží k ověření, že data skutečně odesílá registrovaná stanice. Bez správného ID a klíče server data odmítne.
Základem komunikace se serverem WU je HTTP GET požadavek na adresu:
https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php
Do URL se následně přidají jednotlivé parametry:
https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?ID=IPRAHA123&PASSWORD=ABCD1234&dateutc=now&tempf=72.5&humidity=61&baromin=29.95&action=updateraw
Zde je vidět, že princip je úplně stejný jako v našem předchozím příkladu s PHP skriptem. Pouze místo vlastního serveru posíláme data na server Weather Underground.
Nejčastěji používané parametry pro odesílání dat na server WU
Následující tabulka č. 1 obsahuje přehled nejčastěji používaných parametrů serveru Weather Underground.
| PARAMETR | Význam a popis parametru | Formát (Jednotka) hodnoty |
|---|---|---|
ID |
Identifikátor meteostanice | text |
PASSWORD |
Přístupový klíč stanice | text |
dateutc |
Datum a čas měření (UTC) nebo hodnota now říká, že hodnoty jsou platné právě teď |
UTC |
tempf |
Venkovní teplota | °F |
humidity |
Relativní vlhkost vzduchu | % |
dewptf |
Rosný bod | °F |
baromin |
Atmosférický tlak | inHg |
winddir |
Směr větru | úhlové stupně 0–360 |
windspeedmph |
Rychlost větru | mph |
windgustmph |
Náraz větru | mph |
rainin |
Srážky za poslední hodinu | palce |
dailyrainin |
Denní úhrn srážek | palce |
solarradiation |
Sluneční záření | W/m² |
UV |
UV index | bezrozměrná hodnota |
action |
Typ odesílaných dat (pro aktualizaci: updateraw) |
text |
Je třeba si uvědomit jednu důležitou věc. Weather Underground historicky vychází z amerických meteorologických systémů, a proto řada parametrů používá americké jednotky. Například teplota se očekává ve stupních Fahrenheit (tempf), tlak v palcích rtuťového sloupce (baromin) a rychlost větru v mílích za hodinu (windspeedmph). Pokud tedy naše senzory měří v jednotkách SI, musíme před odesláním provést převod.
ESP32 pak může URL sestavit například takto (pro případ teploty):
float teplotaC = 23.7;
float teplotaF = teplotaC * 9.0 / 5.0 + 32.0; // prevod °C na °F
// sestaveni URL
// POZNÁMKA: Texty v uvozovkách pod sebou překladač spojí automaticky (šetří to paměť RAM).
// Operátor '+' je nutný pouze pro připojení dynamické proměnné String(teplotaF, 1).
String url =
"https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?"
"ID=IPRAHA123"
"&PASSWORD=ABCD1234"
"&dateutc=now"
"&tempf=" + String(teplotaF, 1) +
"&humidity=58"
"&action=updateraw";
Po zavolání http.GET() se data odešlou na server a během několika okamžiků se objeví v databázi služby Weather Underground.
Je zajímavé si uvědomit, že mezi naší jednoduchou ukázkou s URL
.../parametry-GET.php?teplota=23.7&vlhkost=58
a skutečným odesláním dat na Weather Underground není z hlediska principu téměř žádný rozdíl. V obou případech pouze vytvoříme URL obsahující parametry, odešleme HTTP GET požadavek a server přijaté hodnoty zpracuje. Rozdíl je pouze v tom, že zatímco náš PHP skript hodnoty vypíše na obrazovku, server Weather Underground je uloží do rozsáhlé databáze meteorologických měření a zpřístupní je dalším uživatelům.
- POZNÁMKA:
- Pokud se rozhodnete propojit vaši právě vytvořenou DIY meteostanici s některou ze služeb pro amatérské meteorology, je dobré i přes prvotní bastlířské nadšení zachovat chladnou hlavu. Ano, je krásné vidět, jak ESP32 poslušně posílá data do internetu. Není však nezbytné, aby server každou setinu sekundy dostával zprávu, že na vaší zahradě je stále stejných 23,4 °C a neprší. Stejně tak svět meteorologie pravděpodobně nečeká na desetitisíce testovacích měření s teplotou 297 °C a vlhkostí −15 %.
- Během vývoje programu je proto rozumné používat nejprve vlastní testovací skripty nebo lokální server a skutečná meteorologická data začít odesílat až ve chvíli, kdy máme vše spolehlivě odladěné. Pro běžnou amatérskou meteostanici navíc bohatě postačí odesílání dat jednou za několik desítek sekund, spíše však minut. Posílání údajů každou sekundu, nebo dokonce každou desetinu sekundy, obvykle nepřinese nic nového, zato spolehlivě zvýší zátěž serveru. Byla by škoda, kdyby podobné experimenty vedly k omezování nebo zpřísňování podmínek pro domácí meteostanice, protože právě otevřenost služeb, jako je Weather Underground, je jedním z důvodů jejich obliby mezi bastlíři a amatérskými meteorology.
- Jinými slovy: Není třeba přesvědčovat provozovatele podobných služeb o tom, že nebezpečným „meteorologickým“ jevem na Zemi nejsou bouřky ani tornáda, ale nadšení majitelé nově sestavených meteostanic z modulu ESP32. 😊
Získávání dat ze serveru ve formátu JSON
Doposud jsme pomocí HTTP komunikace data především odesílali. Velmi častým úkolem je ale také získávání dat ze vzdáleného serveru. Moderní webové služby přitom obvykle neposílají odpověď ve formě obyčejného textu nebo HTML stránky, ale ve formátu JSON (JavaScript Object Notation).
Jako příklad si ukážeme získání aktuálních meteorologických údajů ze serveru open-meteo.com. Serveru předáme souřadnice místa (Brno), které nás zajímá, a server nám vrátí odpověď ve formátu JSON obsahující mimo jiné aktuální teplotu, rychlost větru nebo oblačnost.
Typická JSON odpověď může vypadat například takto:
{
"current": {
"temperature_2m": 24.5,
"relative_humidity_2m": 78.0,
"wind_speed_10m": 8.3,
"wind_direction_10m": 135
}
}
Naším úkolem bude tuto odpověď stáhnout a z JSON struktury vyčíst požadované hodnoty.
Knihovna ArduinoJson
Pro zpracování JSON dat budeme potřebovat knihovnu ArduinoJson, kterou lze nainstalovat opět pomocí manažeru knihoven Arduino IDE. Dále používaná knihovna je od autora Benoit Blancon a v rámci její podpory je velice pěkně zdokumentována na stránce arduinojson.org.
Po instalaci knihovny můžeme vytvořit následující program. V této ukázce modul ESP32 v roli HTTP klienta odesílá požadavek typu GET na REST API služby Open-Meteo, aby získalaktuálních meteorologických dat:
#include <WiFi.h>
#include <HTTPClient.h>
#include "WI-FI-moje.h"
#include <ArduinoJson.h>
const char* ssid = "nazev wi-fi site";
const char* password = "heslo wi-fi site";
void setup() {
Serial.begin(115200);
if (!connectWiFi(ssid, password)) {
while (true);
}
HTTPClient http;
String url =
"https://api.open-meteo.com/v1/forecast"
"?latitude=49.1951"
"&longitude=16.6068"
"¤t=temperature_2m,relative_humidity_2m,surface_pressure,wind_speed_10m,wind_direction_10m";
http.begin(url);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
DynamicJsonDocument doc(2048);
deserializeJson(doc, payload);
float teplota = doc["current"]["temperature_2m"];
float vlhkost = doc["current"]["relative_humidity_2m"];
float vitr = doc["current"]["wind_speed_10m"];
int smerVetru = doc["current"]["wind_direction_10m"];
Serial.println("Aktualni pocasi:");
Serial.print("Teplota: ");
Serial.print(teplota);
Serial.println(" °C");
Serial.print("Vlhkost: ");
Serial.print(vlhkost);
Serial.println(" %");
Serial.print("Rychlost vetru: ");
Serial.print(vitr);
Serial.println(" km/h");
Serial.print("Smer vetru: ");
Serial.print(smerVetru);
Serial.println("°");
} else {
Serial.println("Nepodarilo se nacist data.");
}
http.end();
}
void loop() {
}
Jak program funguje?
Nejprve sestavíme URL adresu obsahující zeměpisnou šířku a délku sledované lokality a veličiny, které nás v dané lokalitě zajímají.
String url =
"https://api.open-meteo.com/v1/forecast"
"?latitude=49.1951"
"&longitude=16.6068"
"¤t=temperature_2m,relative_humidity_2m,surface_pressure,wind_speed_10m,wind_direction_10m";
Zde je zajímavé právě to zadání požadovaných veličin. Seznam klíčových slov pro jednotlivé veličiny se odděluje čárkou a jako celek se vkládá do jediného parametru – zde parametru current. Podobně lze načíst i data historická, nebo naopak data pro předpověď. Je třeba však místo parametru current použít jiný parametr v zadané URL – v tomto směru je třeba se ale podívat na aktuální dokumentaci serveru: open-meteo.com nebo položit vhodný dotaz některému z AI chatů, snad budou mít nastudovanou právě aktuální verzi.
V tomto případě jsme zvolili souřadnice Brna. Server následně vrátí JSON dokument se zvolenými aktuálními meteorologickými údaji.
Zatímco navázání spojení a přijetí odpovědi probíhá standardní cestou přes knihovnu HTTPClient, klíčová část zpracování spočívá v úpravě přijatého textového řetězce (proměnná payload).
String payload = http.getString();
Odpověď ze serveru ale ve skutečnosti přichází ve formátu JSON, pro jehož efektivní zpracování využijeme zmíněnou knihovnu ArduinoJson. Nejprve vytvoříme objekt DynamicJsonDocument s vyhrazenou pamětí (v našem případě 2048 bajtů)
DynamicJsonDocument doc(2048);
a pomocí funkce deserializeJson() do něj textový řetězec „naparsujeme“. Tím převedeme surový JSON text do strukturovaného stromového objektu doc.
deserializeJson(doc, payload);
Získání konkrétních hodnot je pak velmi intuitivní: přistupujeme k nim pomocí operátoru hranatých závorek kopírujícího strukturu JSONu, tedy například:
float teplota = doc["current"]["temperature_2m"];
Tím získáváme aktuální hodnotu teploty naměřenou ve dvou metrech. Následně můžeme získané údaje přímo vypisovat na sériovou linku nebo dál využívat v logice aplikace.
Na obrázku vidíme načtené aktuální hodnoty ze serveru: open-meteo.com
open-meteo.comPřestože jsme si ukázali příklad s meteorologickými daty, stejný princip se používá prakticky všude:
- burzovní kurzy,
- údaje o dopravě,
- chytré domácnosti,
- cloudové IoT platformy,
- různé REST API.
V praxi se tak mnohem častěji setkáte s tím, že ESP32 získává data ve formátu JSON a následně je zpracovává, než s tím, že by načítalo klasickou HTML stránku určenou pro zobrazení v prohlížeči.
Tímto se naše putování metodou GET v podstatě uzavírá. Začínali jsme jednoduchým ručním sestavením HTTP požadavku pomocí
třídy WiFiClient, pokračovali pohodlnější prací s knihovnou HTTPClient, ukázali jsme si předávání parametrů serveru a nakonec jsme se dostali až ke zpracování odpovědí ve formátu JSON. Právě poslední příklad je přitom velmi typický pro současné IoT aplikace. Ukazuje totiž celý řetězec komunikace:
ESP32 → HTTP GET → JSON → ArduinoJson → konkrétní hodnoty v programu.
Ať už jde o meteorologická data, kurzy měn, údaje z chytré domácnosti nebo libovolné REST API, princip bude vždy velmi podobný.
Odesílání parametrů metodou POST
Nyní se podíváme na druhou důležitou HTTP metodu, se kterou se při tvorbě webových a IoT aplikací setkáme velmi často, na metodu POST, určenou především pro odesílání dat ze zařízení na server.
V případě metody POST narazíme na jeden praktický problém. Zatímco u metody GET existuje řada veřejně dostupných služeb, které nám ochotně vracejí data, u metody POST je situace poněkud jiná. POST totiž slouží především k odesílání dat na server a jen málokterý provozovatel je ochoten umožnit komukoliv bez omezení zapisovat data do svých systémů. Taková otevřenost by totiž představovala značné bezpečnostní riziko.
Na druhou stranu už máme po předchozí kapitole poměrně dobrou představu o tom, jak HTTP komunikace funguje. Nebudeme proto znovu podrobně rozebírat vytváření spojení nebo zpracování odpovědí serveru a zaměříme se především na samotné odesílání dat. Pro všechny ukázky budou na našich stránkách připraveny jednoduché PHP skripty, které přijatá data zachytí a přehledně zobrazí. Díky tomu si budeme moci jednotlivé techniky snadno vyzkoušet a ověřit, že ESP32 skutečně odesílá přesně to, co od něj očekáváme.
Odeslání dat „formulářovým“ způsobem
Nejprve si ukážeme klasické odesílání formulářových dat, tedy stejným způsobem, jakým funguje většina běžných webových formulářů. Poté se podíváme na dnes stále důležitější přenos dat ve formátu JSON, který jsme již poznali u metody GET. Uvidíme ale, že tento formát nemusí sloužit jen pro příjem dat, ale můžeme ho využít i pro odesílání, tedy komunikaci s moderními REST API a cloudovými IoT službami.
Pro odeslání dat metodou POST jsme si opět na těchto stránkách připravili následující PHP skript, který zachytí odeslaná data a zobrazí je v odpovědi:
<?php
echo "<h2>Prijate POST parametry</h2>";
echo "jmeno: " . $_POST['jmeno'] . "<br>";
echo "teplota: " . $_POST['teplota'] . "<br>";
echo "vlhkost: " . $_POST['vlhkost'] . "<br>";
?>
Když jej porovnáme se skriptem, který jsme využívali u metody GET, vidíme, že jediný důležitý rozdíl spočívá v tom, že zde nyní používáme pole $_POST.
Program na straně modulu ESP32, který bude jako klient odesílat POST požadavky na tento skript bude následující:
#include <WiFi.h>
#include <HTTPClient.h>
#include "WI-FI-moje.h"
const char* ssid = "nazev wi-fi site";
const char* password = "heslo wi-fi site";
void setup() {
Serial.begin(115200);
if (!connectWiFi(ssid, password)) {
while (true);
}
HTTPClient http;
http.begin("http://esp32.fyzika.net/Arduino-IDE/parametry-POST.php");
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
String data =
"jmeno=ESP32"
"&teplota=23.4"
"&vlhkost=58";
int httpCode = http.POST(data);
if (httpCode > 0) {
Serial.println(http.getString());
} else {
Serial.println("Chyba komunikace.");
}
http.end();
}
void loop() {
}
Na rozdíl od předchozích příkladů zde používáme metodu POST() a tedy navíc přidáváme hlavičku Content-Type, která serveru sděluje formát dat odesílaných v těle dotazu.
Vidíme, že odezva našeho PHP skriptu je ve výsledku stejná jako při předání parametrů metodou GET:
Modul ESP32 se nyní vlastně chová jako takový HTML webový formulář – kupříkladu jako níže uvedený formulář. Můžete si zkusit jej odeslat a pak porovnat jeho odpověď s výsledkem, který se zobrazí v sériovém monitoru po spuštění programu pro modul ESP32.
<form action="http://esp32.fyzika.net/Arduino-IDE/parametry-POST.php" method="POST" target="_blank">
<input name="jmeno" value="ESP">
<input name="teplota" value="23.4">
<input name="vlhkost" value="58">
<button>Odeslat</button>
</form>
- POZNÁMKA:
- Ve skutečnosti server většinou vůbec netuší, kdo požadavek odeslal. Vidí pouze HTTP zprávu a zpracuje ji podle jejího obsahu. Právě proto mohou stejná serverová rozhraní používat webové formuláře, mobilní aplikace i mikrokontrolery ESP32.
Odesílání dat ve formátu JSON
V předchozích příkladech jsme odesílali data ve formátu připomínajícím klasické webové formuláře: jmeno=ESP
Výhodou formátu JSON je především možnost přenášet složitější datové struktury, větší přehlednost a snadnější zpracování na straně serveru.
Právě kombinace HTTP POST + JSON dnes tvoří základ komunikace většiny moderních IoT zařízení. Přesně tímto způsobem komunikují například:
- systémy chytré domácnosti,
- mobilní aplikace,
- různé cloudové služby,
- databázové servery,
- REST API.
Zatímco u formulářových dat jsme si ukázali spíše historický a velmi jednoduchý způsob komunikace, JSON POST představuje technologii, se kterou se dnes při vývoji IoT zařízení setkáte nejčastěji. Proto je dobré ji zvládnout ještě dříve, než se pustíte do komunikace s různými cloudovými službami nebo systémy chytré domácnosti.
Ukázka odeslání JSON:
Stejná data, která jsme v předchozím příkladu poslali jako formulářová, by v JSON mohla být zapsána například takto:
{
"jmeno": "ESP32",
"teplota": 23.4,
"vlhkost": 58
}
Server pak obdrží jeden JSON dokument, ve kterém jsou jednotlivé hodnoty přehledně pojmenovány.
PHP skript pro příjem JSON dat
Na rozdíl od formulářových dat se JSON neukládá do pole $_POST. Musíme jej načíst přímo z těla HTTP požadavku.
<?php
$json = file_get_contents("php://input");
echo "<h2>Prijata JSON data</h2>";
echo "<pre>";
echo htmlspecialchars($json);
echo "</pre>";
?>
Tento skript je velmi jednoduchý. Přečte celé tělo HTTP požadavku a vypíše jej do webové stránky. Díky tomu okamžitě uvidíme, co naše ESP32 na server skutečně odeslalo.
Odeslání JSON dat z ESP32
Nyní si ukážeme samotné odeslání dat.
#include <WiFi.h>
#include <HTTPClient.h>
#include "WI-FI-moje.h"
const char* ssid = "nazev wi-fi site";
const char* password = "heslo wi-fi site";
void setup() {
Serial.begin(115200);
if (!connectWiFi(ssid, password)) {
while (true);
}
HTTPClient http;
http.begin(
"http://esp32.fyzika.net/Arduino-IDE/parametry-JSON-POST.php"
);
http.addHeader(
"Content-Type",
"application/json"
);
String json =
"{"
"\"jmeno\":\"ESP32\","
"\"teplota\":23.4,"
"\"vlhkost\":58"
"}";
int httpCode = http.POST(json);
if (httpCode > 0) {
Serial.println(http.getString());
} else {
Serial.println("Chyba komunikace.");
}
http.end();
}
void loop() {
}
Nejdůležitější novinkou je hlavička:
http.addHeader(
"Content-Type",
"application/json"
);
Ta serveru sděluje, že data uložená v těle požadavku nejsou formulářové údaje, ale JSON dokument.
Samotný JSON pak předáme metodě POST():
http.POST(json);
Knihovna HTTPClient se postará o vše ostatní.
Na obrázku opět vidíme odpověď našeho připraveného PHP skriptu:
- Poznámka k obrázku:
- Výrazy
"jsou tzv. html entity, tedy náhradní HTML kódy za znaky uvozovek – tuto záměnu provedl příkazhtmlspecialchars()v našem PHP kódu. Nejde tedy o nějaké poškození našich odeslaných dat HTTP protokolem nebo metodou POST.
Vytváření JSON z proměnných
Ve skutečném programu budeme obvykle do JSON ukládat hodnoty získané ze senzorů.
- Poznámka:
- V této ukázce vytváříme JSON jako textový řetězec pomocí operátoru
+. Tento přístup je pro jednoduché příklady přehledný a zcela dostačující. Ve větších aplikacích se však obvykle používá knihovnaArduinoJson, která umožňuje JSON dokumenty vytvářet programově a bezpečněji.
float teplota = 24.7;
float vlhkost = 61.0;
String json =
"{"
"\"jmeno\":\"ESP32\","
"\"teplota\":" + String(teplota, 1) + ","
"\"vlhkost\":" + String(vlhkost, 1) +
"}";
Výsledkem může být například:
{
"jmeno":"ESP32",
"teplota":24.7,
"vlhkost":61.0
}
Závěr:
Dnešní seznámení s ESP32 v roli webového klienta končí. Ukázali jsme si navázání spojení se serverem, použití metod GET a POST, předávání parametrů, příjem odpovědí i práci s formátem JSON, který dnes tvoří základ komunikace většiny webových služeb a REST API. To jsou znalosti, které postačí pro naprostou většinu běžných IoT projektů, od jednoduchých senzorů až po komunikaci s cloudovými službami.
Všechny ukázky v tomto článku využívaly klasický protokol HTTP, protože nám umožňuje soustředit se na samotný princip komunikace bez dalších komplikací. V reálných aplikacích se však stále častěji setkáme se zabezpečenou variantou HTTPS, která přenášená data šifruje a chrání je před odposlechem nebo neoprávněnou manipulací. Dobrou zprávou je, že z pohledu programátora jsou rozdíly mezi HTTP a HTTPS v prostředí ESP32 poměrně malé. Pokud vás problematika zabezpečené komunikace zajímá, podrobně jsme se jí věnovali v samostatném článku ESP32: HTTP a HTTPS požadavek na URL.
Ať už budeme pomocí ESP32 načítat meteorologická data, komunikovat s domácí automatizací, ukládat hodnoty do databáze nebo ovládat zařízení přes internet, budeme ve většině případů používat právě techniky, které jsme si v dnešním článku nastínili. HTTP klient je totiž jedním ze základních stavebních kamenů současných IoT aplikací.