From 6989a49f6489e3466c0946b0e97cb9ba3b7ef9de Mon Sep 17 00:00:00 2001 From: "Matt Johnson (via Claude)" Date: Wed, 10 Jun 2026 06:04:56 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20periodic=20health=20broadcast=20missing?= =?UTF-8?q?=20pillars=20=E2=80=94=20add=20full=20score=20payload=20+=20val?= =?UTF-8?q?idity=20gate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The periodic health_update in main.py only sent score/tier/totals but no pillars dict. Dashboard setHealth() replaced the full REST response with this incomplete object, causing all pillar bars to drop to 0.0. Now sends the complete payload matching mesh_routes.py and ws.py (pillars, util_percent, flagged_nodes, battery_warnings, recommendations) and gates on composite > 0 + infra_total > 0 to skip partial state. Co-Authored-By: Claude Opus 4.6 --- meshai/main.py | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/meshai/main.py b/meshai/main.py index 4dd6e5d..ad1dc2d 100644 --- a/meshai/main.py +++ b/meshai/main.py @@ -126,16 +126,30 @@ class MeshAI: if self.broadcaster and self.health_engine.mesh_health: try: mh = self.health_engine.mesh_health - health_dict = { - "score": round(mh.score.composite, 1), - "tier": mh.score.tier, - "total_nodes": mh.total_nodes, - "total_regions": mh.total_regions, - "infra_online": mh.score.infra_online, - "infra_total": mh.score.infra_total, - "last_computed": mh.last_computed, - } - await self.broadcaster.broadcast("health_update", health_dict) + sc = mh.score + if sc.composite > 0 and sc.infra_total > 0: + health_dict = { + "score": round(sc.composite, 1), + "tier": sc.tier, + "pillars": { + "infrastructure": round(sc.infrastructure, 1), + "utilization": round(sc.utilization, 1), + "coverage": round(sc.coverage, 1), + "behavior": round(sc.behavior, 1), + "power": round(sc.power, 1), + }, + "infra_online": sc.infra_online, + "infra_total": sc.infra_total, + "util_percent": round(sc.util_percent, 1), + "flagged_nodes": sc.flagged_nodes, + "battery_warnings": sc.battery_warnings, + "total_nodes": mh.total_nodes, + "total_regions": mh.total_regions, + "unlocated_count": getattr(mh, "unlocated_count", 0), + "last_computed": mh.last_computed, + "recommendations": getattr(mh, "recommendations", []), + } + await self.broadcaster.broadcast("health_update", health_dict) except Exception as e: logger.debug("Dashboard broadcast error: %s", e)