🛡️ H.A.C.A — Continuous Config Audit, Auto-Fix & Health Scoring for Home Assistant (HACS)

Hello community :wave:

I’m excited to share H.A.C.A (Home Assistant Config Auditor) — a dedicated audit and self-healing integration for Home Assistant.

Why?

Home Assistant setups naturally degrade over time:

  • broken device IDs after re-pairing
  • deprecated services
  • stale entities
  • performance-heavy templates
  • security risks in YAML

H.A.C.A continuously scans your configuration and provides:


Core Capabilities

  • :mag: Scheduled full audits
  • :bar_chart: Real-time health score sensor
  • :zap: 1-click fixes with YAML backups
  • :robot: AI-powered explanations & automation optimization
  • :package: Recorder DB orphan cleanup
  • :battery: Battery fleet monitoring
  • :shield: Security detection
  • :page_facing_up: Report exports (PDF, Markdown, JSON)

Everything runs locally.


HACS Installation

Compatible with HACS (Custom Repository).

GitHub:


I’d love feedback from power users, especially regarding:

  • automation complexity analysis
  • performance heuristics
  • security detection patterns

Thanks for taking a look :pray:

1 Like

Seems interesting, but failing:

2026-03-02 12:10:19.958 ERROR (MainThread) [custom_components.config_auditor] Unexpected error fetching config_auditor data
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 416, in _async_refresh
    self.data = await self._async_update_data()
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 307, in _async_update_data
    return await self.update_method()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/config_auditor/__init__.py", line 132, in async_update_data
    await automation_analyzer.analyze_all()
  File "/config/custom_components/config_auditor/automation_analyzer.py", line 161, in analyze_all
    self._check_blueprint_issues()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/config/custom_components/config_auditor/automation_analyzer.py", line 1357, in _check_blueprint_issues
    "message": t("blueprint_empty_input", key=input_key),
               ~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: TranslationHelper.t() got multiple values for argument 'key'

Thanks for your feedback.
How did you install it?
I can’t reproduce those errors.

By the book, i.e HACS :wink:
I see the error seems to be related to translations, and I’m running HA in French, if that matters.

EDIT:
I assume there is an actual issue in my blueprints that your integration does not handle…

I updated the project for the translation errors. I’am french so I’m running HA in French too.

HACA is still in development so It cannot yet detect all issue.
What is the issue in your blueprints ?

If I would know :wink:

I added a debug line before:

                # Check for missing or empty inputs
                inputs = blueprint.get("input", {}) if isinstance(blueprint, dict) else {}
                _LOGGER.info("Blueprints: %s", inputs)

This is what I get

{
  "presence_filter": [],
  "camera": [
    "camera.jardin_arriere"
  ],
  "notify_device": "3d2b656d71fa49081f71790c09e636b6",
  "base_url": "<retracted>",
  "attachment": "snapshot.jpg?bbox=1",
  "video": "",
  "title": "Frigate alert arrière",
  "update_thumbnail": True,
  "android_auto": True,
  "sticky": True,
  "labels": [],
  "debug": True,
  "loiter_timer": 15,
  "state_entity": "input_boolean.away_mode",
  "state_filter_states": [
    "on"
  ],
  "state_filter": True
}

EDIT:
As there is no notion of optional blueprint parameters, not actually sure the whole test is relevant, tbh

Ok, I will work on that.

I just tried this out. I get all zeros for all the entities, even the score which I assume should be 100% if there are zero issues ?

After 60s the scan starts and all entities become unavailable, until I do a reload, then the same happens again after 60s. Also the same if I run the scan action.

I also get the same as above in the logs:

Logger: custom_components.config_auditor
Source: helpers/update_coordinator.py:426
integration: Home Assistant Config Auditor (H.A.C.A) (documentation, issues)
First occurred: 12:19:52 pm (5 occurrences)
Last logged: 12:24:37 pm

Unexpected error fetching config_auditor data
Traceback (most recent call last):
  File "/config/custom_components/config_auditor/translation_utils.py", line 55, in t
    return template.format(**kwargs)
           ~~~~~~~~~~~~~~~^^^^^^^^^^
KeyError: 'count'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 426, in _async_refresh
    self.data = await self._async_update_data()
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 309, in _async_update_data
    return await self.update_method()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/config_auditor/__init__.py", line 132, in async_update_data
    await automation_analyzer.analyze_all()
  File "/config/custom_components/config_auditor/automation_analyzer.py", line 97, in analyze_all
    self._analyze_automation(entity_id, config)
    ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/config_auditor/automation_analyzer.py", line 449, in _analyze_automation
    self._analyze_complexity(entity_id, alias or entity_id, automation_id, config)
    ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/config_auditor/automation_analyzer.py", line 545, in _analyze_complexity
    "message":       t(label,
                     ~^^^^^^^
                       score=score,
                       ^^^^^^^^^^^^
    ...<2 lines>...
                       actions=n_actions,
                       ^^^^^^^^^^^^^^^^^^
                       templates=template_score),
                       ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/config_auditor/translation_utils.py", line 57, in t
    _LOGGER.debug("Error formatting translation key '%s': %s", key, e)
                                                               ^^^
NameError: name 'key' is not defined

Just got this in my log:

Logger: homeassistant.util.loop
Source: util/loop.py:137
First occurred: 12:50:27 pm (1 occurrence)
Last logged: 12:50:27 pm

Detected blocking call to scandir with args (57,) inside the event loop by custom integration 'config_auditor' at custom_components/config_auditor/__init__.py, line 580: shutil.rmtree(path) (offender: /usr/local/lib/python3.14/shutil.py, line 777: with os.scandir(topfd) as scandir_it:), please create a bug report at https://github.com/JeanMarc-Labs/ha-config-auditor/issues For developers, please see https://developers.home-assistant.io/docs/asyncio_blocking_operations/#scandir Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/usr/src/homeassistant/homeassistant/__main__.py", line 229, in <module> sys.exit(main()) File "/usr/src/homeassistant/homeassistant/__main__.py", line 215, in main exit_code = runner.run(runtime_conf) File "/usr/src/homeassistant/homeassistant/runner.py", line 289, in run return loop.run_until_complete(setup_and_run_hass(runtime_config)) File "/usr/local/lib/python3.14/asyncio/base_events.py", line 706, in run_until_complete self.run_forever() File "/usr/local/lib/python3.14/asyncio/base_events.py", line 677, in run_forever self._run_once() File "/usr/local/lib/python3.14/asyncio/base_events.py", line 2046, in _run_once handle._run() File "/usr/local/lib/python3.14/asyncio/events.py", line 94, in _run self._context.run(self._callback, *self._args) File "/usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py", line 598, in start task = asyncio.Task(coro, loop=loop, eager_start=True) File "/usr/local/lib/python3.14/site-packages/aiohttp/web_protocol.py", line 510, in _handle_request resp = await request_handler(request) File "/usr/local/lib/python3.14/site-packages/aiohttp/web_app.py", line 569, in _handle return await handler(request) File "/usr/local/lib/python3.14/site-packages/aiohttp/web_middlewares.py", line 117, in impl return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 92, in security_filter_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 87, in forwarded_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 26, in request_context_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 86, in ban_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 242, in auth_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/headers.py", line 41, in headers_middleware response = await handler(request) File "/usr/src/homeassistant/homeassistant/helpers/http.py", line 73, in handle result = await handler(request, **request.match_info) File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 116, in delete result = await hass.config_entries.async_remove(entry_id) File "/usr/src/homeassistant/homeassistant/config_entries.py", line 2151, in async_remove unload_success, entry = await self._async_remove(entry_id) File "/usr/src/homeassistant/homeassistant/config_entries.py", line 2174, in _async_remove await entry.async_remove(self.hass) File "/usr/src/homeassistant/homeassistant/config_entries.py", line 1065, in async_remove await component.async_remove_entry(hass, self) File "/config/custom_components/config_auditor/__init__.py", line 595, in async_remove_entry safe_remove_dir(reports_path) File "/config/custom_components/config_auditor/__init__.py", line 580, in safe_remove_dir shutil.rmtree(path)

I investigate about all your issues.
Thanks for your feedback.

Any way to change the language to English? Most of it is showing up in French.

Yes, it’s a bug. We work on it.

1 Like

Working great for me. I’d only note the same thing as above. Some (but not all) labels in the panel are being listed in French rather than my default language (English).

One example:
image

One suggestion (and maybe its already a feature and I’ve missed it) is to allow for certain zombie entities to be excluded if they are tagged with a certain label.

Thank You. Great integration!

That’s a good suggestion, but the difficulty is that a label can be anything and different for each user.

Obv this may be difficult to code on your end, but you could say “any entity, automation, etc. labeled with 'haca_ignore” will be ignored by the audit tool".

It would be helpful for integrations like Keymaster that have hundreds of “unknown” entities but that’s not necessarily an issue.

Either way, I’m loving this so far. Amazing work man

Good Idea !

I can’t install it. When i add it as custom repository and restart home assistant, the custom repository disappeared.
I have tested on three different systems, one HAOS with lastest beta installed, Home Assistant Container also with latest beta and my “production” system, Home Assistant Container, which is still on 2026.2.3.
No log entries either. The install seems to silently fail.

Do you use HACS ?

Yes, i found that on the Home Assistant Container with beta installed it is partially? installed. I found the files in custom_components/config_auditor. When i try to add the integration in settings-devices there is no integration h.a.c.a to add.