O REST API sztuczna inteligencja napisała tak: “REST API (Representational State Transfer Application Programming Interface) to styl architektury sieciowej oraz zestaw reguł, które pozwalają na tworzenie interfejsów programowania aplikacji, umożliwiających komunikację między różnymi systemami lub usługami internetowymi. REST API umożliwia klientom na zapytanie serwera o dane lub na wykonanie akcji poprzez standardowe protokoły internetowe, takie jak HTTP i protokół SSL/TLS, zazwyczaj zwracając dane w formacie JSON lub XML. REST API jest często stosowany w aplikacjach internetowych, takich jak sklepy internetowe, media społecznościowe, systemy płatności online, a także w aplikacjach mobilnych.“
Poniżej kod napisany w Arduino, którym płytka ESP32 kontaktuje się z serwerem napisanym w pythonie z użyciem modułu flask. Musiałem użyć Arduino, zamiast prostszego Micropython, bo jak dotąd brak dobrej biblioteki dla mojego wyświetlacza e-Paper 4.2″ w tym języku.
Arduino IDE, ESP32 klient
/*
* Arduino IDE, ESP32 klient
*/
#include <WiFi.h>
const char* ssid = "******";
const char* password = "*******";
const char* host = "*******"; // wpisz adres serwera z którym się łączysz na przykład "192.168.1.23"
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);
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()
{
delay(20000);
++value;
Serial.print("connecting to ");
Serial.println(host);
// Use WiFiClient class to create TCP connections
WiFiClient client;
const int httpPort = ****; // wpisać numer portu serwera z którym się komunikujemy
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
String url = "/epd"; // ścieżka do strony. jeśli kierujemy na główną piszemy "/"
Serial.print("Requesting URL: ");
Serial.println(url);
// This will send the request to the server
client.print(String("POST ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
// Read all the lines of the reply from server and print them to Serial
while(client.available()) {
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");
}
Drugi przykład, tym razem ESP8266 z Arduino. Zamiast języka MicroPython użyłem Arduino, ponieważ miałem problem z komunikacją między czujnikiem balkonowym działającym w oparciu o procesor ATmega328 i moduł radiowy nrf24L01, a esp8266 na MicroPythonie, który odbierałby dane i przekazywał do serwera. Za diabła nie chciały się widzieć. Poniżej kod wysyłający JSON do serwera oparty o bibliotekę ESP8266HTTPClient.h
. Część odpowiadającą za nRF24 i tworzenie obiektu JSON pominąłem. Zwróćcie uwagę, że zastosowałem metodę POST, która pozwala wysyłać dane na serwer w dyskretny sposób.
Arduino IDE, ESP8266 HTTP klient —> flask serwer
/**
PostHTTPClient.ino
Created on: 21.11.2016
https://www.bot-thoughts.com/2021/11/make-esp8266-wifi-temperature-sensor.html
*/
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#define SERVER_IP "192.168.1.104:8080" // adres mojego lokalnego serwera flask
#ifndef STASSID
#define STASSID "*******"
#define STAPSK "********"
#endif
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
Serial.println();
WiFi.begin(STASSID, STAPSK);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
// wait for WiFi connection
if ((WiFi.status() == WL_CONNECTED)) {
WiFiClient client;
HTTPClient http;
Serial.print("[HTTP] begin...\n");
// configure traged server and url
http.begin(client, "http://" SERVER_IP "/balkon"); // HTTP
http.addHeader("Content-Type", "application/json");
Serial.print("[HTTP] POST...\n");
// start connection and send HTTP header and body
int httpCode = http.POST("{\"temp\":\"22.30\", \"humi\":\"55\"}");
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] POST... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK) {
const String& payload = http.getString();
Serial.println("received payload:\n<<");
Serial.println(payload);
Serial.println(">>");
}
} else {
Serial.printf("[HTTP] POST... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
delay(10000);
}
Serwer flask, kod:
Sztuczna inteligencja o flask-u pisze tak: “Flask to lekki i minimalistyczny framework dla języka Python, który umożliwia tworzenie aplikacji webowych i API z łatwością i szybkością. Flask dostarcza wiele wbudowanych funkcjonalności, takich jak routing, obsługa formularzy, autoryzacja, obsługa baz danych oraz wsparcie dla różnych rozszerzeń. Dzięki swojej prostocie i elastyczności, Flask jest bardzo popularnym narzędziem w świecie programowania webowego.”
Poniżej kod najprostszego serwera flask. U mnie działa nawet na starym Mac-u z 2009 roku. Oczywiście żeby współdziałał z ESP32 i kodem zapisanym wyżej należałoby dodać @app.route('/epd', methods=['POST'])
z funkcją coś zwracającą.
# Podziękowania dla twórców za filmy na YouTube:
# https://youtu.be/9sG0xjGwIMM
# https://www.youtube.com/watch?v=zT8FrCVjKjU&t=8s
from flask import Flask, jsonify, render_template, request
app = Flask(__name__)
@app.route('/balkon', methods=['GET', 'POST'])
def balkon():
if request.method == 'GET':
return jsonify('witaj na stronie!')
else:
data = request.get_json()
print(data)
return jsonify('flask pozdrawia!')
@app.route('/epd', methods=['GET', 'POST'])
def epd():
print("EPD")
temp = 3.20
time_stamp = '12:30'
hum = 55
return jsonify(f'Temp. {temp} st.C, Wilgotnosc {hum} %, Czas {time_stamp}')
if __name__ == '__main__':
app.run(host='192.168.1.104', port=8080, debug=True)