diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart index 574f953..ab3acb2 100644 --- a/lib/screens/dashboard_screen.dart +++ b/lib/screens/dashboard_screen.dart @@ -48,18 +48,7 @@ class _DashboardScreenState extends State { @override void initState() { super.initState(); - WidgetsBinding.instance.addPostFrameCallback((_) { - _lireBilan(); - // ⚠️ La configuration des charges n'était chargée QUE par l'écran des rôles. Le - // détail de consommation en a besoin — c'est elle qui porte le `domain` de chaque - // charge — et sans elle il affichait « non publié » sur des charges que la box - // publiait bel et bien. Une absence côté app présentée comme une absence côté box : - // le défaut qu'on vient de corriger, reproduit un cran plus loin. - final svc = context.read(); - context.read() - ..attach(svc) - ..load(); - }); + WidgetsBinding.instance.addPostFrameCallback((_) => _lireBilan()); _tick = Timer.periodic(_periode, (_) => _lireBilan()); } @@ -72,6 +61,22 @@ class _DashboardScreenState extends State { Future _lireBilan() async { if (!mounted) return; final svc = context.read(); + // ── La configuration des charges, et pourquoi ICI plutôt qu'au montage ────── + // + // Le détail de consommation a besoin du `domain` de chaque charge, porté par + // `GetLoadConfig` — sans lui, il affiche « non publié » sur des charges que la box + // publie : une absence côté APP présentée comme une absence côté BOX. + // + // Un chargement unique au montage ne suffit pas : l'écran se construit avant que la + // connexion soit établie, l'appel échoue en silence, et **rien ne réessaie**. Vérifié + // à l'écran le 2026-09-06 — le correctif « charger au montage » n'a rien changé. + // Accroché au tick, il se rattrape de lui-même dès que la box répond. + final cfg = context.read(); + if (cfg.entries.isEmpty) { + cfg + ..attach(svc) + ..load(); + } // Les ratios de la box sont lus à côté du bilan, pas à sa place : ils ne couvrent pas // la même fenêtre, et c'est justement ce que l'écran doit pouvoir dire. final r = await svc.fetchEnergyRatios(); @@ -114,10 +119,30 @@ class _DashboardScreenState extends State { return out; } + /// Vrai une fois la configuration demandée avec une box joignable — évite de relancer + /// l'appel à chaque trame pendant que la réponse arrive. + bool _configDemandee = false; + + /// Le tick est à cinq minutes : trop lent pour un premier chargement. On se raccroche + /// donc aussi au moment où la box devient joignable, une seule fois. + void _assurerConfig(NymeaService service) { + if (_configDemandee || !service.isConnected) return; + final cfg = context.read(); + if (cfg.entries.isNotEmpty) return; + _configDemandee = true; + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) return; + cfg + ..attach(service) + ..load(); + }); + } + @override Widget build(BuildContext context) { return Consumer( builder: (context, service, _) { + _assurerConfig(service); final data = service.energyData; return Scaffold( backgroundColor: EtmTokens.bgOf(context),