Skip to content

Commit 3808907

Browse files
julienldclaude
andauthored
fix: query area/entity registries for accurate area count in overview (#216)
The ha_get_overview tool was returning total_areas: 0 because it tried to get area_id from entity state attributes, but Home Assistant stores area assignments in the entity registry, not state attributes. This fix: - Queries config/area_registry/list for accurate total_areas count - Queries config/entity_registry/list to build entity-to-area mappings - Uses entity registry data for area_analysis instead of state attributes Fixes #203 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
1 parent c570bdf commit 3808907

1 file changed

Lines changed: 33 additions & 3 deletions

File tree

src/ha_mcp/tools/smart_search.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,36 @@ async def get_system_overview(
240240
entities = await self.client.get_states()
241241
services = await self.client.get_services()
242242

243+
# Get area registry and entity registry for proper area mapping
244+
# Areas exist in the registry, not in entity state attributes
245+
area_registry: list[dict[str, Any]] = []
246+
entity_registry: list[dict[str, Any]] = []
247+
try:
248+
area_result = await self.client.send_websocket_message(
249+
{"type": "config/area_registry/list"}
250+
)
251+
if area_result.get("success"):
252+
area_registry = area_result.get("result", [])
253+
except Exception as e:
254+
logger.debug(f"Could not fetch area registry: {e}")
255+
256+
try:
257+
entity_result = await self.client.send_websocket_message(
258+
{"type": "config/entity_registry/list"}
259+
)
260+
if entity_result.get("success"):
261+
entity_registry = entity_result.get("result", [])
262+
except Exception as e:
263+
logger.debug(f"Could not fetch entity registry: {e}")
264+
265+
# Build entity_id -> area_id mapping from entity registry
266+
entity_area_map: dict[str, str | None] = {}
267+
for entry in entity_registry:
268+
entity_id = entry.get("entity_id")
269+
area_id = entry.get("area_id")
270+
if entity_id:
271+
entity_area_map[entity_id] = area_id
272+
243273
# Determine defaults based on detail_level
244274
if max_entities_per_domain is None:
245275
max_entities_per_domain = 10 if detail_level == "minimal" else None
@@ -285,8 +315,8 @@ async def get_system_overview(
285315

286316
domain_stats[domain]["all_entities"].append(entity_data)
287317

288-
# Area analysis
289-
area_id = attributes.get("area_id")
318+
# Area analysis - use entity registry mapping, not state attributes
319+
area_id = entity_area_map.get(entity_id)
290320
if area_id:
291321
if area_id not in area_stats:
292322
area_stats[area_id] = {"count": 0, "domains": {}}
@@ -374,7 +404,7 @@ async def get_system_overview(
374404
"total_entities": len(entities),
375405
"total_domains": len(domain_stats),
376406
"total_services": total_services,
377-
"total_areas": len(area_stats),
407+
"total_areas": len(area_registry),
378408
},
379409
"domain_stats": formatted_domain_stats,
380410
"area_analysis": area_stats, # Now included in all detail levels

0 commit comments

Comments
 (0)