Dependency Mapping & Impact Analysis for Home Assistant
EntityMap is a Home Assistant custom integration that answers a simple question: "What depends on what in my smart home?"
It scans your entire configuration — devices, entities, automations, scripts, scenes, helpers, groups — and builds a live dependency graph. Then it shows you, visually and interactively, how everything is connected. Before you replace a Zigbee device, disable an entity, or refactor an automation, EntityMap tells you exactly what will break.
- What depends on this device? — See every automation, script, and scene that references it
- Is anything broken right now? — Find missing entities, stale references, gone devices
- How risky is this change? — Risk score from 0-100 with severity classification
- How do I safely replace this? — Step-by-step migration guidance
- Are my automations fragile? — Detect device_id references, tight coupling, hidden dependencies
Unlike manually searching through YAML files, EntityMap gives you a complete, interactive dependency graph with one-click impact analysis — all 100% local, read-only, and instant.
- Key Features
- Screenshots
- Installation
- Supported Home Assistant Versions
- Supported Languages
- Configuration Guide
- Using the Graph Panel
- Entities Explained
- Services
- Ready-Made Dashboard
- Impact Analysis
- Fragility Detection
- Example Use Cases
- Troubleshooting
- FAQ
- Limitations & Known Tradeoffs
- Privacy & Security
- Architecture
- Development
- Contributing
- License
- Changelog
- Interactive dependency graph — Zoomable, draggable force-directed visualization with color-coded node types
- Hierarchy view — Area → Device → Entity tree with list and visual D3 tree modes (horizontal & vertical)
- Impact analysis — Select any node to see exactly what breaks if you remove, disable, or replace it
- Fragility detection — Automatically find device_id references, missing entities, stale references, tight coupling
- Migration guidance — Step-by-step recommendations for safely replacing devices or entities
- Repair issues — Actionable warnings surfaced in Home Assistant's Repairs dashboard
- Three services —
entitymap.scan,entitymap.analyze_impact,entitymap.get_dependencies - Summary sensors — Total nodes, total dependencies, fragility issue count, last scan time
- WebSocket API — Full programmatic access for custom dashboards and automations
- Fully async — No blocking I/O; uses async adapters for all registry and config access
- Zero external dependencies — Uses only libraries bundled with Home Assistant
- Diagnostics support — Safe diagnostics output with sensitive data redaction
- UI configuration — Config flow and options flow, no YAML needed
Full interactive force-directed graph — every device, entity, automation, script, and scene as a connected node.
Click any node to see risk score, affected entities, and step-by-step migration guidance.
Collapsible list of Areas → Devices → Entities with entity IDs, availability badges, and counts.
Visual D3 tree layout (vertical and horizontal) — like a genealogical tree for your smart home.
Ready-made Lovelace cards — status tiles, gauges, history graphs, and a rescan button.
- Open HACS in Home Assistant
- Click the three dots menu > Custom repositories
- Add
https://github.com/polprog-tech/EntityMapas an Integration - Search for "EntityMap" and install
- Restart Home Assistant
- Go to Settings > Devices & Services > Add Integration > search for EntityMap
- Download or clone this repository
- Copy
custom_components/entitymap/to your Home Assistantconfig/custom_components/directory - Restart Home Assistant
- Go to Settings > Devices & Services > Add Integration > search for EntityMap
Minimum: Home Assistant 2025.1.0
EntityMap is fully translated and adapts to your Home Assistant language setting.
| Language | Code | Status |
|---|---|---|
| 🇬🇧 English | en |
✅ Complete |
| 🇵🇱 Polish (Polski) | pl |
✅ Complete |
All UI elements are translated: config flow, options flow, entity names, error messages, repair issues, and service descriptions.
Want to add your language? Copy custom_components/entitymap/translations/en.json, translate the values, save as {language_code}.json, and open a PR. See CONTRIBUTING.md for details.
- Go to Settings > Devices & Services > Add Integration
- Search for EntityMap
- You'll see the setup form with default options
| Setting | Default | What it does |
|---|---|---|
| Scan on startup | ✅ On | Runs a full dependency scan when Home Assistant starts |
| Auto refresh | ✅ On | Automatically rescans when device/entity registries change |
| Scan interval | 6 hours | How often to run a periodic reconciliation scan |
| Include templates | ✅ On | Parse template entity configs for entity references (regex-based) |
| Include groups | ✅ On | Include group membership edges in the graph |
Tip: The defaults work well for most installations. Start with them and adjust later if needed.
After adding the integration, EntityMap automatically runs a full scan. This typically takes under 2 seconds. Once complete:
- The EntityMap panel appears in your sidebar
- Summary sensors are created under the EntityMap device
- Fragility findings (if any) appear in the Repairs dashboard
Go to Settings > Devices & Services > EntityMap > Configure to adjust scan interval, toggle template/group scanning, or change auto-refresh behavior.
EntityMap adds a panel to your Home Assistant sidebar. Here's what you can do:
- Pan and zoom — Scroll to zoom, drag the background to pan
- Drag nodes — Click and drag any node to rearrange the layout
- Click a node — Opens the detail panel with impact analysis, fragility findings, and migration guidance
- Filter by type — Use the chips at the top to show/hide specific node types (devices, entities, automations, etc.)
- Search — Type in the search box to filter nodes by name or ID; neighbors of matched nodes are shown too
- Switch to the Issues tab to see all fragility findings as a card grid
- Cards are color-coded by severity (critical, high, medium, low, info)
- Click any card to jump to the affected node in the graph view
- Switch to the Hierarchy tab to browse your setup organized by Area → Device → Entity
- List mode — Collapsible sections per area with device/entity counts, entity IDs, and availability badges; expand/collapse all with one click
- Tree mode — Visual D3 tree layout; toggle between ↔ Horizontal and ↕ Vertical orientation; zoom, pan, and click any node to jump to the graph view
When you click a node, the right panel shows:
- Node identity — Type badge, name, entity ID, availability status
- Impact analysis — Risk meter (0-100%), severity, affected entity counts by type
- Fragility findings — Issues specific to this node with severity and remediation
- Migration guidance — Step-by-step recommendations if you're planning to replace or remove this entity/device
EntityMap creates a single device called EntityMap with the following entities:
| Entity | Type | What it shows |
|---|---|---|
| Total nodes | Sensor | Number of nodes in the dependency graph (devices, entities, automations, etc.) |
| Total edges | Sensor | Number of dependency relationships discovered |
| Fragility issues | Sensor | Number of fragility findings across the entire graph. 0 = clean |
| Last scan | Sensor | Timestamp of the most recent completed scan |
| Entity | What it does |
|---|---|
| Rescan | Button entity that triggers an immediate full dependency scan. Use after making configuration changes to get fresh results without waiting for the next scheduled scan. |
| Entity | Entity ID |
|---|---|
| Total nodes | sensor.entitymap_total_nodes |
| Total edges | sensor.entitymap_total_edges |
| Fragility issues | sensor.entitymap_fragility_issues |
| Last scan | sensor.entitymap_last_scan |
| Rescan | button.entitymap_rescan |
Entity IDs are set via suggested_object_id in the code and are always English regardless of your Home Assistant language setting. The language setting only affects display names shown in the UI — the underlying entity IDs remain stable.
Trigger a full dependency scan. Returns node and edge counts.
service: entitymap.scanAnalyze what would break if a specific node were removed, disabled, or replaced.
service: entitymap.analyze_impact
data:
node_id: "light.living_room"Returns: risk score, severity, affected entities by type, fragility findings, migration suggestions.
Get inbound and outbound dependencies for a specific node.
service: entitymap.get_dependencies
data:
node_id: "automation.motion_light"
include_inferred: trueReturns: lists of nodes that this entity depends on, and nodes that depend on it.
When you select a node in the graph (or call entitymap.analyze_impact), EntityMap:
- Finds direct dependents — objects that explicitly reference the target
- Traces transitive dependents — the full chain of objects affected downstream
- Calculates a risk score (0-100) based on dependent count, object types, and reference fragility
- Assigns severity — Critical (≥70), High (≥50), Medium (≥25), Low (>0), Info (0)
- Generates migration suggestions based on the types of dependencies found
| Scenario | Risk | Severity |
|---|---|---|
| Light with no dependents | 0% | Info |
| Entity used in 1 automation | ~15% | Low |
| Device used in 5 automations + 2 scripts | ~65% | High |
| Core entity with 10+ transitive dependents | ~85% | Critical |
EntityMap automatically detects these fragility patterns on every scan:
| Finding | Severity | What it means |
|---|---|---|
| Missing entity reference | High | An automation references an entity that doesn't exist in the registry |
| Missing device reference | High | An automation references a device that's been removed |
| Device ID reference | Medium | Using device_id-based triggers — fragile to device re-pairing |
| Disabled reference | Low | Referencing a disabled entity (may be intentional) |
| Tight device coupling | High | 3+ device_id references to the same device in one automation |
| Hidden dependency | Info | An automation calls a script that has many sub-dependencies of its own |
Findings appear in three places:
- The Issues tab in the EntityMap panel
- The detail panel when you click an affected node
- The Home Assistant Repairs dashboard (for high/critical findings)
- Open the EntityMap panel from the sidebar
- Search for your device name
- Click the device node
- Review the impact panel — see every automation, script, and scene affected
- Follow the migration guidance checklist
- Switch to the Issues tab in the EntityMap panel
- Review findings sorted by severity
- Click a finding to jump to the affected node in the graph
- Fix the broken reference in the automation/script editor
- Check the Repairs dashboard for EntityMap warnings
- Or use the Issues tab to find all
device_id_referencefindings - Consider switching to entity-based triggers for resilience against re-pairing
Before a major HA update or device ecosystem change:
# Run a scan and check the fragility sensor
service: entitymap.scanThen review sensor.entitymap_fragility_issues — if it's > 0, open the panel and address findings before proceeding.
EntityMap comes with ready-to-use cards — you can set up a full dashboard or add individual cards to any existing dashboard.
This works for any card below:
- Open any dashboard → click the pencil ✏️ icon (top right) to enter Edit mode
- Click "+ Add Card" (bottom right) → scroll down → click "Manual"
- Paste the YAML → click "Save"
That's it! The card appears on your dashboard immediately.
Tip: Entity IDs used in the examples below match what the integration creates. If you renamed an entity manually, go to Settings > Devices & Services > Entities and search "entitymap" to verify.
One card with everything — status tiles, gauges, history charts, and rescan button. Perfect for adding to your main dashboard.
Paste the contents of docs/cards/all-in-one.yaml:
type: vertical-stack
cards:
- type: grid
columns: 4
square: false
cards:
- type: tile
entity: sensor.entitymap_total_nodes
name: Nodes
icon: mdi:graph
color: blue
vertical: true
- type: tile
entity: sensor.entitymap_total_edges
name: Dependencies
icon: mdi:vector-polyline
color: cyan
vertical: true
- type: tile
entity: sensor.entitymap_fragility_issues
name: Issues
icon: mdi:alert-outline
color: orange
vertical: true
- type: tile
entity: sensor.entitymap_last_scan
name: Last Scan
icon: mdi:clock-check-outline
color: green
vertical: true
- type: grid
columns: 2
square: false
cards:
- type: gauge
entity: sensor.entitymap_total_nodes
name: "Graph Nodes"
min: 0
max: 500
needle: true
severity:
green: 0
yellow: 200
red: 400
- type: gauge
entity: sensor.entitymap_total_edges
name: "Dependencies"
min: 0
max: 1000
needle: true
severity:
green: 0
yellow: 400
red: 800
- type: history-graph
title: "📈 Graph Growth — 7 days"
hours_to_show: 168
entities:
- entity: sensor.entitymap_total_nodes
name: Nodes
- entity: sensor.entitymap_total_edges
name: Dependencies
- type: history-graph
title: "📊 Fragility Issues — 7 days"
hours_to_show: 168
entities:
- entity: sensor.entitymap_fragility_issues
name: Fragility Issues
- type: button
entity: button.entitymap_rescan
name: "🔄 Rescan Dependencies"
icon: mdi:refresh
tap_action:
action: toggle
show_state: false
icon_height: 40pxPick only the cards you need. Each file in docs/cards/ is a standalone card.
| Card | What it shows | File |
|---|---|---|
| Status Overview | 4 colored tiles: Nodes, Dependencies, Issues, Last Scan | status-overview.yaml |
| Graph Stats Gauges | Two needle gauges for nodes and dependencies | graph-stats-gauges.yaml |
| Graph Growth Chart | 7-day history graph of nodes + dependencies | graph-growth.yaml |
| Fragility History | 7-day history graph of fragility issue count | fragility-history.yaml |
| Actions & Fragility | Rescan button + fragility summary | actions-fragility.yaml |
| All-in-One | Everything in a single card | all-in-one.yaml |
If you want a separate "Dependency Health" dashboard with all cards pre-arranged:
- Go to Settings > Dashboards > Add Dashboard
- Name it "Dependency Health" and create it
- Open the new dashboard → three-dot menu (⋮) → Edit Dashboard
- Three-dot menu (⋮) again → Raw configuration editor
- Paste the contents of
docs/dashboard.yaml - Click Save
| Problem | Solution |
|---|---|
| Graph is empty | Click the Rescan button or call entitymap.scan. First scan runs automatically on startup. |
| Missing automations in the graph | Ensure automations are loaded before EntityMap starts (check after_dependencies in manifest). Restart HA if needed. |
| Panel not showing in sidebar | Clear browser cache. Check HA logs for frontend registration errors. |
| "Scan failed" repair issue | Check HA logs for adapter errors. One of the source adapters may have hit an unexpected data format. File an issue with diagnostics. |
Entities show unknown |
This is normal right after a restart — values populate after the first scan completes (usually within seconds). |
| Entity IDs don't match the docs | If you previously installed EntityMap before suggested_object_id was added, remove and re-add the integration to get the correct English entity IDs. |
If something isn't working, check Home Assistant logs:
- Go to Settings > System > Logs
- Search for
entitymap - Look for ERROR or WARNING messages
You can also enable debug logging by adding this to configuration.yaml:
logger:
logs:
custom_components.entitymap: debugDoes EntityMap modify my automations or scripts?
No. EntityMap is completely read-only. It only reads configuration data from HA registries and component stores. It never writes, modifies, or deletes anything in your setup. It's safe to install alongside any other integration.
How accurate is the template reference extraction?
EntityMap uses regex-based pattern matching to extract entity references from Jinja2 templates. This covers the common patterns — states('entity_id'), is_state(), state_attr(), and direct states.domain.entity references.
Complex templates using set variables, macros, or dynamically constructed entity IDs may be missed. EntityMap marks these references as inferred (medium confidence) in the graph so you can distinguish them from direct references.
Coverage is approximately 85% of real-world template usage. Full Jinja2 AST parsing is planned for a future release.
How often should I scan?
The default 6-hour periodic scan works well for most users. EntityMap also listens for registry change events and rescans automatically when devices or entities are added, removed, or modified.
You only need manual rescans after editing automation/script YAML — those changes don't trigger registry events.
What happens with very large installations (1000+ entities)?
The backend scan is fast — typically under 2 seconds even for large installations. The visual graph clips at 500 nodes for D3.js performance. Use the search and filter features to navigate large graphs.
If you have 5000+ entities, scans may take 3-5 seconds. The graph will show the first 500 nodes; use type filters to focus on the nodes you care about.
Can I use EntityMap data in my own automations?
Yes! You have several options:
- Sensors — Use
sensor.entitymap_fragility_issuesto trigger automations when new issues appear - Services — Call
entitymap.analyze_impactorentitymap.get_dependenciesfrom scripts - WebSocket API — For advanced use, the same WebSocket commands used by the panel are available to any WS client
Example automation that alerts when fragility issues increase:
automation:
- alias: "EntityMap - New Fragility Issues"
trigger:
- platform: numeric_state
entity_id: sensor.entitymap_fragility_issues
above: 0
action:
- service: notify.mobile_app
data:
title: "EntityMap Alert"
message: "{{ states('sensor.entitymap_fragility_issues') }} fragility issues detected."Does EntityMap require internet access?
The backend is 100% local — no internet required. However, the graph panel loads D3.js from a CDN on first use. If your HA instance has no internet access, the graph visualization won't render.
Bundling D3.js locally is planned for a future release to support fully air-gapped installations.
What is __pycache__ and how do I delete it?
Python caches compiled .pyc files in __pycache__ folders. After updating EntityMap, stale cached bytecode can cause errors. Deleting __pycache__ forces Python to recompile from updated source.
Terminal / SSH:
find /config/custom_components/entitymap -type d -name __pycache__ -exec rm -rf {} +On HA Container or Core, replace
/configwith your config path (e.g.,~/.homeassistant).
macOS Finder: Press ⌘ Cmd + Shift + . to toggle hidden files, then delete __pycache__.
Windows Explorer: Click View > Hidden items, then delete the folder.
How do I completely uninstall EntityMap?
- Go to Settings > Devices & Services > EntityMap
- Click the three dots (⋮) > Delete
- Restart Home Assistant
- Delete the
custom_components/entitymap/directory - (Optional) Remove the EntityMap panel entry from your sidebar
- Restart Home Assistant once more
If installed via HACS, use HACS to remove it instead of manually deleting files.
- Template extraction is regex-based — Complex Jinja2 templates with macros,
setvariables, or dynamic entity IDs may be missed. EntityMap marks extracted references as "inferred" confidence. - Automation configs accessed via HA APIs — EntityMap reads automation configurations through HA component APIs, not raw YAML files. If HA changes these internal APIs, adapters may need updating.
- Entity availability is a point-in-time snapshot — The
availableflag reflects status at scan time, not real-time. - Graph clips at 500 nodes — For browser performance. Use search and filters on large installations.
- D3.js loaded from CDN — Requires internet on first panel load. Offline bundling is planned.
- Single config entry — Only one EntityMap instance per HA installation.
- All processing is local — No data is sent to external services
- No telemetry — EntityMap does not collect or transmit usage data
- Read-only — EntityMap never modifies your automations, scripts, scenes, or any configuration
- Diagnostics are redacted — Entity IDs are anonymized in diagnostics downloads
- Network activity — Only the frontend panel loads D3.js from
cdn.jsdelivr.neton first use
EntityMap uses a hybrid event-driven + on-demand architecture:
- Full scan on startup (configurable) builds the complete dependency graph in memory
- Registry event listeners trigger automatic rebuilds when devices/entities change
- Periodic reconciliation scans ensure the graph stays fresh over time
- On-demand rescan via button entity, service call, or panel button
This approach avoids the overhead of DataUpdateCoordinator (not suitable for local graph computation) while remaining responsive to changes.
| Object Type | Coverage | Source |
|---|---|---|
| Devices | ✅ Full | Device registry |
| Entities | ✅ Full | Entity registry + state machine |
| Automations | ✅ Full | Automation component configs |
| Scripts | ✅ Full | Script component configs |
| Scenes | ✅ Full | Scene component configs |
| Helpers | ✅ Full | Entity registry (input_* domains) |
| Groups | ✅ Full | Group state attributes |
| Templates | ⚡ Partial | Template entity configs (regex-based) |
| Areas | ✅ Reference | Area registry |
- Direct (high confidence) — Entity explicitly referenced by ID in a trigger, condition, action, or target
- Inferred (medium confidence) — Entity reference extracted from a Jinja2 template via regex
- Low confidence — Heuristic matches that may have false positives
git clone https://github.com/polprog-tech/EntityMap.git
cd EntityMap
python -m venv venv
source venv/bin/activate
pip install homeassistant voluptuous aiohttp pytest pytest-asyncio pytest-cov ruff mypypytest tests/ -v --cov=custom_components/entitymapAll tests follow the GIVEN / WHEN / THEN convention.
| Module | Tests | Status |
|---|---|---|
| Analysis — impact analysis engine | 11 | ✅ |
| Config Flow — UI setup & options | 6 | ✅ |
| Diagnostics — diagnostics export | 4 | ✅ |
| Fragility — fragility detection | 14 | ✅ |
| Graph — graph builder lifecycle | 6 | ✅ |
| Migration — migration suggestions | 9 | ✅ |
| Models — domain models & serialization | 33 | ✅ |
| Total | 83 | ✅ All passing |
Full test breakdown by scenario class
Analysis (test_analysis.py)
TestImpactOnNonexistentNode— 2 testsTestImpactOnEntityWithDependents— 3 testsTestImpactOnDevice— 2 testsTestImpactOnHelper— 1 testTestImpactOnIsolatedNode— 2 testsTestImpactRiskScoring— 1 test
Config Flow (test_config_flow.py)
TestConfigFlowUserStep— 3 testsTestOptionsFlowInit— 3 tests
Diagnostics (test_diagnostics.py)
TestDiagnosticsOutput— 2 testsTestDiagnosticsPrivacy— 1 testTestDiagnosticsWithFindings— 1 test
Fragility (test_fragility.py)
TestCleanGraph— 2 testsTestMissingEntityReference— 2 testsTestMissingDeviceReference— 1 testTestDeviceIdUsage— 2 testsTestDisabledReference— 2 testsTestTightDeviceCoupling— 2 testsTestHiddenDependency— 2 testsTestFindingIdStability— 1 test
Graph (test_graph.py)
TestGraphBuilderInitialState— 2 testsTestGraphBuilderBuild— 2 testsTestGraphBuilderSerialization— 2 tests
Migration (test_migration.py)
TestMigrationForNonexistentNode— 1 testTestMigrationForIsolatedNode— 1 testTestMigrationForTriggerDependency— 2 testsTestMigrationForDeviceReplacement— 2 testsTestMigrationForSceneMembers— 1 testTestMigrationForGroupMembers— 1 testTestMigrationForMultipleDependencies— 1 test
Models (test_models.py)
TestGraphNodeCreation— 3 testsTestGraphNodeSerialization— 2 testsTestGraphNodeImmutability— 2 testsTestGraphEdgeCreation— 2 testsTestGraphEdgeSerialization— 1 testTestGraphNodeOperations— 3 testsTestGraphEdgeOperations— 4 testsTestGraphDependencyQueries— 3 testsTestGraphTransitiveTraversal— 2 testsTestGraphNeighborhood— 3 testsTestGraphLifecycle— 2 testsTestFragilityFindingSerialization— 2 testsTestImpactReportSerialization— 2 testsTestMigrationSuggestionSerialization— 2 tests
ruff check .
ruff format --check .mypy custom_components/entitymap --ignore-missing-importsSee CONTRIBUTING.md for development setup, architecture guidelines, and testing philosophy.
MIT License — see LICENSE.
See CHANGELOG.md.





