Picoweb
Picoweb est un microframework : picoweb, façon bottlepy ou flask.. :
Liens utiles
- https://icircuit.net/make-esp32-http-webserver-using-micropython/2152
- < https://github.com/pfalcon/picoweb>
- https://www.dfrobot.com/blog-934.html
- https://www.dfrobot.com/blog-742.html
Ce framework permet de créer des routes à la façon de Bottlepy par exemple.
https://github.com/pfalcon/picoweb
Pré-requis
Etre connecté au réseau wifi pour avoir accès au web :
>>> import network
>>> wifi=network.WLAN(network.STA_IF)
>>> wifi.active(True)
True
>>> wifi.connect("ssid","password")
>>> wifi.isconnected()
True
Ceci peut aussi être automatisé dans un boot.py
Installation
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.
On fait l'installation à l'aide de pip depuis le micropython !
>>> import upip as pip
>>> pip.install("picoweb")
Installing to: /lib/
Warning: micropython.org SSL certificate is not validated
Installing picoweb 1.8.2 from https://files.pythonhosted.org/packages/c2/22/a1eb0cf52b72e818fe47acadaf8ade200d7c0c7c6fc5acc7b47f53f2a338/picoweb-1.8.2.tar.gz
Installing pycopy-uasyncio 3.7 from https://files.pythonhosted.org/packages/e5/58/80b8b403c52ea88d44844570dbe487d7a4b3045ae0ecad0c9f4dbac0d104/pycopy-uasyncio-3.7.tar.gz
Installing pycopy-pkg_resources 0.2.1 from https://files.pythonhosted.org/packages/05/4a/5481a3225d43195361695645d78f4439527278088c0822fadaaf2e93378c/pycopy-pkg_resources-0.2.1.tar.gz
Installing pycopy-uasyncio.core 2.3.2 from https://files.pythonhosted.org/packages/ca/b2/c5bba0bde7022b6d927a6144c026d7bf310d3f8a20e031571fbf1a08a433/pycopy-uasyncio.core-2.3.2.tar.gz
>>>
Enorme !
Perso, je trouve çà "énorme" de pouvoir aussi facilement installer un truc sur l'ESP à partir de micropython !
Application de test
Ici, une simple webapp de test où on explore les possibilités, notamment d'utiliser du fichier statique... et çà fonctionne !
import network
import picoweb
wifi = network.WLAN(network.STA_IF)
if not wifi.isconnected():
print('connecting to network...')
wifi.active(True)
wifi.connect("DWR-921-6E38","12345678910")
while not wifi.isconnected():
pass
print('network config:', wifi.ifconfig())
ipadd=wifi.ifconfig()
app = picoweb.WebApp(__name__)
@app.route("/")
def index(req, resp):
print(req.method) # info sur la methode requete GET ou POST
yield from picoweb.start_response(resp)
yield from resp.awrite("Hello !")
yield from resp.awrite("Or my <a href='file'>file</a>.")
# lien renvoie vers une route dediee
yield from resp.awrite("Or my <a href='boot.py'>file py</a>.")
yield from resp.awrite("Or my <a href='smoothie.js'>file js</a>.")
yield from resp.awrite("Or my <a href='html'>page html</a>.")
@app.route("/file")
def static_file(req, resp):
yield from app.sendfile(resp, "boot.py")
@app.route("/boot.py")
def static_file(req, resp):
yield from app.sendfile(resp, "boot.py")
@app.route("/smoothie.js")
def static_file(req, resp):
yield from app.sendfile(resp, "smoothie.js")
@app.route("/html")
def page_html(req, resp):
page=b"""
<!DOCTYPE HTML>
<!-- Debut de la page HTML -->
<html>
<head> <!-- Debut entete -->
<meta charset="utf-8" /> <!-- Encodage de la page -->
<title>JavaScript: Test librairie Smoothie</title> <!-- Titre de la page -->
<!-- Inclusion librairies / codes Javascript externes -->
<script src="smoothie.js" type="text/javascript" ></script>
<!-- Debut du code Javascript -->
<script language="javascript" type="text/javascript">
// variables globales
//var elem; // variable globale élément du DOM
var randomSerie = new TimeSeries(); // crée un objet série de date - fournit par lib smoothie
var smoothieGraph = new SmoothieChart({millisPerPixel:50}); // crée un objet graphique smoothie - fournit par lib smoothie
window.onload = function () { // au chargement de la page
// acces aux éléments du DOM
//elem=document.getElementById("myElem");
// définition de la gestion des évènements du DOM
//elem.setAttribute('onchange', 'fonction()'); // appel la fonction voulue lors de l'évènement-façon HTML
// code a exécuter au chargement de la page
// initialisation du graphique smoothie
smoothieGraph.addTimeSeries(randomSerie, { strokeStyle: 'rgba(0, 255, 0, 1)', fillStyle: 'rgba(0, 255, 0, 0.2)', lineWidth: 2 });
smoothieGraph.streamTo(document.getElementById("smoothieCanvas"), 1000); // définition canva et vitesse défilement
setInterval(function() { refreshSmoothieGraph()}, 500); // fixe délai actualisation
// le résultat final est le fruit du mixage entre vitesse de défilement et délai actualisation valeur
} // fin onload
// fonctions de gestion des évènement du DOM
function fonction(){
} // fin fonction
// autres fonctions
// fonction d'actualisation de la série de valeur à intervalle régulier
function refreshSmoothieGraph(){
randomSerie.append(new Date().getTime(), Math.random() * 4096); // ajoute donnée à la série de données - ici aléatoire
} // fin refresh smootthie
</script> <!-- Fin du code Javascript -->
</head> <!-- Fin entete -->
<body > <!-- Debut Corps de page HTML -->
<!-- === placer ici le code HTML de la page === -->
<canvas id="smoothieCanvas" width="600" height="300"></canvas> <!-- canvas pour graphique smoothie -->
</body> <!-- Fin de corps de page HTML -->
</html> <!-- Fin de la page HTML -->
"""
yield from picoweb.start_response(resp)
yield from resp.awrite(page)
app.run(debug=-1, port=8000, host =ipadd[0]) # debug -1 pour eviter probleme ulogging
Doc minimale
run( host="127.0.0.1", port=8081, debug=False, lazy_init=False, log=None)
- mettre debug=-1 pour ne pas avoir message erreur avec ulogging
- port par défaut est 8081... fixé ce que l'on veut.
Pour l'analyse de la requete, voir ici :
Autour de senfile
COntent Type : https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Content-Type
Mime Type : https://developer.mozilla.org/fr/docs/Web/HTTP/Basics_of_HTTP/MIME_types
Note : gérer le chargement des librairies :
https://aaronsmith.online/easily-load-an-external-script-using-javascript/ https://webexplorar.com/jquery-check-page-is-fully-loaded-or-not/
Compléments potentiellement utiles
Un tuto pas mal ici : https://itywik.org/2018/10/30/eight-micropython-python-experiments-for-the-esp32/
Il est possible d'utiliser des versions compressées de librairies qui seront décompressés par le navigateur : https://www.alsacreations.com/article/lire/914-compression-pages-html-css-gzip-deflate.html
Ici par exemple, dans le cas de jquery, l'utilisation de minifié + gzipped fait passer une lib de 255Ko à 29Ko... à tester du coup ! https://mathiasbynens.be/demo/jquery-size
Dans le cas précis de Brython, il est aussi possible de mémoire de "compiler" en JS non ?
Test de Brython sur l'ESP
Création d'un répertoire static pour y placer :
- brython.js : attention le fichier est gros (700Ko et la copie prend un peu de temps) Une autre option serait de la mettre sur un serveur commun sur le réseau local, un Pi.
- les libs éventuelles
Trop lourd pour l'ESP
Par contre, bien que fonctionnelle, clairement, cette façon de faire est trop lourde pour l'ESP : çà met plusieurs 10aine de secondes à transférer le fichier brython.js... et on n'a pas la lib standard.
Donc, à minima, préférer un accès web : Et si on veut isoler le réseau, mettre un Pi avec fichier de serveur statique, voire même le poste depuis lequel on accède.
A noter que l'adresse à utiliser dans le index.html sera celle sur laquelle on accède au brython.js avec le navigateur. Le plus simple est de la tester en manuel pour éviter les gags...
Création d'un répertoire app pour y placer :
- index.html
- scriptBrython.py
Serveur picoweb qui a routes :
- /app/index.html
- /app/scriptBrython.py
- /static/brython.js
Test Ajax
cf essai Brython
Ou bien avec Jquery.
Cf dans ce cas les alternatives légères à jquery d'une part. https://www.technotification.com/2019/06/5-lightweight-jquery-alternatives-2019.html
Autour jQuery :
https://raygun.com/blog/jquery-is-undefined/ https://stackoverflow.com/questions/1956719/jquery-get-is-not-a-function https://www.pierre-giraud.com/jquery-apprendre-cours/creation-requete-ajax/
Test websocket
Libs websockets en Micropython :
Au passage découverte d'un autre projet de webserver : https://github.com/jczic/MicroWebSrv2
Un projet intéressant ici utilisant MicroWebserver et websocket : https://www.rototron.info/raspberry-pi-esp32-micropython-websockets-tutorial/ https://www.rototron.info/raspberry-pi-esp32-micropython-websockets-tutorial/