#!/usr/bin/env python3 """ Script de démonstration de toutes les fonctions du datamodel IndicePollen Utilise les données réelles de l'API pour Tomblaine (aujourd'hui) Idéal pour documentation et exemples """ from atmo_data_wrapper import AtmoDataClient, AtmoDataException from atmo_data_wrapper import CODE_TAXON from datetime import datetime import sys def demo_pollen_functions(): """Démonstration complète des fonctions IndicePollen avec données réelles""" # Configuration CODE_INSEE_TOMBLAINE = "54526" AASQA_GRAND_EST = "44" today = datetime.now().strftime('%Y-%m-%d') print("🌸 DÉMONSTRATION DES FONCTIONS INDICEPOLLEN") print("=" * 55) print(f"📍 Ville: Tomblaine (INSEE: {CODE_INSEE_TOMBLAINE})") print(f"🗓️ Date: {today}") print(f"🏛️ AASQA: {AASQA_GRAND_EST} (Grand Est)") print() try: # Connexion et récupération des données print("🔐 Connexion à l'API...") client = AtmoDataClient() success = client.auto_login() if not success: print("❌ Échec de la connexion à l'API") return False print("✅ Connecté avec succès !") # Récupération des données pollen print(f"🌸 Récupération des indices pollen pour {today}...") pollens = client.get_indices_pollens( format="geojson", date=today, aasqa=AASQA_GRAND_EST, code_zone=CODE_INSEE_TOMBLAINE, with_geom=False ) if not pollens or len(pollens) == 0: print("❌ Aucune donnée pollen trouvée") return False print(f"✅ {len(pollens)} station(s) trouvée(s)") # Utiliser la première station pour la démo pollen = pollens[0] print(f"📍 Station sélectionnée: {pollen.lib_zone}") print() # === DÉMONSTRATION DES PROPRIÉTÉS DE BASE === print("📊 === PROPRIÉTÉS DE BASE (héritées d'AtmoDataBase) ===") print() print("🏛️ INFORMATIONS GÉNÉRALES:") print(f" • AASQA: {pollen.aasqa}") print(f" • Zone: {pollen.lib_zone}") print(f" • Source: {pollen.source}") print(f" • Alerte active: {pollen.alerte}") print() print("🗺️ COORDONNÉES:") if pollen.has_coordinates(): coords = pollen.get_coordinates() print(f" • Latitude: {coords.latitude:.6f}") print(f" • Longitude: {coords.longitude:.6f}") else: print(" • Pas de coordonnées disponibles") print() print("🎨 FONCTIONS CENTRALISÉES:") for level in [0, 1, 2, 3, 4]: emoji_round = pollen.get_emoji_by_level(level, "round") emoji_square = pollen.get_emoji_by_level(level, "square") color_hex, color_rgb = pollen.get_color_by_level(level) print(f" • Niveau {level}: {emoji_round}{emoji_square} {color_hex} {color_rgb}") print() # === DÉMONSTRATION DES PROPRIÉTÉS SPÉCIFIQUES POLLEN === print("🌿 === PROPRIÉTÉS SPÉCIFIQUES POLLEN ===") print() print("📈 CODES PAR TAXON:") print(f" • Ambroisie (ambr): {pollen.code_ambr}") print(f" • Armoise (arm): {pollen.code_arm}") print(f" • Aulne (aul): {pollen.code_aul}") print(f" • Bouleau (boul): {pollen.code_boul}") print(f" • Graminées (gram): {pollen.code_gram}") print(f" • Olivier (oliv): {pollen.code_oliv}") print() print("🔬 CONCENTRATIONS (grains/m³):") print(f" • Ambroisie: {pollen.conc_ambr:.1f}") print(f" • Armoise: {pollen.conc_arm:.1f}") print(f" • Aulne: {pollen.conc_aul:.1f}") print(f" • Bouleau: {pollen.conc_boul:.1f}") print(f" • Graminées: {pollen.conc_gram:.1f}") print(f" • Olivier: {pollen.conc_oliv:.1f}") print() print("🎯 TAXONS RESPONSABLES DE L'INDICE:") print(f" • pollen_resp (raw): '{pollen.pollen_resp}'") print() # === DÉMONSTRATION DES MÉTHODES HELPER === print("🛠️ === MÉTHODES HELPER ===") print() # 1. is_alert_active() print("🚨 1. DÉTECTION D'ALERTE:") alert_active = pollen.is_alert_active() print(f" • is_alert_active(): {alert_active}") if alert_active: print(" → Alerte pollen active !") else: print(" → Pas d'alerte pollen") print() # 2. get_highest_pollen() print("🏆 2. POLLEN LE PLUS ÉLEVÉ:") highest_taxon, highest_code = pollen.get_highest_pollen() highest_name = CODE_TAXON.get(highest_taxon, highest_taxon.title()) print(f" • get_highest_pollen(): ('{highest_taxon}', {highest_code})") print(f" → Espèce: {highest_name}") print(f" → Niveau: {highest_code}") print() # 3. get_highest_concentration() print("🔬 3. CONCENTRATION LA PLUS ÉLEVÉE:") highest_conc_taxon, highest_conc_value = pollen.get_highest_concentration() highest_conc_name = CODE_TAXON.get(highest_conc_taxon, highest_conc_taxon.title()) print(f" • get_highest_concentration(): ('{highest_conc_taxon}', {highest_conc_value})") print(f" → Espèce: {highest_conc_name}") print(f" → Concentration: {highest_conc_value:.1f} grains/m³") print() # 4. get_dangerous_pollens() print("⚠️ 4. POLLENS DANGEREUX (niveau ≥ 4):") dangerous = pollen.get_dangerous_pollens() print(f" • get_dangerous_pollens(): {dangerous}") if dangerous: dangerous_names = [CODE_TAXON.get(p, p.title()) for p in dangerous] print(f" → Espèces à risque: {', '.join(dangerous_names)}") else: print(" → Aucun pollen à risque élevé") print() # 5. get_responsible_pollens() - NOUVELLE MÉTHODE print("🎯 5. TAXONS RESPONSABLES DE L'INDICE (API):") responsible = pollen.get_responsible_pollens() print(f" • get_responsible_pollens(): {responsible}") if responsible: print(f" → Espèces responsables selon l'API: {', '.join(responsible)}") else: print(" → Aucun taxon responsable spécifié par l'API") print() # 6. get_concentrations() print("📊 6. TOUTES LES CONCENTRATIONS:") concentrations = pollen.get_concentrations() print(f" • get_concentrations(): {concentrations}") print(" → Détail:") for taxon, conc in concentrations.items(): taxon_name = CODE_TAXON.get(taxon, taxon.title()) print(f" - {taxon_name}: {conc:.1f} grains/m³") print() # 7. get_pollens_summary() print("📋 7. RÉSUMÉ COMPLET:") summary = pollen.get_pollens_summary() print(f" • get_pollens_summary():") print(" → Structure complète par taxon:") for code_taxon, info in summary.items(): if info['code'] > 0: # Afficher seulement les pollens détectés print(f" - {code_taxon}:") print(f" * Code: {info['code']}") print(f" * Espèce: {info['espece']}") print(f" * Qualificatif: {info['qualificatif']}") print(f" * Concentration: {info['concentration']:.1f} gr/m³") print(f" * Couleur: {info['couleur']}") print(f" * Émoji rond: {info['emoji_round']}") print(f" * Émoji carré: {info['emoji_square']}") print() # 8. Test des styles d'émojis print("🎨 8. TEST DES STYLES D'ÉMOJIS:") summary_round = pollen.get_pollens_summary("round") summary_square = pollen.get_pollens_summary("square") print(" • Comparaison des styles par défaut:") for code_taxon in ['arm', 'gram']: # Tester avec les pollens détectés if summary_round[code_taxon]['code'] > 0: round_emoji = summary_round[code_taxon]['emoji'] square_emoji = summary_square[code_taxon]['emoji'] espece = summary_round[code_taxon]['espece'] print(f" - {espece}: Rond={round_emoji} | Carré={square_emoji}") print() # === DÉMONSTRATION DES MÉTHODES STRING === print("📝 === REPRÉSENTATION STRING ===") print() print("🔤 MÉTHODE __str__():") print(f" • str(pollen): '{str(pollen)}'") print() # === EXEMPLES D'UTILISATION PRATIQUE === print("💡 === EXEMPLES D'UTILISATION PRATIQUE ===") print() print("🎯 ANALYSE RAPIDE:") print(f" • Niveau global le plus élevé: {highest_name} (niveau {highest_code})") print(f" • Concentration maximale: {highest_conc_name} ({highest_conc_value:.1f} gr/m³)") if alert_active: print(" • ⚠️ ALERTE ACTIVE - Précautions recommandées") if dangerous: print(f" • 🚨 POLLENS À RISQUE: {', '.join([CODE_TAXON.get(p, p) for p in dangerous])}") else: print(" • ✅ Aucun pollen à risque élevé") print() print("📈 DÉTECTION DE TENDANCES:") detected_pollens = [taxon for taxon, info in summary.items() if info['code'] > 0] significant_pollens = [taxon for taxon, info in summary.items() if info['code'] >= 2] print(f" • Pollens détectés: {len(detected_pollens)} espèces") print(f" • Pollens significatifs (≥2): {len(significant_pollens)} espèces") if significant_pollens: sig_names = [CODE_TAXON.get(p, p) for p in significant_pollens] print(f" → {', '.join(sig_names)}") print() print("🔍 FILTRAGE AVANCÉ:") # Exemple de filtrage par concentration high_conc = {t: c for t, c in concentrations.items() if c > 5.0} if high_conc: print(" • Concentrations élevées (>5 gr/m³):") for taxon, conc in high_conc.items(): taxon_name = CODE_TAXON.get(taxon, taxon.title()) print(f" → {taxon_name}: {conc:.1f} gr/m³") else: print(" • Aucune concentration élevée (>5 gr/m³)") print() # === INFORMATIONS TECHNIQUES === print("🔧 === INFORMATIONS TECHNIQUES ===") print() print("📦 STRUCTURE DE DONNÉES:") print(f" • Type d'objet: {type(pollen).__name__}") print(f" • Classe parente: {type(pollen).__bases__[0].__name__}") print(f" • Propriétés disponibles: {len(pollen.properties)} champs") print(f" • Géométrie: {'Oui' if pollen.has_coordinates() else 'Non'}") print() print("🎨 MÉTHODES HÉRITÉES:") inherited_methods = [ 'get_emoji_by_level()', 'get_color_by_level()', 'has_coordinates()', 'get_coordinates()', 'get_source()' ] print(f" • Méthodes de AtmoDataBase: {', '.join(inherited_methods)}") print() specific_methods = [ 'is_alert_active()', 'get_highest_pollen()', 'get_highest_concentration()', 'get_dangerous_pollens()', 'get_responsible_pollens()', 'get_concentrations()', 'get_pollens_summary()' ] print(f" • Méthodes spécifiques IndicePollen: {', '.join(specific_methods)}") print() print("🎨 NOUVEAUTÉS ÉMOJIS:") print(" • get_emoji_by_level(level, style) - style='round'|'square'") print(" • get_emoji(style) - pour IndiceAtmo avec choix de style") print(" • get_pollens_summary(emoji_style) - résumé avec style d'émoji") print(" • Chaque résumé inclut emoji_round ET emoji_square") print() print("📋 CONFORMITÉ NOTICE OFFICIELLE (1er avril 2025):") print(" • Tous les champs de la notice officielle sont supportés") print(" • Classes IndiceAtmo et IndicePollen conformes aux spécifications") print(" • Nouvelles propriétés pour IndiceAtmo : type_zone, coordonnées réglementaires") print(" • Concentrations facultatives ajoutées selon la notice") print(" • Méthodes basées sur les règles officielles de calcul") print(" • Codes couleur et qualificatifs conformes au tableau page 6") print() print("✅ === DÉMONSTRATION TERMINÉE ===") print() print("📚 Ce script illustre toutes les fonctionnalités de la classe IndicePollen") print("🔧 Utilisez ces exemples pour votre documentation et vos développements") print() return True except AtmoDataException as e: print(f"❌ Erreur API: {e}") return False except Exception as e: print(f"❌ Erreur inattendue: {e}") import traceback traceback.print_exc() return False def main(): """Point d'entrée principal""" print("🌸 Démonstration des fonctions IndicePollen") print("=" * 55) print() success = demo_pollen_functions() if not success: print("\n❌ La démonstration s'est terminée avec des erreurs") sys.exit(1) else: print("🎉 Démonstration terminée avec succès !") sys.exit(0) if __name__ == "__main__": main()