Test de serveur simple

L'intérêt majeur de l'ESP est de pouvoir créer des petits serveurs simples. Donc ici, on explore la possibilité de faire çà.

Une très bonne source : https://microcontrollerslab.com/esp32-esp8266-micropython-web-server/

Ce qu'il faut savoir :

Le module ESP a 2 modes possibles :

  • soit comme un poste sur le réseau wifi
  • soit comme un point wifi à lui-tout seul.

Débrouillage dans l'interpréteur

>>> ## initialisation connexion 
>>> import socket
>>> import network
>>> wifi=network.WLAN(network.STA_IF)
>>> wifi.active()
False
>>> wifi.connect("dlink","")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: Wifi Unknown Error 0x0005
>>> wifi.active(True)
True
>>> wifi.connect("dlink","")
>>> wifi.isconnected()
True
>>> ## le serveur
>>> from machine import Timer
>>> timer=Timer(0)
>>> page="""Hello world !""")
Traceback (most recent call last):
  File "<stdin>", line 1
SyntaxError: invalid syntax
>>> page="""Hello world !"""
>>> s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.bind(('',80))# port
Traceback (most recent call last):
  File "<stdin>", line 2
SyntaxError: invalid syntax
>>> s.bind('',80)# port
Traceback (most recent call last):
  File "<stdin>", line 2
SyntaxError: invalid syntax
>>> s.bind(("",80))
>>> s.listen(5) # max connection
Traceback (most recent call last):
  File "<stdin>", line 2
SyntaxError: invalid syntax
>>> s.listen(5) 
>>> def loop(timer):
    conn,addr=s.accept()
    conn.settimeout(3.0)
    request=conn.recv(1024)
    conn.settimeout(None)
    request=str(request)
    print(request)
    response=page
    conn.send('HTTP/1.1 200 OK\n')
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')
    conn.sendall(response)
    conn.close()

>>> while True:
    loop()

Ensuite se connecter sur l'ip de l'ESP 32, sur le port sépcifié :

192.168.4.100:80

On obtient la page et dans le terminal on a la réponse qui apparaît à chaque requete.

b'GET / HTTP/1.1\r\nHost: 192.168.4.100\r\nUser-Agent: Mozilla/5.0 (X11; Linux i686; rv:78.0) Gecko/20100101 Firefox/78.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\nAccept-Language: fr,en-US;q=0.7,en;q=0.3\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nSec-GPC: 1\r\n\r\n'

Rendre le choses plus définitives

Pour rendre les choses plus définitives, on crée 2 fichier :

  • un boot.py qui va contenir la partie activation de la connexion
  • un main.py qui va gérer la partie serveur à proprement parler

Questions

Est-il possible ou facile de servir des fichiers statiques et donc librairie *.js avec ESP 32 ?

Un microframework : picoweb, façon bottlepy ou flask.. :

Ce framework permet de créer des routes à la façon de Bottlepy par exemple.
https://github.com/pfalcon/picoweb

https://www.cnx-software.com/2017/10/16/esp32-micropython-tutorials/

Note : l'installation va nécessiter que l'ESP ait accès au Web au moins pour l'installation. picoweb permet aussi l'utilisation de template ce qui à priori est intéressant.

Si on veut servir des librairies js, etc... on peut :

  • les intégrer directement dans le code de la page que l'on envoie si elles ne sont pas trop grosses, ce qui est le cas de la majorité des libs js, notamment a format "minifié"
  • les ouvrir à partir fichiers locaux sur la Flash de l'ESP ( on a 2 Mo de dispo, ce qui laisse quand même de la marge) selon route prédéfinie avec picoweb
  • les ouvrir de façon similaire depuis une carte SD si besoin de plus... os
  • utiliser un serveur local, un pi par exemple, qui va fournir les lib pour tous les esp présents sur le réseau. C'est une bonne alternatives
  • on peut aussi imaginer que le poste depuis lequel on accède aux ESP serve les libs utiles
  • et bien sûr, que le réseau ait accès au web, auquel cas, les libs sont dispos

Ce qui est très tentant ici c'est d'utiliser Brython pour le client et faire des pages très propres...

Tester aussi ajax, ce que devrait à priori permettre facilement picoweb via les routes.

Et aussi

Un autre projet de serveur Micropython qui supporte Ajax et websocket : https://github.com/jczic/MicroWebSrv2

Gérer les requetes avec les sockets

Le microframework, c'est bien, mais çà peut poser des problèmes, ne pas être ultra rapide, et par conséquent, çà peut être bien d'utiliser les sockets et gérer directement les requêtes reçues, etc.

A la mano

Probablement encore le plus efficace :

Voici une requête GET type :

GET / HTTP/1.1
Host: 192.168.0.52:8080
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: fr,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-GPC: 1

Là, ce qu'on veut c'est extraire ce qu'il y a derrière le GET, le / et le texte qui suit.

Une façon simple consiste à faire :

Avec un module ?

Pour se simplifier la vie, on a un module disponible, 'urllib.parse'

Installation (le wifi étant actif sur l'ESP)

import upip as pip
pip.install("urllib.parse")

https://pypi.org/project/micropython-urllib.parse/

Ne fonctionne pas pour moi

Problèmes de mémoire

https://stackoverflow.com/questions/62550514/how-to-resolve-memoryerror-memory-allocation-failed-with-micropython

import micropython
micropython.alloc_emergency_exception_buf(100)

Voir : https://docs.micropython.org/en/latest/library/micropython.html?highlight=module%20micropython#micropython.alloc_emergency_exception_buf A mettre au début du code.

Lib alternative à jQuery pour Ajax call ?

j'utilise / ai besoin de jQuery essentiellement pour simplifier l'appel Ajax... mais si on peut faire autrement, alors, j'en n'ai plus besoin et on peut faire des petits serveurs ESP entièrement "embarqué" et donc en hotspot ce qui peut être particulièrement pratique. Il suffit de se connecter sur l'ESP pour contrôler, avoir les datat, etc..

Très bonne page ici : https://dzone.com/articles/top-javascript-libraries-for-making-ajax-calls

Fetch a l'air de ne même pas nécessiter de lib...

Librairie js intéressantes dans un contexte de microwebserveur embarqué ?

Alpine.js : une lib de 6.4 (minified + gzipped) qui permet de coder "inside the html" et qui permet la capture d'évènement, l'interaction avec les éléments eux-mêmes, etc.