Menu Fermer

Python Web Flask sur un NAS (Synology)

Date de la dernière modification: 18 janvier 2023

A la suite de mon article Python Flask et SQLite pour le Raspberry Pi 3 ou 4 – exemples de communication avec des ESP32 ou ESP8266, il m’est venu à l’idée d’intégrer ce serveur Web Flask sur un NAS (Network Attached Storage) de Synology pour, non seulement collectionner les mesures prises par mes différents Raspberry Pi, ESP8266 ou ESP32, de la même manière que sur un RPi, mais aussi en permettant un accès de l’extérieur, voire d’y combiner des données de ces différents objets connectés dans mon réseau local.

Introduction

C’est en essayant de rediriger sur mon NAS de Synology une page Web d’un de mes Raspberry Pi, afin qu’il soit accessible de l’extérieur, qu’il m’est venu à l’idée d’utiliser les différentes technologies décrites dans l’article Python Flask et SQLite pour le Raspberry Pi 3 ou 4 – exemples de communication avec des ESP32 ou ESP8266, et de déplacer les fonctionnalités implémentées sur le Raspberry Pi (RPi) sur un serveur NAS de Synology.

Synology DDNS

Le service DDNS de Synology permet de se connecter de l’extérieur sur son NAS de Synology. Je ne décrirai pas son installation qu’on peut retrouver sur le site de Synology. Je ne décrirai non plus pas comment configurer le routeur pour rediriger correctement le port, afin qu’un URL comme http://(mon_nom_ddns).synology.me:(mon_port_web flask/
puisse atteindre le serveur Web Flask décrit ici.

Un exemple des plus simples

Sur l’armoire, au rez-de-chaussée de ma maison, j’ai un Raspberry Pi avec une application Java et un serveur Web qui me retourne avec l’URL http://192.168.1.xxx:8000/status (xxx fixé dans le routeur WiFi):

C’est un simulateur de présence saisonnier où, par exemple entre 7:13 et 7:43 le matin, un luminaire s’allumera pendant 340 secondes (avec de petites variations aléatoires) et s’éteindra pendant environ 35 secs. La nuit, où si la lumière est trop faible le jour, le détecteur de mouvement activera le luminaire pour 96 secondes. La lumière actuelle est de 347 et la limite à 3720 (valeurs inverses de la quantité de lumière). Le dernier mouvement a eu lieu à 7:11 et il y a aussi des indications de température. Le 16.8 degrés indiquent sans doute un moment où nous avons ouvert toutes les fenêtres.

J’aimerais maintenant que cette page soit accessible de l’extérieur, c’est à dire depuis mon NAS de Synology.

Dans mon article Python Flask et SQLite pour le Raspberry Pi 3 ou 4 – exemples de communication avec des ESP32 ou ESP8266 nous avons quelques scripts Flask que nous allons réutiliser.

Installation de Flask sur le Synology

Il y a différentes façons de développer des applications sur un NAS de Synology. Il est possible de travailler avec le DiskStation Manager (DSM), mais moi je préfère, comme avec mes Raspberry Pi, de préparer et tester mes scripts depuis mon PC Windows avec une console PuTTY, un émulateur client de terminal client pour le protocole SSH. Nous trouveron PuTTY sur le site https://www.putty.org/.

Pour mes scripts Python, j’ai réservé un répertoire sur mon PC pour les stocker (voire les tester) et ensuite, avec WinSCP les transférer dans un sens ou l’autre depuis le NAS de Synology. WinSCP est une application Windows de transfert de fichier disponible sur le site https://winscp.net/eng/download.php .

Avec PuTTY, il faudra se loguer avec l’utilisateur admin pour se retrouver alors sous admin@DiskStation dans le répertoire /var/services/homes/admin.

Il nous faudra installer tout d’abord pip, l’outil d’installation pour Python, s’il n’est pas encore installé, la librairie Flask évidemment et aussi celle de requests qui nous permettra d’accéder notre page Web généré depuis le RPi. Il faudra avoir tout de même quelques connaissances Linux pour comprendre ce qui suit.

admin@DiskStation:~/flaskeur$ sudo -i
root@DiskStation:~# wget https://bootstrap.pypa.io/get-pip.py
....
 La suite: cela prend du temps:
root@DiskStation:~# python get-pip.py
...
root@DiskStation:~# pip install flask
... 
root@DiskStation:~# pip install requests
...

Trop facile ce premier script Flask

Pour commencer par une première vérification, nous pourrions évidement réutiliser le premier script nommé salut_flaskeur.py, décrit au début de l’article Flask dédié au RPi, pour vérifier l’installation, et après avoir créé un sous-répertoire flaskeur sur la racine de notre utilisateur pour y stocker nos scripts.

Cependant nous ferons tout de suite beaucoup plus fort avec le script test1.py:


# armoire.py

from flask import Flask
import requests

app = Flask(__name__)

@app.route('/')
def home():
  r = requests.get("http://192.168.1.134:8000/status")
  return r.text

if __name__ == '__main__':
  app.run(host='0.0.0.0', port=8800, debug=True)

Après avoir importé la librairie Flask, on lui donne le nom app. La fonction home() va nous permettre de générer une page Web pour la racine de ce site. Cette fonction va générer le document html venant de la page http://192.168.1.134:8000/status correspondant la page “Armoire” de notre site Web sur notre Raspberry Pi vu précédemment. La fonction get() de la librairie Python requests fera le job suivi du return pour envoyer le contenu.

Nous pouvons à présent tester le script:

admin@DiskStation:~/flaskeur$ python test1.py
 Serving Flask app "test1" (lazy loading)
 Environment: production
 WARNING: This is a development server. Do not use it in a production deployme                   nt.
 Use a production WSGI server instead.
 Debug mode: on
 Running on http://0.0.0.0:8800/ (Press CTRL+C to quit)
 Restarting with stat
 Debugger is active!
 Debugger PIN: 102-642-322
 192.168.1.110 - - [16/Apr/2020 09:31:01] "GET / HTTP/1.1" 200 -
 192.168.1.110 - - [16/Apr/2020 09:31:01] "GET /favicon.ico HTTP/1.1" 404 - 

que nous vérifierons avec http://192.168.1.xx:8800/ avec xx étant la dernière partie de l’adresse IP de notre NAS accessible dans le réseau local depuis le PC Windows.

Nous retrouverons alors notre page Web V.22.02.2020 – Armoire montrée précédemment et évidemment avec les données du moment (Time now sur la seconde ligne de la page Web étant l’heure au moment de la requête).

Définition d’un script de démarrage

Le script précédent devra être adapté avec le port 8800 modifié avec celui ouvert par le routeur (voir partie DDNS précédente) pour qu’un URL comme http://(mon_nom_ddns).synology.me:(mon_port_web flask/ puisse fonctionner depuis l’extérieur.

ATTENTION! Un test avec ce lien va certainement fonctionner depuis la maison avec une connexion WiFi ou câblée dans et sur notre réseau.
Pour une vrai vérification, il faudra se connecter avec par exemple un smartphone avec connexion réseau et sans WiFi, ou alors demander à une personne extérieur de faire le test.

Nous nous rendrons tout d’abord dans le répertoire /etc/init. Nous y trouverons toute une série de fichier .conf.

Nous allons créer notre propre fichier flaskjbb.conf:


description "Start flask external Web"
author "Jean-Bernard"

respawn

exec /var/services/homes/admin/flaskeur/start.sh

Nous le copierons aussi dans notre répertoire /var/services/homes/admin/flaskeur afin de le conserver au cas ou le répertoire /etc/init serait écrasé ou remplacé par une installation d’une nouvelle version du DSM de Synology.

Le fichier /var/services/homes/admin/flaskeur/start.sh sera défini ainsi avec un chmod +x usuel:


cd /var/services/homes/admin/flaskeur
python mon_flaskeur.py >/dev/null &

Et évidemment le fichier mon_flaskeur.py


# mon_flaskeur.py

from flask import Flask
import requests

app = Flask(__name__)

@app.route('/')
def home():
  r = requests.get("http://192.168.1.134:8000/status")
  return r.text

if __name__ == '__main__':
  app.run(host='0.0.0.0', port=XXXX, debug=True)

XXXX sera le port déjà décrit, de celui ouvert par le router pour notre accès DDNS de l’extérieur.

Pour démarrer et stopper ce service flaskjbb nous utiliserons les commandes:

admin@DiskStation:~/flaskeur$ sudo start flaskjbb
Password:
flaskjbb start/spawned, process 5242
admin@DiskStation:~/flaskeur$ sudo stop flaskjbb
stop: Unknown instance:

Améliorer notre premier exemple

Le script précédent va nous donner une série d’exception dans le cas où notre http://192.168.1.134:8000/status est inaccessible. Afin d’améliorer notre programmation en Python, nous allons à présent utiliser PyDev, une extension à Eclipse. Nous y trouverons une description dans l’article PyDev, un IDE pour Python, sous Eclipse et pour le Raspberry Pi 3.

Le code qui suit va inclure le traitement de l’exception, dû à un timeout, si l’URL n’est pas atteignable. Nous avons volontairement utiliser l’adresse 135, celle d’un autre RPi que je n’avais pas connecté. J’ai spécifié un timeout raisonnable de 3 secondes.

Et évidemment le nouveau fichier mon_flaskeur.py


#http://127.0.0.1:5001
# mon_flaskeur.py

from flask import Flask
import requests

app = Flask(__name__)

@app.route('/')
def home():
  try:
    r = requests.get("http://192.168.1.135:8000/status", timeout=3.0)
    return r.text
  except:
    resp = "http://192.168.1.135:8000/status is not reachable!"
    return resp

if __name__ == '__main__':
  app.run(host='0.0.0.0', port=XXXX, debug=True)
  

XXXX sera le port déjà décrit, donc celui ouvert par le router pour notre accès DDNS de l’extérieur.
La première ligne est utile pour tester sur le PC Windows sous Eclipse avec PyDev. C’est expliquer dans l’article que nous venons de citer.

A suivre …. avec d’autres exemples comme déjà celui-ci en travail!

Un ESP8266 avec mesure de température et de lumière

Nous allons presque tout mettre sur cet ESP8266, des composants électroniques intéressants et de la technologie à la hauteur de nos attentes.

Lorsqu’on dépose des composants sur une platine d’essai, et ensuite qu’on les attache à l’ESP8266 via les broches choisies, il est important de déposer, au début de notre sketch, du code pour montrer dans notre console COM de l’IDE de l’Arduino que, le WiFi fonctionne, son adresse IP, ainsi que les premières valeurs lues à l’initialisation pour la température et l’intensité lumineuse.

Dès que nous aurons déconnecté le câble, déplacé notre système à l’endroit désiré, il sera bien de pouvoir accéder ces deux valeurs au travers d’un mini serveur Web.

Ensuite, le code client du POST http pourra être utilisé dès qu’un serveur Flask sera en place tout d’abord pour des tests sur un PC Windows with Eclipse et son extension PiDev, et ensuite sur un Raspberry Pi avec une base de données SQLite, et finalement sur un NAS de Synology, toujours avec Flask et Python, et, pourquoi pas, sur une base mySQL.

A venir: schéma, photo et sketch.