Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
| asso:si:si_garage [2026/10/10 17:45] – Mise à jour : électronique (schéma Fritzing, photos), serveur nginx/Flask, badges RFID, dépannage nrineau | asso:si:si_garage [2026/10/12 22:04] (Version actuelle) – La route locale est aussi appelée par le bouton garage du Pi de la porte (gatepi) nrineau | ||
|---|---|---|---|
| Ligne 6: | Ligne 6: | ||
| * **Badge RFID** : un badge de la liste ouvre le **garage** uniquement. | * **Badge RFID** : un badge de la liste ouvre le **garage** uniquement. | ||
| - | < | + | {{ :asso:si:garage_archify.png? |
| - | Framateam ──HTTP | + | |
| - | Badge ──► lecteur RFID USB ──► rfid.py ──► rfid.log ──► gate-service.sh (perm.list) ──┘ | + | //Schéma réalisé avec [[https:// |
| - | </code> | + | |
| ==== Électronique ==== | ==== Électronique ==== | ||
| Ligne 15: | Ligne 14: | ||
| {{ : | {{ : | ||
| - | Schéma Fritzing modifiable : {{:asso:si:boitier-garage.fzz|boitier-garage.fzz}} | + | Schéma Fritzing modifiable : {{:asso:si:boitier_garage_fritzing.zip|boitier_garage_fritzing.zip}} (contient '' |
| {{ : | {{ : | ||
| Ligne 114: | Ligne 113: | ||
| ^ Route ^ Déclenchée par ^ Action ^ Contrôle ^ | ^ Route ^ Déclenchée par ^ Action ^ Contrôle ^ | ||
| - | | ouverture locale (GET) | '' | + | | ouverture locale (GET) | '' |
| | garage (POST) | commande slash Framateam | garage | canal garage ou canal porte | | | garage (POST) | commande slash Framateam | garage | canal garage ou canal porte | | ||
| | entrer (POST) | commande slash Framateam | ouvre la porte arrière + message « X a ouvert le local » | canal porte | | | entrer (POST) | commande slash Framateam | ouvre la porte arrière + message « X a ouvert le local » | canal porte | | ||
| | sortir (POST) | commande slash Framateam | ferme la porte arrière + message « X a fermé le local » | canal porte | | | sortir (POST) | commande slash Framateam | ferme la porte arrière + message « X a fermé le local » | canal porte | | ||
| + | |||
| + | ==== Code du serveur (server.py) ==== | ||
| + | |||
| + | Version en service sur l'atom (''/ | ||
| + | |||
| + | <code python> | ||
| + | from flask import Flask, request, jsonify | ||
| + | app = Flask(__name__) | ||
| + | import serial | ||
| + | |||
| + | ARDUINO = '/ | ||
| + | GARAGE_CHANNEL = '< | ||
| + | PORTE_CHANNEL = '< | ||
| + | |||
| + | def send_command(c): | ||
| + | try: | ||
| + | with serial.Serial(port=ARDUINO, | ||
| + | banner = f.readline().decode(' | ||
| + | if ' | ||
| + | return " | ||
| + | f.write(c) | ||
| + | f.flush() | ||
| + | resp = f.readline().decode(' | ||
| + | return " | ||
| + | except serial.serialutil.SerialException as e: | ||
| + | return str(e) | ||
| + | |||
| + | # uncondtionnally open the garage (for local usage) | ||
| + | @app.route('/< | ||
| + | def local_open(): | ||
| + | return send_command(b' | ||
| + | |||
| + | @app.route('/< | ||
| + | def open(): | ||
| + | user_name = request.form.get(' | ||
| + | channel_id = request.form.get(' | ||
| + | if channel_id != GARAGE_CHANNEL and channel_id != PORTE_CHANNEL: | ||
| + | return "this is not the command you are looking for" | ||
| + | return send_command(b' | ||
| + | |||
| + | @app.route('/< | ||
| + | def enter(): | ||
| + | user_name = request.form.get(' | ||
| + | channel_id = request.form.get(' | ||
| + | if channel_id != PORTE_CHANNEL: | ||
| + | return "this is not the command you are looking for" | ||
| + | r = send_command(b' | ||
| + | return jsonify({ | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | }] | ||
| + | }) | ||
| + | |||
| + | @app.route('/< | ||
| + | def leave(): | ||
| + | user_name = request.form.get(' | ||
| + | channel_id = request.form.get(' | ||
| + | if channel_id != PORTE_CHANNEL: | ||
| + | return "this is not the command you are looking for" | ||
| + | r = send_command(b' | ||
| + | return jsonify({ | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | }] | ||
| + | }) | ||
| + | |||
| + | if __name__ == ' | ||
| + | app.run(host=' | ||
| + | </ | ||
| + | |||
| + | Fonctionnement : | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * Le serveur n' | ||
| + | |||
| + | ==== Code du lecteur de badges (gate-service.sh) ==== | ||
| + | |||
| + | <code bash> | ||
| + | #!/bin/bash | ||
| + | |||
| + | cd $(dirname " | ||
| + | LOG=./ | ||
| + | |||
| + | (while true ; do python3 rfid.py ; sleep 1 ; done) & | ||
| + | |||
| + | validate_id() { | ||
| + | awk "/^$1 / { print \$2 }" ./perm.list | ||
| + | } | ||
| + | |||
| + | while true; do | ||
| + | inotifywait -qq -e modify " | ||
| + | date | ||
| + | l=$(tail -n 1 " | ||
| + | if ! egrep -q ' | ||
| + | echo " | ||
| + | continue | ||
| + | fi | ||
| + | c=$(cut -d ' ' -f 2 <<< | ||
| + | name=$(validate_id " | ||
| + | if [ -z " | ||
| + | echo " | ||
| + | continue | ||
| + | fi | ||
| + | echo " | ||
| + | curl http:// | ||
| + | done | ||
| + | </ | ||
| + | |||
| + | Fonctionnement : | ||
| + | * lance '' | ||
| + | * '' | ||
| + | * à chaque nouvelle ligne de '' | ||
| + | * si le badge est autorisé, il appelle la route locale du serveur (''< | ||
| Lancement au démarrage, dans ''/ | Lancement au démarrage, dans ''/ | ||