No description
  • Python 95.3%
  • JavaScript 2.4%
  • Shell 0.9%
  • CSS 0.8%
  • HTML 0.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Julien LEQUEN 0bca81a5ce Test des caractères : « été » s'écrit é-t-é
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:47:38 +02:00
deploiement Fiabilité : tests, copies de secours, limites, sauvegardes, mise à jour des données 2026-10-14 09:26:56 +02:00
serveur Cinq nouveaux services : ESSENCE, ITI, SNCF, ROUTE, AIR 2026-10-14 14:47:25 +02:00
tests Test des caractères : « été » s'écrit é-t-é 2026-10-14 14:47:38 +02:00
.dockerignore Cinq nouveaux services : ESSENCE, ITI, SNCF, ROUTE, AIR 2026-10-14 14:47:25 +02:00
.gitignore Cinq nouveaux services : ESSENCE, ITI, SNCF, ROUTE, AIR 2026-10-14 14:47:25 +02:00
client.py Reconnexion automatique et reprise de session 2026-10-13 22:01:45 +02:00
docker-compose.yml Cinq nouveaux services : ESSENCE, ITI, SNCF, ROUTE, AIR 2026-10-14 14:47:25 +02:00
minitel.py Serveur 3615 : services Minitel, client série et émulateur web 2026-10-13 19:57:17 +02:00
README.md Cinq nouveaux services : ESSENCE, ITI, SNCF, ROUTE, AIR 2026-10-14 14:47:25 +02:00

3615

Serveur de services Minitel maison, un client qui relie un vrai Minitel au serveur par le port série (en jouant le rôle de l'ancien modem), un émulateur Minitel dans le navigateur, et un utilitaire pour utiliser le Minitel comme terminal Linux.

Minitel ──câble DIN/USB── PC : client.py ──HTTP(S) / WebSocket──┐
                                                                ├── Docker : serveur (port 8615)
Navigateur : http://hote:8615 ───────────HTTP / WebSocket───────┘

Démarrer

docker compose up -d --build                    # serveur (redémarre avec la machine)
./client.py                                     # Minitel sur /dev/ttyUSB0, serveur local
./client.py --serveur http://10.0.2.5:8615      # serveur sur une autre machine
./client.py --serveur minitel.maison.lequen.fr:443   # derrière le proxy HTTPS (wss://)
./client.py --numero 3614 ...                   # numéro composé d'avance

Sans Minitel : ouvrir http://hote:8615 dans un navigateur (ajouter ?vitesse=0 pour un affichage instantané au lieu des 4800 bauds d'origine).

Allumer le Minitel avant de lancer le client ; Ctrl-C sur le PC l'arrête. Si le serveur coupe la connexion ou ne répond pas, ENVOI sur le Minitel pour réessayer.

Numéros d'accès (grille Télétel de 1991)

À la connexion, on compose le numéro sur le clavier du Minitel puis CONNEXION/FIN : 11 (Annuaire électronique, 3 minutes gratuites puis 0,365 F/mn), 3613 (0,122 F/mn), 3614 (0,365 F/mn), 3615 (0,84 à 1,25 F/mn), 3616 (0,98 à 1,25 F/mn), 3617 (2,19 F/mn). Chaque service est rangé à son numéro ; la page Télétel (SOMMAIRE) donne le coût au tarif d'époque. Le 11 cherche dans la base Sirene des entreprises en activité (pas d'annuaire des particuliers en données ouvertes, pas de téléphones).

La page web de l'émulateur explique aussi comment télécharger et lancer le client.

Services

La page Télétel (reconstituée d'après la notice France Télécom du Minitel 12) demande le nom du service. MGS ouvre le guide des services (« Les Pages Minitel », page d'origine de 1995), SOMMAIRE le coût de la communication au tarif d'époque, GUIDE le mode d'emploi.

Code Service
MGS guide des services : question en clair, ou GUIDE pour la liste complète
METEO météo du jour, 7 jours (Open-Meteo) et vigilance Météo-France du département
ACTU actualités franceinfo par rubrique
MESSAGES messagerie : pseudo, CV, salon, messages privés ; PSEUDO,CODE ouvre une boîte aux lettres gardée
PINGDX cluster CB 11 m et PMR446 de pingdx.org, ouvertures, météo spatiale
ULLA recréation personnelle du 3615 ULLA : pseudo,motdepasse, annonces, animateurs régionaux (Ollama local)
VENT vent et vagues façon Windguru, 32 spots ou n'importe quelle ville
NAVALE bataille navale contre l'ordinateur (3 niveaux) ou entre deux Minitels, palmarès
ADSB carte des avions en temps réel (readsb / tar1090), fiche avion, trace, avions remarquables
MARINE bulletin côtier façon Météo-France, 22 zones de Dunkerque à Bastia ou tout port, marées
RADIO propagation HF, passages (visibles) de l'ISS et des satellites amateurs, l'ISS sur la carte du monde
CINEMA salles de toute la France par ville ; programme lu sur le site de la salle (Six N'Étoiles…), sinon chez AlloCiné
TV programme de la TNT : ce soir, en ce moment, par chaîne, films du soir, recherche (xmltvfr.fr)
PHARMACIE toutes les pharmacies de France par commune, ouvertes maintenant, garde (32 37), urgences
MUSEE pages Vidéotex d'époque, dessinées à la vitesse du 1200 bauds, avec leur fiche
METAR météo des aérodromes français : METAR traduit en clair et TAF (aviationweather.gov)
ORACLE horoscope du jour, tarot de Marseille, questions à Madame Irma (Ollama)
AGENDA sorties autour de Toulon (office de tourisme Provence Méditerranée)
LOTO tirages et rapports du Loto et de l'Euromillions (archives officielles FDJ), vérification d'une grille, statistiques
BOURSE CAC 40, hausses et baisses, grandes valeurs de Paris et leur courbe sur 3 mois (cours différés, Yahoo Finance)
DICO définitions et synonymes (Wiktionnaire), anagrammes, mots croisés, mot existant (liste Français-GUTenberg)
EPHEMERIDE prénoms fêtés, soleil, lune, ce jour-là dans l'histoire et naissances (Wikipédia), pour tout jour
SEISMES séismes de la semaine en France (RéNaSS) et dans le monde (USGS), fiche et carte du monde
ESSENCE prix des carburants autour d'une commune, du moins cher au plus cher (prix-carburants.gouv.fr)
ITI itinéraire routier : distance, durée, grandes routes, carburant estimé (OSRM, OpenStreetMap)
SNCF départs et arrivées d'une gare en temps réel, retards et suppressions (API SNCF, clé gratuite SNCF_CLE)
ROUTE info trafic Bison Futé des routes nationales, autour d'une commune ou sur une route
AIR qualité de l'air (indice européen), polluants, tendance sur 3 jours, pollens (CAMS via Open-Meteo)

Touches, comme sur Télétel

ENVOI valide, SOMMAIRE revient au sommaire du service, GUIDE donne l'aide de l'écran, RETOUR / SUITE l'écran précédent / suivant, ANNULATION efface la saisie, CORRECTION le dernier caractère, RÉPÉTITION réaffiche l'écran. CONNEXION/FIN ramène à la page Télétel pour changer de service ; un second appui, sur la page Télétel, met fin à la consultation.

Ligne 0

Comme le PAVI de Télétel, le serveur écrit sur la ligne 0 (colonnes 1 à 36) le service en cours et les messages ; les colonnes 37 à 40 restent au Minitel pour son indicateur de connexion C / F. À droite, un compteur donne la durée et le coût de la consultation aux tarifs de 1991 (celui de chaque service, plus la mise en relation), mis à jour chaque minute. Chaque écriture se termine par LF, qui ramène le curseur là où il était. Un message privé fait sonner le Minitel, et 15 minutes sans toucher le clavier mettent fin à la consultation.

Réglages (docker-compose.yml)

Variable Rôle
OLLAMA_URL, OLLAMA_MODELE modèle de langage des animateurs ULLA
ANIMATEURS, ANIMATEURS_JUSQUA, ANIMATEURS_PRESENTS script sans Ollama, non sans animateurs ; seuil d'humains ; animateurs connectés à la fois (5, sur 10, avec relève)
ADSB_URL, ADSB_DEBIT dossier data/ du récepteur ADS-B ; octets/s du Minitel (120 à 1200 bauds)
STATION_LAT, STATION_LON position pour les passages de satellites (défaut : Six-Fours)
PINGDX_URL autre instance de PingDX
INACTIVITE secondes sans touche avant la fin de consultation (défaut 900)
DIFFERENCES non pour toujours envoyer les pages entières
SESSIONS_MAX, SESSIONS_PAR_ADRESSE connexions simultanées acceptées, en tout et par adresse IP
SNCF_CLE clé de l'API SNCF (gratuite, numerique.sncf.com), dans un fichier .env à côté de docker-compose.yml
SORTIE_DONNEES, CACHE_OVERPASS où la mise à jour mensuelle écrit les données nationales, et son cache
MUSEE_DEBIT octets par seconde pour dessiner les pièces du musée (120 = 1200 bauds, 0 = d'un coup)

Le volume memoire (/data, ou DONNEES) garde ce qui doit survivre à un redémarrage : boîtes aux lettres de MESSAGES et d'ULLA (bal_*.json, codes hachés en scrypt), profils des pseudos réservés d'ULLA (« pseudo,motdepasse »), petites annonces ULLA, palmarès NAVALE, mémoire des animateurs ULLA, et les copies des sources lentes (orbites, programme TV, agenda). Le serveur doit pouvoir sortir sur Internet.

Contenu

Fichier Rôle
client.py pont port série ⇄ WebSocket (HTTP ou HTTPS), Vidéotex 40 colonnes
minitel.py shell Linux sur le Minitel (mode téléinformatique 80 colonnes)
serveur/minitel3615/videotex.py codes d'affichage : couleurs, tailles, mosaïque, accents
serveur/minitel3615/session.py clavier, touches, zones de saisie, ligne 0, enchaînement des pages
serveur/minitel3615/passerelle_web.py, web/ HTTP + WebSocket, émulateur Minitel dans le navigateur
serveur/minitel3615/pages/ une page par fichier : Télétel, sommaire et chaque service
serveur/minitel3615/pages/ulla/ service ULLA ; vdt/ : écrans de pynitel (AGPL-3.0, voir vdt/CREDITS.md)
serveur/minitel3615/animateurs.py animateurs ULLA : personnages, Ollama, mémoire, répliques de secours
serveur/minitel3615/messagerie.py, rencontres.py connectés, salon, messages privés, BAL, annonces
serveur/minitel3615/ecran.py copie de l'écran du Minitel : n'envoie d'une page que ce qui change
serveur/minitel3615/stockage.py fichiers JSON du volume /data (écriture atomique)
serveur/minitel3615/adsb.py, carte.py, tampon.py ADS-B : récepteur, fond de carte, envoi des seules cases qui changent
serveur/minitel3615/donnees/cote.json.gz trait de côte OSM (© contributeurs OpenStreetMap, ODbL) ; serveur/outils/telecharger_cote.py le régénère
serveur/minitel3615/bataille.py bataille navale : grilles, ordinateur, appariement
serveur/minitel3615/radio.py propagation (HamQSL), orbites (CelesTrak, sgp4)
serveur/minitel3615/ia.py accès commun au modèle de langage local (Ollama)
serveur/minitel3615/metar.py, donnees/aerodromes.json METAR / TAF et aérodromes français (OurAirports, domaine public)
serveur/minitel3615/agenda.py agenda lu sur provencemed.com (copie dans le volume)
serveur/minitel3615/cinema.py programme lu sur le site du Six N'Étoiles
serveur/minitel3615/tv.py guide TV XMLTV (copie dans le volume)
serveur/minitel3615/sante.py, donnees/sante.json.gz officines de France avec horaires, et urgences ; serveur/outils/telecharger_sante.py les régénère (FINESS, OpenStreetMap)
serveur/minitel3615/cinema.py, allocine.py, donnees/cinemas.json.gz salles de cinéma de France ; serveur/outils/telecharger_cinemas.py les régénère (OpenStreetMap)
serveur/minitel3615/vigilance.py vigilance Météo-France (cartes en données ouvertes, data.gouv.fr)
serveur/minitel3615/donnees/mots.txt.gz 336 531 mots français (Français-GUTenberg, C. Pythoud, GPL ; liste de C. Pallier)
serveur/minitel3615/donnees/monde.txt terres émergées en 80 x 48 points (Natural Earth, domaine public)
serveur/minitel3615/donnees/musee/ pages d'époque du musée (pynitel, AGPL, voir CREDITS.md)
serveur/minitel3615/openmeteo.py, rss.py, pingdx.py, web.py sources de données

Tests, déploiement, exploitation

tests/lancer.sh                  # tests unitaires + parcours de tous les services
deploiement/deployer.sh          # tests, git push, mise à jour de 10.0.2.5
  • tests/test_unitaires.py : calculs (marées, horaires, IA navale, METAR, BAL...), validité Vidéotex des écrans, exactitude de l'envoi par différences. Sans réseau.
  • tests/parcours.py : un Minitel de test parcourt chaque service sur un serveur jetable (port 3625) avec les vraies sources ; échoue sur une position hors écran, une connexion coupée, un écran vide, ou une erreur Python dans le journal du serveur.
  • deploiement/mettre_a_jour.sh (sur le serveur) construit la nouvelle image avant d'arrêter l'ancienne, vérifie que le serveur répond (HTTP et TCP) et sinon revient au commit et à l'image d'avant. Il installe aussi deux tâches systemd :
    • 3615-sauvegarde.timer : chaque nuit à 3 h 30, le volume /data (BAL, annonces, palmarès, mémoire des animateurs) est archivé dans /data/sauvegardes/3615 (second disque), 30 jours gardés ;
    • 3615-donnees.timer : le 1er du mois, les outils régénèrent pharmacies, horaires, hôpitaux et salles de cinéma dans /data/nationales, que le serveur préfère aux fichiers livrés quand ils sont plus récents.
  • Quand une source ne répond plus, le serveur ressert sa dernière bonne réponse (gardée dans /data/secours) et l'indique en ligne 0 (« copie de 14h20 »).
  • Le conteneur est limité à 512 Mo et un processeur, ses journaux à 3 x 10 Mo ; le serveur accepte 20 connexions en tout et 4 par adresse (SESSIONS_MAX, SESSIONS_PAR_ADRESSE), derrière le proxy d'après X-Forwarded-For.

Ajouter un service

Une page est une coroutine qui reçoit la session et renvoie la page suivante (ACCUEIL pour la page Télétel, None pour raccrocher) :

from .. import videotex as vt
from ..session import ACCUEIL

async def horloge(session):
    await session.envoyer(vt.FF, vt.position(10, 5), vt.couleur(vt.JAUNE), vt.texte("Bonjour !"))
    while True:
        t = await session.touche(aide="SOMMAIRE : page Télétel")
        if t.fonction == "SOMMAIRE":
            return ACCUEIL

Puis la référencer dans SERVICES de pages/accueil.py et relancer docker compose up -d --build.