[PARTAGE] micropython installation esp8266 esp32 et dialogue jeedom sans plugin

Tutoriel Partie 1

Partie 1, Installation de MicroPython dans un ESP

MicroPyton c’est quoi c’est un langage issu de Python adapté aux micro-contrôleurs.
En savoir plus : MicroPython — Wikipédia https://micropython.org/

Pour mettre tout le monde sur un pied d’égalité et comme jeedom fonctionne sur une base débian ou raspian.

Vu que certains n’utilisent pas d’interface graphique nous utiliserons des outils simple et en ligne de commande. Donc pas de windows ni de mac … bien que de nombreux utilitaires existent sous ces OS.

La première des chose à faire est de télécharger le microcode à installer en fonction du microcontrôleur, nous ne traiterons ici que les ESP 32 et 8266.

Rendez-vous :
Pour les esp8266 ici : MicroPython - Python for microcontrollers
Pour les esp32 ici : MicroPython - Python for microcontrollers

Choisir le firmware correspondant à vos besoin et ou à la taille mémoire de votre contrôleur.

Transfer du micro-code ( le fichier.bin ) dans votre ESP
Nous allons devoir utiliser un utilitaire → esptool.

Connectez-vous en console et entrez la ligne suivante :

pip3 install esptool

il faut maintenant utiliser esptool pour effacer l’ESP injecter le code binaire.

Après avoir connecté votre ESP sur un port USB

Repérez ou se trouve votre ESP avec la commande :

ls /dev/ttyUSB*

exemple :

pi@covid:~$ ls /dev/ttyUSB*
/dev/ttyUSB0

ici le port de communication est /dev/tty/USB0

Effacer et programmer un ESP 8266 :

sudo esptool.py --port /dev/ttyUSB0 erase_flash

sudo esptool.py --port /dev/tty/USB0 --baud 460800 write_flash --flash_size=detect 0 esp8266-version_téléchargé.bin

Effacer et programmer un ESP32

sudo esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash

sudo esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 esp32-version_téléchargé.bin

Si tout s’est bien passé …
A l’aide de la console et de la commande screen verifions avec la commande suivante :

screen /dev/ttyUSB0 115200

ecran noir normal
appuyez sur entrée

>>>

Ho un prompt MicroPython.
Appuyez sur le bouton reset du microcontrôleur.

MicroPython v1.12 on 2019-12-20; ESP module with ESP8266
Type "help()" for more information.
>>> 
>>> print(2+2)

Ah oui ça fait bien 4 !

Voilà fin de la première partie, Nous sommes prêt à faire du MicroPython

4 « J'aime »

Tutoriel partie 2

Connexion au réseau WiFi
Programmation à distance avec webrepl (interface web)

Bien que ce ne soit pas indispensable, il est intéressant de pouvoir programmer à distance ses ESP. Ceci peut être fait grâce à un utilitaire WEBREPL.
référence : 2. Getting a MicroPython REPL prompt — MicroPython latest documentation

La premiere chose à faire est d’initialiser votre ESP avec un mot de passe pour le réseau.

voici comment ca se passe :

>>> import webrepl_setup
import webrepl_setup

WebREPL daemon auto-start status: enabled

Would you like to (E)nable or (D)isable it running on boot?
(Empty line to quit)
> E
Would you like to change WebREPL password? (y/n) y
New password (4-9 chars): 423651
Confirm password: 423651
No further action required
>>> 

N’oubliez pas votre mot de passe nous en aurons besoin plus tard.
Ceci n’est à faire qu’une fois.

Passons aux choses sérieuses … Activation du WiFi en mode client
(oui il y a aussi un mode serveur qui permet à votre ESP devenir un point d’accés WiFi, nous en parleront plus tard)

>>> import network
>>> # activation des fonctions réseau
>>> network.WLAN(network.STA_IF).active(1)
>>> # activatiation de la couche client wifi
>>> network.WLAN(network.STA_IF).connect('Mon_SSDI', 'le_Mot_passe_de mon_réseau_wifi')
>>> # caracteristiques de connexion a mon réseau WiFi
>>> network.WLAN(network.STA_IF).ifconfig()[0]
>>> #vérification de l'adresse IP

Voilà notre ESP est prêt à dialogué en WiFi sur notre réseau local.
Pour des raisons évitentes il serait bien d’attribuer une adresse statique dans votre routeur à cet ESP (je vous laisse faire car chaque box a ses méthodes.)
Il est évident que nous n’allons pas faire ça à chaques fois mais regrouper ces ligne dans un fichier pour que ceci puisse être executé à chaque démarrage.

Justement comment ça fonctionne …

Au démarrage après l’initialisation votre ESP va lire des fichiers de type texte que vous aurez écrit et transféré dans votre micro-controleur.
2 fichiers (boot.py et main.py) sont appelés au départ qui eux-même peuvent en appeler d’autres.
Il existe au moins 2 méthodes de transfert, par la ligne USB, par internet.
-------------------Méthode USB---------------------------------------
Par des lignes de commande en console a l’aide de AMPY
Installation de AMPY suivre la ou les lignes de commande ici :

Une fois installé les commandes sont assez simples.
Exportez votre configuration avec ces 3 lignes en console.

export AMPY_PORT=/dev/ttyUSB0
export AMPY_BAUD=115200
export AMPY_DELAY=2

Après cela les commandes sont plus simple :

Liste des fichiers présent sur votre ESP

ampy ls

Envoyer un fichier dans votre ESP

ampy put votre_fichier.py

Recevoir un fichier présent sur votre machine

ampy get nomdufichieresp.py > nomdufichiersurvotremachine.py

-------------------Méthode INTERNET ------------------------------
Nous y voilà un peu d’interface graphique par l’intermédiaire de votre navigateur…
WEBREPL rendez-vous sur le github :

Je vous conseille de faire ‹ clone or download ›
et d’installer en local cet utilitaire.
Une fois fait ouvrez dans le dossier webrepl-master la page html :
webrepl.html.
Dans votre navigateur,
vous devriez avoir cette page:

Modifiez juste l’adresse IP puis cliquez sur connect.
une fois fait entrez le mot de passe que vous avez défini plus haut (dans le fil).
Vous devriez avoir cette page:

Le pompt >>> est bon signe
Tapez print(2*4) si ça fait 8 c’est parfait.

2 boutons en haut à droite (send a file)
Parcourir et Send to device vous permette de choisir un fichier.py à envoyer depuis votre machine.

1 zone Get a file vous permet de récupérer un fichier depuis L’ESP vers votre ordinateur.

Quels sont les fichiers dans votre ESP exemple :

>>> from os import listdir                                                                                                                            
>>> listdir()                                                                                                                                         
['boot.py', 'jeedom.py', 'webrepl_cfg.py', 'main.py']                                                                                                 
>>>  

Voilà vous savez maintenant envoyer et recevoir des fichiers depuis votre navigateur.
Dans la partie suivante nous apprendrons quel fichier de base et quoi mettre dedans. :wink:

1 « J'aime »

Tutoriel partie 3

Les fichiers de base

Envoi de données à un virtuel Jeedom

Extraire des données de Jeedom


Bon nous voilà au pied du mur, on met quoi dans les fichiers.py ?
Du code MicroPython bien sûr :wink:

Le point de départ c’est le fichier boot.py
Nous allons mettre ici des instructions qui servent à l’initialisation.
exemple :

# exemple de fichier boot.py
import webrepl
webrepl.start()

Puis il nous faut renseigner le fichier main.py

# exemple de fichier main.py
#ce serait pas mal d'initialiser tout de suite le réseau
from network  import WLAN,STA_IF
from time     import sleep

ssid ='lessiddevotrewifi'
mot_de_passe = 'lemotdepasseduwifi'

WLAN(STA_IF).active(1)
WLAN(STA_IF).connect(ssid, mot_de_passe)

print("Attente du réseau WiFi")
at=0
while not WLAN(STA_IF).isconnected(): #Boucle infinie d'attente de connexion wifi
    sleep(1)
    af='Attente wifi ' + str(at)
    print(af)
    at+=1
    pass

print("Le wifi est connecté")

Faites trés attention en Python comme en MicroPython l’indentation est très importante et fait partie de la syntaxe du langage.

Le décalage en marge est de 4 espaces. Dans l’exemple la fin boucle while est en marge avec le print qui suit.
Voilà nous venons d’automatiser tout ce que nous avons fait à la main dans la partie 2.


On s’approche mais on a pas encore envoyé de données à jeedom …
Allez on va ajouter 2 lignes au fichier main.py
mais avant il nous faut un virtuel dans jeedom …
Creez un virtuel puis ajouter une commande info virtuel de type numérique
dans l’équipement notez :
URL de retour
puis
dans la commande
notez (1ere colonne) le n°ID de la commande

L’affaire est assez simple et la ligne assez longue
il vous faudra personnaliser les infos suivante dans la 2iéme ligne ci-dessous
A savoir
IPJEEDOM (inscrite dans URL de RETOUR)
APIJEEDOM (Réglage/systeme/configuration/onglet_API/Clé API)
IDDUVIRTUEL (dans la commande) 1ere colonne
VALEURAENVOYER à vous de choisir une valeur qui sera reçue par la commande virtuel

import urequests

urequests.get("http://IPJEEDOM/core/api/jeeApi.php?plugin=virtual&apikey=APIJEEDOM&type=virtual&id=IDDUVIRTUEL&value=VALEURAENVOYER").text


Il nous reste à faire le contraire prendre une donnée de jeedom vers l’ESP

Le combat est presque le même
Choisir une commande cliquez sur la roue cranté pour obtenir la configuration de la commande.
Dans l’onglet information en haut à droite bouton de droite au dessus de url direct copiez le lien.

on obtiens une adresse comme celle-ci:

http://IP/core/api/jeeApi.php?apikey=1234567890&type=cmd&id=2440

reportez cette adresse dans les lignes suivantes en lieu et place de ICI

import urequests
valeur=str(urequests.get("____ICI____").text)
print(valeur)

Le import urequests n’est à utiliser qu’une fois par fichier.py.

Ouff ca y est non on va devoir mettre un peu d’ordre la dedans,
Je vous ai fait tout ça à l’arrache mais le principe est là.

1 « J'aime »

Tutoriel partie 4 Un effort d’écriture et utilisation de fonctions

Tout ça n’est pas très structuré, pas propre…
Comment bien ré-écrire l’ensemble ?

Pour bien écrire il est nécessaire de bien segmenter les morceaux de notre programme

Cela peut être fait à l’intérieur d’un seul et même fichier ou dans plusieurs fichiers.

La deuxième solution est à privilégier, plus les codes seront petits et indépendants plus il seront facile à maintenir et à réutiliser dans d’autres programmes. l’usage de fonction facilite l’écriture.

Penchons nous sur l’instruction import elle nous permet d’importer des fonctions qu’elles soient interne ou externe. on peut importer aussi seulement une partie des fonctions avec l’instruction

from xxxxx import yyyyy

vous en avez un exemple en début du code main.py

from network  import WLAN,STA_IF
from time     import sleep

network et time sont des librairies qui comportent de nombreuses fonctions.
J’ai choisi de n’importer que ce dont le programme avait besoin. WLAN,STA_IF et sleep

J’aurais pu importer toutes les fonctions.

from network import *

ou d’importer network

import network

dans ce cas j’aurais du écrire

network.WLAN(STA_IF).active(1)
network.WLAN(STA_IF).connect(ssid, mot_de_passe)

à la place de

WLAN(STA_IF).active(1)
WLAN(STA_IF).connect(ssid, mot_de_passe)

Constatez que cela facilite grandement l’écriture et l’encombrement du code.

Il pourrait être sympatique de sortir du code main.py des constantes ou variable

au début du code main.py j’ai utilisé

ssid ='lessiddevotrewifi'
mot_de_passe = 'lemotdepasseduwifi'

Allez on va sortir cela du main.py avec la création d’un nouveau fichier config.py
dans ce fichier nous allons mettre :

# config.py fichier de configuration
ssid ='lessiddevotrewifi'
mot_de_passe = 'lemotdepasseduwifi'
# mais aussi ce qui nous servira plus loin
ipjd ="IPJEEDOM"
apijd="APIJEEDOM"
# nous ajouterons ici toutes les variables ou constantes 

En debut du main.py nous ajouterons :

from config import *

notre main.py se transforme donc en :

# exemple de fichier main.py
#ce serait pas mal d'initialiser tout de suite le réseau
from network  import WLAN,STA_IF
from time     import sleep
import urequests
from config import *

WLAN(STA_IF).active(1)
WLAN(STA_IF).connect(ssid, mot_de_passe)

print("Attente du réseau WiFi")
at=0
while not WLAN(STA_IF).isconnected(): #Boucle infinie d'attente de connexion wifi
    sleep(1)
    af='Attente wifi ' + str(at)
    print(af)
    at+=1
    pass

print("Le wifi est connecté")
print("envoi valeur au virtuel jeedom")
urequests.get("http://"+ipjd+"/core/api/jeeApi.php?plugin=virtual&apikey="+apijd+"&type=virtual&id=IDDUVIRTUEL&value=VALEURAENVOYER").text


Pas mal mais pour aller encore plus loin je verrais bien une petite fonction facile a utiliser genre :

SendAjeedom(idvirtuel,valeur)

vous en pensez quoi ?

En MicroPython une fonction ressemble à cela:

def nomDeLaFonction(liste de paramètres):
    ... 
    bloc d'instructions
    ...
    return resultat

nous allons donc écrire :

# fichier fonctionjd.py
from config import * #pas sur que ce soit nécéssaire ...
# la fonction 
def SendAjeedom(idvirtuel,valeur):
    # construction de l'url
    url =  "http://"
    url += ipjd
    url += "/core/api/jeeApi.php?plugin=virtual&apikey="
    url += apijd
    url += "&type=virtual&id="
    url += idvirtuel
    url += "&value="
    url += valeur
    # Envoi de la valeur a la commande info du virtuel
    urequests.get(url).text
    print("La valeur :" + valeur + " a été envoyer a la commande " + idvirtuel + " de jeedom"
    return

Petit rappel en MicroPython les espaces (indentations) font partie de la syntaxe ils sont au nombre de 4 devant chaque lignes faisant partie de la fonction.

je vous laisse donc écrire dans votre fichier main.py la ligne qui suit avec les paramètres correspondant à votre commande info virtuel jeedom

Nous voilà donc avec une fonction et un nouveau fichier.

je vous laisse donc écrire dans votre fichier main.py la ligne qui suit avec les paramètres correspondant a votre commande info virtuel jeedom

SendAjeedom(idvirtuel,valeur)

C’est à vous …

1 « J'aime »

Tutoriel partie 5 entrées et sorties numériques

_______________________ Les entrées numériques
Bon c’est bien joli tout cela mais, on sait communiquer avec jeedom.
Maintenant il est temps de connecter quelque chose du côté de notre ESP.
En faisant google esp8266 pinout ou ESP32 vous trouverez certainement votre modèle avec plus ou moins de différences de sortie de broches.
Pour rester basique je vous propose juste ce qui vous permettra de comprendre :


Mise à part VCC GND (les alimentations) et quelques autre broches spécifique.
La majorité des autres GPIOXX ont des entrées ou sorties selon la façon dont on les programme.
Accroché derrière les étiquettes certaines broches sont plutôt dédiées à des fonctions ou communications spécifiques comme par exemple GPIO 1 et 3 qui sont plutôt orientés sur des liaisons série. Toutes les broches ne sont pas utilisables, dans la plupart des cas, seules les broches 0, 2, 4, 5, 12, 13, 14, 15 et 16 peuvent être utilisées.
Allez on se lance …

Première idée, un contact que l’on va ouvrir ou fermer puis renvoyer l’information sur un virtuel avec une commande info binaire de jeedom, cela vous va ?

Bien, pour pouvoir communiquer avec les broches (appelons cela PIN) dans notre ESP il faut
importer la librairie interne machine et la fonction pin, ce qui donne donc :

from machine import Pin

Attention le Pin est avec un P majuscule.
Puis nous allons dire de quelle PIN il est question, si elle fonctionne en entrée ou en sortie, si elle est tirée au plus ou au moins (PULL_UP et PULL_DOWN). C’est un peu comme un contact normalement ouvert ou fermé. Si vous avez choisi un PULL_UP il vous faudra connecter votre PIN à la masse (moins), dans le cas d’un PULL_DOWN c’est un plus 3.3 volts qui fraudra.
PIN.IN est une entrée.
PIN.OUT est une sortie.

p2 = Pin( 2 , PIN.IN , PULL_DOWN )

Voilà pour la définition de la broche.

Pour voir son état c’est assez simple maintenant.

>>> p2.value()

Va répondre 0 ou 1 selon son état (connecter un fil entre VCC et GPIO2) pour notre exemple.

Pour poursuivre ce qui a été écrit plus haut … rappelez-vous notre belle fonction jeedom,
remplaçons valeur par p2.value()

SendAjeedom(idvirtuel,p2.value())

Bon cela ne fonctionne qu’une fois peu importe il nous suffit d’inclure tout cela dans une boucle de temps.

On va donc ajouter à notre main.py :

from machine import Pin
p2 = Pin( 2 , PIN.IN , PULL_DOWN )
memp2 = 0
while True
    z = p2.value()
    if memp2 != z
        SendAjeedom(idvirtuel,z)
        memp2 = z
        print("envoi de la valeur a jeedom")
    sleep(1)
    

Pour stopper la boucle et reprendre la main utilisez Ctrl et C …
On peut aussi utiliser les Interruptions externes qui n’appellent une fonction que lorsqu’il y a un changement sur notre entrée (c’est un peu comme un déclencheur dans un scénario).
Pour ne pas alourdir ce tuto et perdre les débutants, Je vous invite à suive la section 6.1 de cette page : 6. GPIO Pins — MicroPython 1.9.3 documentation

_______________________ Les sorties numérique

La formule est sensiblement la même voir plus simple.
On défini une broche cette fois ci en sortie Pin.OUT
puis on lui donne une valeur

>>> from machine import Pin
>>> p4 = Pin(4, Pin.OUT)
>>> p4.value(0)
>>> p4.value(1)

Vous connaissez la technique pour interroger un virtuel, en fonction de son état vous pourrez activer une broche en fonction de son état.

La tension de sortie de la broche sera 3,3 volts ou 0 volts il est à noté que les intensités de sortie sont trés faible vous pouvez allumer une led au travers d’une résistance ou un module relais (avec un driver) prévu à cet effet.


Attention les leds on un sens de fonctionnement.
Regardez en transparence, ou longueur des pattes, ou forme de la patte juste à la sortie.

ATTENTION les sorties utilisées sur ces photos ne correspondent pas forcément aux exemples du tutoriel. vérifiez 'google votre ESP pinout ’ …

Voilà juste pour vous dire que tout est possible ou presque.

Ce tutoriel n’est qu’une initiation MicroPython en relation directe avec jeedom.

Avec les ESP on peut faire plein de choses.
De nombreuses librairies sont disponibles

mes relais, mes boutons, mes sondes, mes afficheurs, mon mini serveur web …

et surtout vos idées, exprimez-vous ! Je peux orienter le tutoriel sur des sujets particuliers …

J’espère vous avoir mis le doigt dans l’engrenage qui n’a de limite que votre imagination.

Liens références rapide
ESP8266 : Quick reference for the ESP8266 — MicroPython latest documentation
ESP32 : Quick reference for the ESP32 — MicroPython latest documentation

Crédit @anon7911623 @patrice_payen

4 « J'aime »

bravo pour ces partages @olive.

promis un jour je me lancerai lol

1 « J'aime »

J’espère bien que tu va tester flo :wink:

Merci @olive
Sujet et tuto très intéressant.
Je vais suivre avec attention.

1 « J'aime »

Bonsoir

Je ne sais pas si cela vient du binaire chargé dans l’Esp32 mais j’ai des erreurs de syntax qui bloquent dans main.py

Les ’ ne passent et il faut "
import urequests et non urequest (noté le s à la fin)

Sinon, pour tout le reste, ça marche super.
Dans l’attente de la suite…

1 « J'aime »

Bonjour @patrice_payen ,

Effectivement c’est bien import urequests a la fin, merci d’avoir tester, c’est corrigé maintenant.

Merci de ta participation.

Super pour ton partage. Je ne suis pas fan de diy mais peut être qu’un jour je franchirai le pas :slight_smile:

1 « J'aime »

Merci de ton commentaire n’hésite pas a revenir le jour ou tu sera prêt :wink:

Merci pour ce partage

1 « J'aime »

De rien @Greg c’est un plaisir avant tout.

1 « J'aime »

Super, un grand merci pour ce tuto, c’est exactement ce que je cherchais !

Bon j’avoue c’est mon deuxième soir sur ESP/Micropython du coup je fais quelques détours par Google, mais je reste confiant :crazy_face:

Dans la partie 3, après avoir reporté la commande « import urequests », j’ai un message d’erreur :

envoi valeur au virtuel jeedom
Traceback (most recent call last):
  File "<stdin>", line 23, in <module>
  File "urequests.py", line 149, in get
  File "urequests.py", line 132, in request
NotImplementedError: Redirects not yet supported

J’ai installé la libraire " pycopy-lib" qui est censé contenir le module « urequests », mais ça ne devait pas être ça le soucis…

Aurais-tu une idée stp ?

En attendant je vais essayer de prendre une donnée de Jeedom vers l’ESP. Merci d’avance

Pas facile de te répondre avec tout les exemples …
1-Dit moi d’abord quel distribution tu a choisi (le nom du fichier.bin) que tu a installer dans ton ESP et quel type d’esp ?
2-copie ici en utilisant l’icon </> le code des fichiers qui génère cette erreur…

aprés je regarde … normalement si tu a installer le bon .bin urequests est de dans …
donc ne nécésite pas un fichier .py

Merci pour ta réponse, j’ai finalement trouvé en passant à la suite, il manquait simplement le S à HTTPS !

J’obtiens une nouvelle erreur :

TLS buffer overflow, record size: 5424 (+5)
ssl_handshake_status: -257
Traceback (most recent call last):
  File "<stdin>", line 23, in <module>
  File "urequests.py", line 149, in get
  File "urequests.py", line 93, in request
OSError: [Errno 5] EIO

J’ai pu lire sur ce Gituhb qu’il s’agissait d’un manque de RAM de la D1 mini. Peut-être qu’au lieu de recompiler un fichier .bin je vais utiliser une carte D1 mini Pro, mais il semblerait qu’il faille compiler un firmware pour profiter des 16Mo de ram.

Sinon concernant le .bin actuel, c’est la version la plus récente du site de MicroPython (j’évite au maximum les fichiers hébergés par d’autres).

Hello,

Je n’avais pas vu ce tuto… un très bon point de départ pour moi qui n’aime pas le C, mais qui veut quand même jouer avec des ESP !

Merci !

1 « J'aime »

C’est le code source de ton fichier .py (pas l’erreur si non je peut pas reproduire et voir ce qu’il se passe)
donne moi aussi le nom complet de ton fichier.bin (ça change régulièrement) que je regarde avec la même version que toi

Merci

Merci mais étant donné que j’ai solutionné mon problème en ajoutant un S à « http », je n’ai pas jugé utile de te partager le code source de mon main.py
La nouvelle erreur ne nécessite pas non plus que je te le partage puisque la limitation est matérielle.

Je vais continuer ton tuto avec un D1 min Pro ou un ESP32 et je reviendrai avec de vraies questions :wink: