[PYTHON] Test des requêtes HTTP avec ESP-WROOM-32

Test des requêtes HTTP avec ESP-WROOM-32

Depuis qu'il est devenu possible de développer avec la construction de l'environnement ESP-WROOM-32, j'ai testé la fonction de communication.

Chose que tu veux faire

Envoyez HTTP POST depuis ESP-WROOM-32 vers le serveur Web. Le serveur Web le reçoit et le publie sur Slack pour confirmer le succès du POST.

Ce que vous avez préparé

RaspberryPi3 (utilisé comme serveur Web) Carte de développement ESP32-DevKitC ESP-WROOM-32

Site référencé

Artisanat et courses de chevaux HTTP, POST et GET bitlog

Développement côté ESP-WROOM-32

ESP-IDF a un échantillon de http_request, j'ai donc décidé de l'utiliser. Copiez la source de l'échantillon.

cd ~/esp
cp -r $IDF_PATH/examples/protocols/http_request .
cd ~/esp/http_request

Modifiez main / http_request_example_main.c.

http_request_example_main.c


/* HTTP GET Example using plain POSIX sockets

This example code is in the Public Domain (or CC0 licensed, at your option.)

Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"

/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.

If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD

#define DEFAULT_PS_MODE WIFI_PS_NONE
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;

/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const int CONNECTED_BIT = BIT0;

/* Constants that aren't configurable in menuconfig */
#define WEB_SERVER "192.168.xxx.xxx" //Voici l'IP du serveur WEB
#define WEB_PORT 80
#define WEB_URL "http://192.168.xxx.xxx" //URL ici

static const char *TAG = "test";

//Message HTTP POST
//Le corps de la demande est du texte=test
static const char *REQUEST = "POST " WEB_URL " HTTP/1.0\r\n"
							"Host: "WEB_SERVER"\r\n"
							"User-Agent: esp-idf/1.0 esp32\r\n"
							"Content-Type: application/x-www-form-urlencoded\r\n"
							"Content-Length: 9\r\n"
							"\r\n"
							"text=test\r\n"
							;


static esp_err_t event_handler(void *ctx, system_event_t *event)
{
	switch(event->event_id) {
		case SYSTEM_EVENT_STA_START:
			esp_wifi_connect();
			break;
		case SYSTEM_EVENT_STA_GOT_IP:
			xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
			break;
		case SYSTEM_EVENT_STA_DISCONNECTED:
			/* This is a workaround as ESP32 WiFi libs don't currently
			auto-reassociate. */
			esp_wifi_connect();
			xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
			break;
		default:
			break;
	}
	return ESP_OK;
}

static void initialise_wifi(void)
{
	tcpip_adapter_init();
	wifi_event_group = xEventGroupCreate();
	ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
	wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
	ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
	ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
	wifi_config_t wifi_config = {
		.sta = {
		.ssid = EXAMPLE_WIFI_SSID,
		.password = EXAMPLE_WIFI_PASS,
		},
	};
	ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
	ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
	ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
	ESP_ERROR_CHECK( esp_wifi_start() );
}

static void http_post_task(void *pvParameters)
{
	const struct addrinfo hints = {
		.ai_family = AF_INET,
		.ai_socktype = SOCK_STREAM,
	};
	struct addrinfo *res;
	struct in_addr *addr;
	int s, r;
	char recv_buf[64];

	/* Wait for the callback to set the CONNECTED_BIT in the
	event group.
	*/
	xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
	false, true, portMAX_DELAY);
	ESP_LOGI(TAG, "Connected to AP");

	int err = getaddrinfo(WEB_SERVER, "80", &hints, &res);

	if(err != 0 || res == NULL) {
		ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p", err, res);
		vTaskDelay(1000 / portTICK_PERIOD_MS);
		return;
	}

	/* Code to print the resolved IP.

	Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */
	addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
	ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", inet_ntoa(*addr));

	s = socket(res->ai_family, res->ai_socktype, 0);
	if(s < 0) {
		ESP_LOGE(TAG, "... Failed to allocate socket.");
		freeaddrinfo(res);
		vTaskDelay(1000 / portTICK_PERIOD_MS);
		return;
	}
	ESP_LOGI(TAG, "... allocated socket\r\n");

	if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
		ESP_LOGE(TAG, "... socket connect failed errno=%d", errno);
		close(s);
		freeaddrinfo(res);
		vTaskDelay(4000 / portTICK_PERIOD_MS);
		return;
	}

	ESP_LOGI(TAG, "... connected");
	freeaddrinfo(res);

	//Envoyez un message HTTP ici
	if (write(s, REQUEST, strlen(REQUEST)) < 0) {
		ESP_LOGE(TAG, "... socket send failed");
		close(s);
		vTaskDelay(4000 / portTICK_PERIOD_MS);
		return;
	}
	ESP_LOGI(TAG, "... socket send success");

	/* Read HTTP response */
	do {
		bzero(recv_buf, sizeof(recv_buf));
		r = read(s, recv_buf, sizeof(recv_buf)-1);
		for(int i = 0; i < r; i++) {
			putchar(recv_buf[i]);
		}
	} while(r > 0);

	ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d\r\n", r, errno);
	close(s);

	ESP_LOGI(TAG, "esp_wifi_set_ps().");
	esp_wifi_set_ps(DEFAULT_PS_MODE);

	while(1);
}

void app_main()
{
	ESP_ERROR_CHECK( nvs_flash_init() );
	initialise_wifi();
	xTaskCreate(&http_post_task, "http_post_task", 4096, NULL, 5, NULL);
}

Ceci termine le programme de test sur l'ESP-WROOM-32.

Développement côté Raspberry Pi

Puisque RaspberryPi est utilisé comme serveur Web, installez Apache2, etc. selon vos besoins. Ici, les détails de la construction du serveur Web sont omis. Décrivez le traitement de la réponse de la requête HTTP en PHP côté serveur.

index.php


<?php
function func_esp(){
	exec("python3 /home/pi/python_code/slack_esp.py");
	return 'test';
}

if($_POST['text'] == "test"):
	func_esp();
endif;
?>

Si text = test est détecté dans la requête POST Exécutez un script Python.

Ensuite, créez un script python à publier sur Slack. J'utilise Slacker.

slack_esp.py


import sys
from slacker import Slacker

token = "xxxx-xxxx-xxxxxxxx"
slacker = Slacker(token)
channel_name = "#" + "general"

message = 'esp32 test\n'

slacker.chat.post_message(channel_name, message)

Si le HTTP POST réussit, vous recevrez le message "test esp32". Ceci termine la création du programme côté Raspberry Pi.

tester

Écrivez et exécutez le programme dans ESP-WROOM-32.

cd ~/esp/http_request
make flash

Informez votre iPhone ici! IMG_0845.png Le test a réussi.

Recommended Posts

Test des requêtes HTTP avec ESP-WROOM-32
Tester Elasticsearch avec python-tcptest
Communication HTTP avec Python
Réessayer avec des requêtes python
Automatisez les tests python avec CircleCI
Pré-essayez les tests locaux avec Travis
Serveur HTTP facile avec Python
Tester avec des nombres aléatoires en Python
Automatisez les tests d'applications pour smartphone avec Appium-Python Edition
Présentation du shell MicroPython (Mac) avec ESP-WROOM-02
[Python] Fichiers wav POST avec requêtes [POST]
Essayez l'invite http avec un accès http interactif
Obtenez la météo avec les requêtes Python
Obtenez la météo avec les requêtes Python 2
Tests faciles d'AWS S3 avec MinIO
Envoyer des données multipart / form avec des requêtes python
Automatisez les tests d'applications Windows avec Windows Application Driver-Python Edition