Dashboard Observatoire, Meteo / Allsky saftymonitor
Auteur : Frédéric Tapissier — Gîte AVEX / GEVEX, Vimoutiers, Normandie
Site : https://avex-asso.org/ftapissier/
Dashboard live : http://86.241.95.110:8888/
Version : Mai 2026
Table des matières
- Présentation du projet
- Matériel et logiciels utilisés
- Architecture générale
- Le dashboard HTML
- L'analyseur Python allsky_analyzer.py
- Analyse de la couverture nuageuse
- Comptage des étoiles et calibration
- Intégration OpenWeatherMap
- Correction de la Lune
- Intégration NINA via ninaAPI
- Publication sur serveur web Infomaniak
- Historique multi-nuits
- Démarrage automatique Windows
- Structure des fichiers
- Dépannage
- Évolutions possibles
1. Présentation du projet
Objectif
Le GEVEX est un gîte astronomique situé à Vimoutiers en Normandie, équipé d'une caméra allsky ASI178 pilotée par le logiciel AllSkEye. L'objectif de ce projet est de construire un dashboard d'observatoire complet, accessible depuis n'importe quel appareil (PC, téléphone, tablette), affichant en temps réel :
- L'image allsky en direct
- L'analyse automatique du ciel (couverture nuageuse, comptage d'étoiles)
- L'état du séquenceur astronomique NINA
- Les données météo (OWM + Météo-France + carte interactive)
- Les flux des caméras de surveillance
- L'historique des nuits d'observation
Point de départ
AllSkEye génère une page HTML de statut (allskeyestatus.html) servie sur le réseau local (port 8888). Cette page existait mais était basique. Le projet consiste à l'enrichir considérablement tout en restant compatible avec le mécanisme de mise à jour d'AllSkEye.
J'avais déjà opéré à une petite mise à jour de la page pour y apporter des élément hétéroclite de supervisions :
Résultat final
Apres un centaine d'heure de travail :
2. Matériel et logiciels utilisés
Matériel
| Élément | Détail |
|---|---|
| Caméra allsky | ZWO ASI178 couleur, objectif fisheye |
| PC observatoire | Windows 11, héberge AllSkEye |
| PC télescope | Windows, héberge NINA (réseau local séparé) |
| Réseau | IP publique fixe 86.241.95.110 |
| Hébergement web | Infomaniak (avex-asso.org) |
Logiciels
| Logiciel | Rôle |
|---|---|
| AllSkEye | Pilotage caméra allsky, génération JPG, serveur web port 8888 |
| NINA | Séquenceur d'acquisition astronomique |
| ninaAPI (plugin) | API REST pour NINA (v2) |
| Python 3.14 | Analyseur d'images, proxy, serveur HTTP |
| FileZilla | Client FTP pour uploads Infomaniak |
Bibliothèques Python
pip install opencv-python numpy matplotlib watchdog ephem pillow
| Bibliothèque | Usage |
|---|---|
opencv-python |
Analyse d'images allsky |
numpy |
Calculs matriciels sur les pixels |
matplotlib |
Génération des graphiques PNG |
watchdog |
Surveillance du dossier images en temps réel |
ephem |
Calcul position Soleil, Lune, crépuscules |
pillow |
Lecture du masque PNG |
3. Architecture générale
┌─────────────────────────────────────────────────────┐
│ PC OBSERVATOIRE (86.00.00.00) │
│ │
│ AllSkEye ──► D:\AllSkEye\ImageConversions\*.jpg │
│ │ │
│ ▼ │
│ allsky_analyzer.py (Python, tâche planifiée admin) │
│ ├── Analyse image (OpenCV) │
│ ├── Appel OWM (météo référence) │
│ ├── Calcul Soleil/Lune (ephem) │
│ ├── Génère sky_status.json + PNG graphiques │
│ ├── Poll NINA API ──► nina_status.json │
│ ├── Upload FTP ──► Infomaniak │
│ └── Serveur HTTP :8890 (proxy NINA + données) │
│ │
│ AllSkEye web server :8888 │
│ └── allskeyestatus.html (dashboard) │
└─────────────────────────────────────────────────────┘
│ FTP TLS │ navigateur
▼ ▼
┌──────────────────┐ ┌─────────────────────────────┐
│ Infomaniak │ │ Navigateur (local/internet) │
│ avex-asso.org │ │ │
│ /ftapissier/ │ │ http://86.241.95.110:8888/ │
│ gevex/ │ │ ├── allskeyestatus.html │
│ ├── sky_status │◄───│ └── iframes Infomaniak : │
│ ├── nina_status │ │ ├── sky_status_iframe │
│ ├── history │ │ ├── nina_iframe │
│ └── graphiques │ │ └── history_iframe │
└──────────────────┘ └─────────────────────────────┘
Pourquoi cette architecture ?
La contrainte principale est que le navigateur impose des restrictions CORS (Cross-Origin Resource Sharing) : une page chargée depuis 86.241.95.110:8888 ne peut pas faire de requêtes fetch() vers d'autres domaines/ports. Les solutions retenues :
- Les données textuelles (JSON) sont lues depuis des iframes hébergées sur Infomaniak — même domaine = pas de CORS
- Les images PNG (graphiques) passent directement car les balises
<img>ne sont pas soumises au CORS - NINA (sur un autre PC du réseau local) est proxyfié par le programme Python via un serveur HTTP sur le port 8890
4. Le dashboard HTML
Fichier : allskeyestatus.html
Ce fichier est le fichier de statut standard d'AllSkEye, enrichi. Il doit rester dans C:\Program Files\AllSkEye_0.9.29.2\ et conserve les placeholders AllSkEye :
{ImagesPlaceholderDoNotChange}— image allsky injectée par AllSkEye{StatusPlaceholderDoNotChange}— statut système AllSkEye{RefreshTimePlaceholderDoNotChange}— timer de refresh AllSkEye
Organisation du dashboard (grille 3 colonnes)
┌─────────────┬─────────────┬─────────────┐ Ligne 1
│ Caméra │ Analyse │ Vue │
│ Allsky │ Ciel GEVEX │ observatoire│
│ + Statut │ (iframe + │ gevex2.jpg │
│ │ graphiques) │ │
├─────────────┴─────────────┼─────────────┤ Ligne 2
│ NINA — Séquenceur │ Caméra │
│ (iframe Infomaniak) │ télescope │
├─────────────┬─────────────┴─────────────┤ Ligne 3
│ Satellite │ Carte météo │ Caméra │
│ animé │ interactive │ observ. 2 │
├─────────────┴──────────────┴────────────┤ Ligne 4
│ Historique des nuits (pleine largeur) │
└─────────────────────────────────────────┘
Design
- Thème dark scientifique/industriel
- Police
Rajdhani(titres) +Share Tech Mono(données) - Effet scanlines subtil
- Accents colorés : bleu cyan, rose, vert, orange selon les panneaux
- Widget horloge externe (zeitverschiebung.net) — heure locale + date
- Widget phase lunaire (moonphase.guide)
Rafraîchissement
- Toutes les 30 secondes : cache-bust sur les images statiques (allsky, satellite, gevex2.jpg, graphiques PNG) via
?t=timestamp - Toutes les 2 minutes : rechargement complet de la page via
location.hrefavec paramètre?nocache=timestamp - Iframes Infomaniak : se rechargent indépendamment via
<meta http-equiv="refresh">
📸 [Capture : dashboard complet annoté]
5. L'analyseur Python allsky_analyzer.py
Rôle
Programme Python tournant en permanence sur le PC observatoire. Il surveille le dossier images d'AllSkEye et traite chaque nouvelle image dès qu'elle apparaît.
Configuration (début du fichier)
CONFIG = {
'images_dir': r'D:\AllSkEye\ImageConversions',
'mask_path': r'D:\AllSkEye\masque_etoile_pour_Claude.png',
'output_dir': r'D:\AllSkEye',
'lat': '48.873',
'lon': '0.219',
'elevation': 100,
'owm_key': 'VOTRE_CLE_API_OWM', # OWM = Open weather map, site qui diffuse des infos météo locales
'owm_lat': 48.7167, # Fresnay-les-Samon
'owm_lon': 0.3833,
'ftp_host': 'dzcd.ftp.infomaniak.com',
'ftp_user': 'dzcd_XXXXX',
'ftp_pass': 'VOTRE_MOT_DE_PASSE',
'ftp_dir': '/web/ftapissier/gevex',
'ftp_tls': True,
'ftp_enabled': True,
}
Pipeline de traitement par image
Nouvelle image JPG détectée (watchdog)
│
├── Attente 1.5s (écriture complète du fichier)
├── Lecture image OpenCV
├── Extraction horodatage depuis nom de fichier
│ └── Format AllSkEye : -YYYY-MM-DDTHH-MM-SS-mmm.jpg
│ (heure LOCALE France → conversion UTC pour ephem)
├── Calcul contexte astronomique (ephem)
│ ├── Altitude Soleil → mode JOUR/CRÉPUSCULE/NUIT
│ ├── Position Lune → masque dynamique
│ └── Phase lunaire → facteur de correction étoiles
├── Application masque paysage + masque Lune dynamique
├── Analyse couverture nuageuse (selon mode)
├── Si NUIT : comptage étoiles + correction OWM/Lune
├── Enregistrement point historique nuit
├── Génération sky_status.json
├── Génération graphiques PNG (2h glissantes)
└── Upload FTP vers Infomaniak (thread séparé)
Nommage des fichiers AllSkEye
AllSkEye nomme ses JPG en heure locale France :
-2026-05-04T22-30-15-123.jpg
└── 4 mai 2026, 22h30m15s heure locale
Le programme convertit automatiquement en UTC pour les calculs astronomiques (ephem travaille toujours en UTC). La conversion tient compte du changement d'heure été/hiver (CEST UTC+2 / CET UTC+1).
6. Analyse de la couverture nuageuse
Problématique
La détection de nuages sur une caméra allsky couleur est plus complexe qu'il n'y paraît, pour deux raisons :
- La méthode varie selon que c'est le jour ou la nuit
- La présence de la Lune (surtout pleine) peut faire briller les nuages exactement comme un ciel dégagé
Mode jour : saturation HSV
De jour, les nuages sont blancs ou gris (faible saturation), tandis que le ciel dégagé est bleu (forte saturation et teinte dans la plage 85°-135° en HSV).
# Ciel bleu dégagé : teinte bleue + saturation > 50
blue_frac = pixels avec H∈[85-135] et S>50
# Nuages : saturation faible (blanc/gris)
cloud_frac = pixels avec S < 60
# Résultat combiné
cloud_pct = 0.5 * cloud_frac * 100 + 0.5 * (1 - blue_frac) * 100
Fusion avec OWM (Open Weather Map) : La caméra ASI178 produit des images avec une saturation naturellement faible, ce qui peut sous-estimer les nuages. On fusionne donc la détection image (40%) avec la donnée OWM (60%) pour le mode jour :
cloud_pct = 0.4 * cloud_image + 0.6 * owm_clouds
Open Weather map diffuse une API (un systeme de diffusion des données météo locales) qui est compréhensible par des logiciels comme NINA ou par des scripts. Ce calcul permet de ponderer des données localement mal interprété par des données d'une station météo officielle : cela évite des abérations liée, par exemple à une diffusion exessive du sole (pixel blanc) qui peut etre interprété comme des nuages
Mode nuit : variance locale + comptage étoiles
La nuit, le ratio B/R et la saturation HSV ne fonctionnent plus (tout est sombre). On utilise deux indicateurs :
Variance locale par blocs 32×32 pixels :
- Un ciel dégagé avec des étoiles → variance résiduelle élevée (sources ponctuelles brillantes)
- Un ciel couvert homogène → variance résiduelle faible
Ratio étoiles observées / étoiles attendues (méthode principale) :
cloud_pct = 0.75 * (1 - étoiles_observées/étoiles_attendues) * 100
+ 0.25 * cloud_variance
7. Comptage des étoiles et calibration
Méthode de détection
Image nuit → Niveaux de gris
│
├── Soustraction du fond lent (GaussianBlur 51×51)
│ └── Élimine le gradient de luminosité (Lune, pollution lumineuse)
├── Seuillage strict (moyenne + 3.5 σ, minimum 12)
├── Détection de contours
└── Filtres de validation :
├── Aire entre 3 et 120 pixels² (élimine bruit et satellites)
└── Circularité > 0.4 (élimine artefacts allongés)
Auto-calibration de star_max_ref
Le programme maintient une référence star_max_ref (nombre d'étoiles pour un ciel parfait). Cette valeur s'auto-calibre automatiquement :
- Conditions requises : OWM < 10% nuages, visibilité > 8 km, Lune < 20% ou couchée
- Mécanisme : si le nombre d'étoiles observées dépasse la référence actuelle (corrigé de la gêne lunaire), la référence est mise à jour et sauvegardée dans
star_max_ref.json
# Sauvegardé dans D:\AllSkEye\star_max_ref.json
{"star_max_ref": 450, "updated": "2026-05-10T03:15:00"}
📸 [Capture : graphique étoiles détectées 2h]
8. Intégration OpenWeatherMap
Pourquoi OWM ?
OWM fournit des données météo en temps réel (toutes les 10 minutes dans le programme) qui servent à deux usages distincts :
- Calibration de jour : référence de vérité terrain pour la couverture nuageuse
- Calcul d'étoiles attendues la nuit : transparence atmosphérique théorique
Clé API
Inscription gratuite sur openweathermap.org. Le plan gratuit suffit (60 appels/minute, largement suffisant).
Calcul de transparence atmosphérique
transp = (1 - nuages_OWM/100) # couverture nuageuse
× (visibilité/10000) # brume/brouillard
× (1 - 0.25 × humidité/100) # vapeur d'eau
× facteur_code_météo # 0.0 si pluie, 0.3 si brume, 1.0 si clair
Localisation
La station météo OWM est choisie proche de l'observatoire mais pas exactement au même endroit (Fresnay-les-Samon est plus représentatif météorologiquement que Vimoutiers pour ce site).
9. Correction de la Lune
Problème
La Lune, surtout en phase gibbeuse ou pleine, éclaire les nuages et fausse tous les algorithmes de détection. Une pleine Lune à 45° de hauteur rend un ciel couvert indiscernable d'un ciel dégagé par simple analyse de luminosité.
Masque dynamique
La position de la Lune est calculée à chaque image avec ephem. Un masque circulaire est appliqué autour de sa position projetée sur l'image fisheye :
# Projection fisheye équidistante
r = r_max × (1 - altitude_lune / 90°)
moon_x = cx + r × sin(azimut)
moon_y = cy - r × cos(azimut)
# Rayon du masque proportionnel à la phase et l'altitude
rayon = 80 × (0.5 + phase) × (altitude/90°)
Étoiles attendues corrigées
# Facteur lunaire : réduit les étoiles visibles selon phase et altitude
moon_factor = 1 - (phase × altitude/90° × 0.75)
étoiles_attendues = star_max_ref × transparence_OWM × moon_factor
10. Intégration NINA via ninaAPI
Prérequis
- Plugin ninaAPI installé dans NINA (disponible sur le gestionnaire de plugins NINA)
- API activée dans les paramètres du plugin (port 1888 par défaut)
- Les deux PC (observatoire et télescope) sur le même réseau local
Endpoints utilisés (API v2)
| Endpoint | Données récupérées |
|---|---|
GET /v2/api/equipment/camera/info |
Température capteur, gain, setpoint |
GET /v2/api/equipment/mount/info |
RA, DEC, Alt, Az, statut parking |
GET /v2/api/equipment/guider/info |
RMS guidage RA et DEC |
GET /v2/api/equipment/focuser/info |
Position, température |
GET /v2/api/sequence/json |
Nom séquence, statut, progression |
Contournement CORS
NINA tourne sur 192.168.1.21:1888, le dashboard sur 86.241.95.110:8888. Le navigateur bloque les requêtes cross-origin entre ces deux origines. Solution : le programme Python proxyfie les appels NINA via son serveur HTTP interne (port 8890) qui ajoute les headers CORS appropriés.
Navigateur → GET http://86.241.95.110:8890/nina/camera
│
Python :8890 → GET http://192.168.1.21:1888/v2/api/equipment/camera/info
│
└── Réponse + header Access-Control-Allow-Origin: *
Depuis internet : le port 8890 n'est pas exposé sur internet (sécurité). Les données NINA sont uploadées toutes les 30 secondes sur Infomaniak via FTP, et affichées via une iframe nina_iframe.html hébergée sur le même domaine.
Affichage
11. Publication sur serveur web Infomaniak
Pourquoi Infomaniak ?
Le serveur web d'AllSkEye (port 8888) ne sert pas les fichiers statiques librement — il génère dynamiquement sa page HTML. Les fichiers JSON et PNG générés par le programme ne peuvent donc pas être servis directement. Infomaniak (hébergeur du site avex-asso.org) sert de relais public accessible depuis internet.
Structure des fichiers sur Infomaniak
/web/ftapissier/gevex/
├── .htaccess ← Headers CORS (uploadé au démarrage)
├── sky_status.json ← Données ciel temps réel
├── sky_cloud_chart.png ← Graphique nuages 2h
├── sky_star_chart.png ← Graphique étoiles 2h
├── sky_status_iframe.html ← Page HTML affichant sky_status.json
├── nina_status.json ← État NINA temps réel
├── nina_iframe.html ← Page HTML affichant nina_status.json
├── history_status.json ← Historique 30 dernières nuits
├── sky_history_chart.png ← Graphique historique
└── history_iframe.html ← Page HTML affichant l'historique
Upload automatique FTP TLS
Le programme uploade automatiquement après chaque analyse (~1 min) :
- Upload principal : 6 fichiers (status JSON + PNG)
- Upload NINA :
nina_status.jsontoutes les 30 secondes - Upload historique : à chaque clôture de nuit (aube)
- Upload
.htaccess: une seule fois au démarrage
.htaccess CORS
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "GET, OPTIONS"
Header always set Cache-Control "no-cache, no-store, must-revalidate"
Principe des iframes
Les pages *_iframe.html sont servies depuis avex-asso.org et font leurs fetch() vers des fichiers JSON sur le même domaine — pas de CORS. Ces pages sont ensuite intégrées en <iframe> dans le dashboard AllSkEye.
📸 [Capture : arborescence Infomaniak via FileZilla]
12. Historique multi-nuits
Fonctionnement
Le programme accumule les mesures nuit par nuit dans un accumulateur en mémoire. La clôture d'une nuit est déclenchée automatiquement lors de la transition nuit→jour (détectée quand sun_alt > -6° après une période nocturne).
Données enregistrées par nuit
{
"date": "2026-05-10",
"start": "22:15",
"cloud_avg": 45.2,
"cloud_min": 12.3,
"stars_max": 487,
"stars_avg": 312,
"transp_avg": 0.654,
"clear_mins": 180,
"n_measures": 420
}
| Champ | Signification |
|---|---|
cloud_avg |
Couverture nuageuse moyenne sur toute la nuit |
cloud_min |
Meilleure fenêtre de la nuit (% minimum) |
stars_max |
Nombre max d'étoiles détectées en une image |
clear_mins |
Durée cumulée avec nuages < 30% |
transp_avg |
Transparence atmosphérique OWM moyenne |
Persistance
L'historique est sauvegardé dans D:\AllSkEye\night_history.json (60 nuits maximum). Il survit aux redémarrages du programme.
Affichage
📸 [Capture : panneau historique avec tableau et graphiques]
13. Démarrage automatique Windows
Méthode : Planificateur de tâches Windows
Le programme Python tourne comme une tâche planifiée Windows, démarrée automatiquement au démarrage du PC avec les droits SYSTEM (équivalent administrateur, sans session utilisateur ouverte).
Création de la tâche (terminal admin)
C:\Windows\System32\schtasks.exe /create ^
/tn "GEVEX Allsky Analyzer" ^
/tr "\"C:\Users\fredo\AppData\Local\Python\pythoncore-3.14-64\python.exe\" \"D:\AllSkEye\allsky_analyzer.py\"" ^
/sc onstart /ru SYSTEM /rl HIGHEST /f
Commandes de gestion
:: Démarrer
C:\Windows\System32\schtasks.exe /run /tn "GEVEX Allsky Analyzer"
:: Arrêter
C:\Windows\System32\schtasks.exe /end /tn "GEVEX Allsky Analyzer"
:: Statut
C:\Windows\System32\schtasks.exe /query /tn "GEVEX Allsky Analyzer"
:: Supprimer
C:\Windows\System32\schtasks.exe /delete /tn "GEVEX Allsky Analyzer" /f
Logs
Le programme génère D:\AllSkEye\allsky_analyzer.log avec rotation automatique :
- Taille max : 5 Mo par fichier
- Archives gardées : 3 (
.log.1,.log.2,.log.3) - Total max : ~20 Mo
14. Structure des fichiers
PC Observatoire (D:\AllSkEye\)
D:\AllSkEye\
├── allsky_analyzer.py ← Programme principal Python
├── masque_etoile_pour_Claude.png ← Masque paysage (PNG N&B 3096×2080)
├── masque_etoile_pour_Claude.png ← Masque zones à exclure (arbres, bâtiments)
├── sky_status.json ← Données ciel générées
├── sky_cloud_chart.png ← Graphique nuages
├── sky_star_chart.png ← Graphique étoiles
├── nina_status.json ← État NINA
├── history_status.json ← Historique 30 nuits
├── sky_history_chart.png ← Graphique historique
├── night_history.json ← Base historique (60 nuits)
├── star_max_ref.json ← Référence auto-calibrée
└── allsky_analyzer.log ← Logs (rotation 5Mo × 3)
AllSkEye (C:\Program Files\AllSkEye_0.9.29.2\)
├── allskeyestatus.html ← Dashboard (modifié)
├── sky_status_iframe.html ← Iframe données ciel
├── nina_iframe.html ← Iframe NINA
└── history_iframe.html ← Iframe historique
Masque PNG
Le masque est créé manuellement dans Photoshop à la résolution exacte des images JPG (3096×2080 px). Il exclut :
- La structure de l'abri (haut droite)
- Les arbres (bas gauche et bas droite)
- La lumière parasite (bas droite)
- Le bord circulaire de l'optique fisheye
Important : bords nets obligatoires (pas de flou, pas de dégradé). Utiliser Image → Réglages → Seuil dans Photoshop avant export.
15. Dépannage
Le programme ne démarre pas
PermissionError: C:\Program Files\AllSkEye_0.9.29.2\allsky_analyzer.log
→ Lancer le terminal en administrateur
Le masque est introuvable
ERROR Masque introuvable : D:\AllSkEye\masque_etoile_pour_Claude.png
→ Vérifier que le fichier masque est bien dans D:\AllSkEye\
Les données ciel ne s'affichent pas sur le dashboard
- Vérifier que
https://avex-asso.org/ftapissier/gevex/sky_status.jsonest accessible - Vérifier dans le log la présence de lignes
FTP ✓ - Vérifier que
history_iframe.html,sky_status_iframe.htmletnina_iframe.htmlsont présents sur Infomaniak
NINA affiche "hors ligne"
- Vérifier que NINA est lancé et que le plugin ninaAPI est actif
- NINA doit être sur
192.168.1.21:1888(configurable dansNINA_BASEdu programme) - Depuis internet, le panneau NINA se met à jour toutes les 30 secondes via Infomaniak
La couverture nuageuse est incorrecte de nuit
- Vérifier que OWM répond (ligne
OWM [...]dans le log) - La calibration
star_max_refs'affine au fil des nuits — normale au début - Avec pleine Lune, les valeurs sont moins précises (phénomène physique)
L'historique reste vide
- Normal jusqu'à la première transition nuit→jour complète
- Vérifier la présence de
D:\AllSkEye\night_history.jsonaprès une nuit
16. Évolutions possibles
Court terme
- Alertes email/SMS : notification quand le ciel passe de nuageux à dégagé la nuit
- LiveView NINA : affichage de l'image en cours d'acquisition (endpoint
liveviewde ninaAPI) - SQM : affichage de la qualité du ciel depuis les données AllSkEye
Moyen terme
- Safety Monitor ASCOM : coupler l'analyse nuageuse à NINA via un driver ASCOM Safety Monitor — NINA arrêterait automatiquement la séquence si le ciel se couvre
- Prévision de transparence : croiser les données OWM prévisionnelles avec la transparence historique pour prédire les meilleures fenêtres d'observation
Long terme
- Machine Learning : entraîner un modèle sur les paires (image allsky → % nuages réel) pour une détection plus précise que les méthodes HSV/variance
- Multi-sites : étendre le dashboard à d'autres gîtes astronomiques AVEX
Crédits et références
- AllSkEye : https://allskeye.com
- NINA : https://nighttime-imaging.eu/
- ninaAPI : https://github.com/christian-photo/ninaAPI
- OpenWeatherMap : https://openweathermap.org
- ephem (bibliothèque Python) : https://rhodesmill.org/pyephem/
- meteoblue (carte interactive) : https://www.meteoblue.com
- Météo-France (widget prévisions) : https://meteofrance.com
- moonphase.guide (widget lunaire) : https://moonphase.guide
- zeitverschiebung.net (widget horloge) : https://www.zeitverschiebung.net
Documentation générée avec l'assistance de Claude (Anthropic) — Mai 2026
Gîte AVEX / GEVEX — Vimoutiers, Normandie — ftapissier@gmail.com





No comments to display
No comments to display