ESP32でHTTPClientを使ってウェブサーバーにGET、POSTするやり方

はじめに
ESP32でウェブサーバーにHTTPリクエストをするやり方をご紹介します。HTTPClientを使うと簡単にGET、POSTできますよ。SSLを使ったHTTPSでも可能ですが、ここではもっとも簡単なHTTP通信での方法をご紹介いたします。
開発環境
この記事の執筆時では、次の開発環境でプログラムを実行テストしました。
項目 | 値 |
---|---|
Arduino | ESP32-DevKitC |
IDE | Platform IO |
ファームウェア | arduino-esp32#2.0.2 |
HTTPClient | ver 2.0.0 |
ダミーサーバーの用意
ESP32でHTTPリクエストのテストを行う場合は、ダミーサーバーを用意しておくと便利です。Pythonで簡単に立ち上げることができます。必要ない場合は読み飛ばしてください。
パソコン内の適当な場所に、次のような構成でファイルを用意します。
.
├── dummy_root
│ └── status.json
└── dummy_server.py
dummy_server.py
の内容は次のとおりです。
from http.server import HTTPServer, BaseHTTPRequestHandler
import os
import re
import logging
import socket
= socket.gethostbyname_ex(socket.gethostname())
host_list = host_list[2][1]
lan_address
= os.path.dirname(__file__)
dirname = "0.0.0.0"
server_ip = 9998
server_port
= "http://{}:{:d}".format(lan_address, server_port)
lan_url = "http://{}:{:d}".format(server_ip, server_port)
url
+ "/dummy_root/")
os.chdir(dirname
def load_file(path):
with open(path, mode='r') as f:
= f.read()
s return s.encode('utf-8')
class S(BaseHTTPRequestHandler):
def do_GET(self):
# logging.info("GET request,\nPath: %s\nHeaders:\n%s\n", str(self.path), str(self.headers))
= re.match(r'^/status$', self.path)
m if m != None:
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(load_file("status.json"))
def do_POST(self):
print('======================= POST =======================');
print(self.path)
= re.match(r'^/data$', self.path)
m if m != None:
# {"device_name": "esp32", "temperature": 21.6}
= int(self.headers['Content-Length']) # <--- Gets the size of data
content_length = self.rfile.read(content_length) # <--- Gets the data itself
post_data print('======================= HTTP Request =======================');
"POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n",
logging.info(str(self.path), str(self.headers), post_data.decode('utf-8'))
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write('{"status":"ok"}'.encode('utf-8'))
def web_server():
=logging.INFO)
logging.basicConfig(level
= HTTPServer(('', server_port), S)
httpd
'Starting httpd...\n')
logging.info(
httpd.serve_forever()
if __name__ == "__main__":
print(lan_url)
print(url)
web_server()# t = threading.Thread(target = web_server)
# t.start()
# cmd = 'open {}'.format(url)
# print(cmd)
# os.system(cmd)
status.json
の内容は次のとおりです。
{
"TIMESTAMP": "2022-10-30T04:07:00",
"STATUS": 1
}
GETでHTTPリクエストしたい
ESP32でGETリクエストを使う用途としましては、サーバー上に何らかのステータス状態を置いておき、ESP32からアクセスして確認させることでESP32の動作をコントロールするといった使い方ができます。AWSのIoT Coreで言うところのシャドウのような使い方ですね。AWSではMQTTプロトコルで通信しますが、ちょっとした用途でしたらHTTPリクエストで十分です。
次はESP32からウェブサーバーにGETのHTTPリクエストを送信するプログラム例です。
#include <HTTPClient.h>
#include <WiFi.h>
#include "Arduino.h"
#ifndef WIFI_SSID
#define WIFI_SSID "xxxxx" // WiFi SSID (2.4GHz only)
#endif
#ifndef WIFI_PASSWORD
#define WIFI_PASSWORD "xxxxx" // WiFiパスワード
#endif
= "http://192.168.61.5:9998/status";
String url
void setup() {
.begin(115200);
Serial
.mode(WIFI_STA);
WiFi(500);
delay.begin(WIFI_SSID, WIFI_PASSWORD);
WiFi}
void loop() {
;
WiFiClient client;
HTTPClient http
if (!http.begin(client, url)) {
.println("Failed HTTPClient begin!");
Serialreturn;
}
.println("HTTPClient begin!");
Serial.addHeader("Content-Type", "application/json");
httpint responseCode = http.GET();
= http.getString();
String body .println(responseCode);
Serial.println(body);
Serial
.end();
http
(5000);
delay}
簡単ですね! setup()
でWiFiクライアントを立ち上げておきます。 loop()
内で HttpClient
に WiFiClient
をつっこみ、GETでHTTPリクエストします。
responseCode
には、HTTPリクエストのレスポンスコードが格納されてます。200
や 404
エラーなどです。
HTTPリクエストで返された本文の内容は getString()
で取得できます。内容がjsonであれば、そのままjsonの文字列が
String
型で返されます。
ESP32でJSONをパースすにはjson11を使うと便利です。
POSTでHTTPリクエストしたい
ESP32にセンサを取り付けてそのデータをウェブサーバーに投げて記録したいことは多いですよね。
次はESP32からウェブサーバーにPOSTのHTTPリクエストを送信するプログラム例です。
#include <HTTPClient.h>
#include <WiFi.h>
#include "Arduino.h"
#ifndef WIFI_SSID
#define WIFI_SSID "xxxxx" // WiFi SSID (2.4GHz only)
#endif
#ifndef WIFI_PASSWORD
#define WIFI_PASSWORD "xxxxx" // WiFiパスワード
#endif
= "http://192.168.61.5:9998/data";
String url
void setup() {
.begin(115200);
Serial
.mode(WIFI_STA);
WiFi(500);
delay.begin(WIFI_SSID, WIFI_PASSWORD);
WiFi}
void loop() {
;
WiFiClient client;
HTTPClient http= R"({"device_name": "esp32", "temperature": 21.6})";
String json
if (!http.begin(client, url)) {
.println("Failed HTTPClient begin!");
Serialreturn;
}
.println(json);
Serial.addHeader("Content-Type", "application/json");
httpint responseCode = http.POST(json);
= http.getString();
String body
.println(responseCode);
Serial.println(body);
Serial
.end();
http
(5000);
delay}
GETとほぼ同じなので説明はいいでしょう。POSTで投げたいデータは
http.POST(データ内容)
で指定します。
この記事の最初にご紹介したダミーサーバーをお使いになれば、次のようなHTTPリクエストが確認できるはずです。
INFO:root:POST request,
Path: /data
Headers:
Host: 192.168.61.5:9998
User-Agent: ESP32HTTPClient
Connection: keep-alive
Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0
Content-Type: application/json
Content-Length: 44
Body:
{"device_name": "esp32", "temperature": 21.6}
関連記事
- ESP32でWiFi接続を簡単にする「WiFiHelper」ライブラリ開発のリリースノート
- curl|シェル
- たった数行で作るWebサーバー【Python x HTTPServer】
- ESP32でLチカするまでの設定
- ESP32でHTTPSアクセス、ただし証明書検証なし