Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Hass-Cleaner is a Home Assistant App for inspecting storage, stale entities and registry relationships before anything is cleaned up. Safety, informed user choice and recovery come before reclaimed space.

> **Release status:** version 1.1.0 is published for controlled early use. Hass-Cleaner provides facts, advice, backup options and recovery guidance; the user makes the final cleanup decision. The HACS installation changes in this checkout are not yet released.
> **Release status:** version 1.1.1 is published for controlled early use, including HACS installation support. This checkout prepares **1.1.2**, not yet published. Hass-Cleaner provides facts, advice, backup options and recovery guidance; the user makes the final cleanup decision.

## English

Expand Down Expand Up @@ -86,7 +86,13 @@ GitHub Actions builds the version in `hass_cleaner/config.yaml` for `amd64` and

With HACS configured and Home Assistant 2026.9.0 or newer, add `https://github.com/dkwolf1/Hass-Cleaner` under **HACS → menu (⋮) → Custom repositories**, type **Integration**. Download **Hass-Cleaner Companion**, restart Home Assistant Core, then add it under **Settings → Devices & services**. Use the same release version as the app.

HACS updates the companion; the App Store updates the app. The ZIP remains available for manual installation. See [installation and migration instructions](docs/reference-checks.md#installation), including the publication prerequisite for this new HACS route. This repository is not in the default HACS catalog.
HACS updates the companion; the App Store updates the app. The ZIP remains available for manual installation. See [installation and migration instructions](docs/reference-checks.md#installation). This repository is not in the default HACS catalog.

### Quarantine storage in 1.1.2

New operations atomically move files into `/homeassistant/.hass-cleaner-quarantine` (the Home Assistant configuration directory), retaining the original file rather than copying and unlinking it. This folder is excluded from scans. Cross-filesystem moves are rejected without a copy/delete fallback. Existing quarantine in app storage remains supported.

Keep both the configuration folder and the app data in your backups: the recovery manifest stays in the app data. Do not manually remove the hidden quarantine folder. Moving files on the same filesystem does not free disk space; permanent deletion after expiry does. Stop active writers before cleanup; a later write may invalidate the stored checksum, requiring manual recovery instead of automatic restore.

### Local development and tests

Expand Down Expand Up @@ -179,7 +185,9 @@ Versiegebonden wijzigingen staan in [CHANGELOG.md](hass_cleaner/CHANGELOG.md). G
4. Start de App en open de webinterface.
5. Voer eerst een scan uit en beoordeel het rapport voordat je een actie voorbereidt.

GitHub Actions bouwt de versie uit `hass_cleaner/config.yaml` voor `amd64` en `aarch64`. Na publicatie van de container kan Home Assistant die versie installeren of bijwerken. Versie 1.1.0 bevat [referentiecontrole en Reparaties](docs/reference-checks.md#nederlands-kort) via een aparte companion-integratie. Na publicatie van de HACS-ondersteuning kun je die via HACS installeren: voeg deze GitHub-repository toe als aangepaste repository, type **Integratie**. De ZIP blijft een alternatief. Praktijktests zijn nog nodig; de companion zit niet in de app-container.
GitHub Actions bouwt de versie uit `hass_cleaner/config.yaml` voor `amd64` en `aarch64`. Gepubliceerd: **1.1.1** met HACS-ondersteuning. Deze checkout bereidt **1.1.2** voor. Installeer de aparte [companion](docs/reference-checks.md#nederlands-kort) via HACS door deze repository toe te voegen als type **Integratie**. De ZIP blijft een alternatief; de companion zit niet in de app-container.

Vanaf 1.1.2 worden nieuwe quarantainebestanden atomair naar `.hass-cleaner-quarantine` in de Home Assistant-configuratiemap verplaatst. Bestaande quarantaine blijft ondersteund. Bewaar zowel de configuratiemap als appdata in je back-up; verwijder de verborgen map niet handmatig. Verplaatsen maakt nog geen schijfruimte vrij. Verplaatsingen tussen bestandssystemen worden geblokkeerd. Stop actieve schrijvers vooraf; latere wijzigingen kunnen de checksum ongeldig maken en handmatig herstel vereisen.

### Lokaal ontwikkelen en testen

Expand Down
30 changes: 19 additions & 11 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Hass-Cleaner Roadmap

[Nederlands](#nederlands) · [English](#english)
[English](#english) · [Nederlands](#nederlands)

Current published release: **1.1.1**, including reference checks, Repairs and HACS support. This checkout prepares **1.1.2**: quarantine concurrency protection, reference diagnostics, list refresh fixes and documentation/translation corrections. All releases remain intended for controlled early testing, not a guarantee of safety. See [the changelog](hass_cleaner/CHANGELOG.md).

## Nederlands

Expand All @@ -18,12 +20,15 @@ Veiligheid gaat vóór extra opruimwinst. Een release gaat pas door wanneer risi
| 0.9.0 | Afgerond | Supervisor-back-upverificatie, hersteltest, bewaartermijn en expliciete verwijdering na verval. |
| 0.9.1 | Afgerond | Toegestane back-upcontrole, hergebruik van back-upbewijs, bewuste optionele back-upkeuze en selecteerbare entitybeoordeling. |
| 1.0.0 | Uitgebracht | Gebruikersgestuurde cleanup, registeruitvoering, persoonlijke inhoud, schone start en behoud van harde systeembescherming. |
| 1.0.1 | Voorbereid | Technische hardening: crashbestendige uitvoering, paginering, atomaire opslag, toegankelijkheid en betrouwbaar frontendcachebeleid. |
| 1.0.2 | Voorbereid | Herstel- en registerjournals, veilige configuratiesynchronisatie, begrensd scangeheugen, robuuste verzoekvalidatie en verbeterde tweetalige exports. |
| 1.0.1 | Uitgebracht | Technische hardening: crashbestendige uitvoering, paginering, atomaire opslag, toegankelijkheid en betrouwbaar frontendcachebeleid. |
| 1.0.2 | Uitgebracht | Herstel- en registerjournals, veilige configuratiesynchronisatie, begrensd scangeheugen, robuuste verzoekvalidatie en verbeterde tweetalige exports. |
| 1.1.0 | Uitgebracht | Companion met referentiecontrole en native Reparaties. |
| 1.1.1 | Uitgebracht | HACS-installatie en instructies. |
| 1.1.2 | Voorbereid | Atomaire quarantaine, diagnostiek, lijstverversing en documentatie/vertalingen. |

### Praktijkcontrole voor vroege testers

- 1.0.2 installeren of bijwerken via de echte GitHub/GHCR-workflow.
- De nieuwe release installeren of bijwerken via de echte GitHub/GHCR- en HACS-workflow.
- Volledige back-up starten en voltooiing op Home Assistant OS verifiëren.
- Zowel een veilige als een bewust gekozen reviewkandidaat naar quarantaine verplaatsen.
- Hersteltest uitvoeren en hetzelfde bestand werkelijk terugplaatsen.
Expand All @@ -35,7 +40,7 @@ Veiligheid gaat vóór extra opruimwinst. Een release gaat pas door wanneer risi
- Minimaal enkele gebruikerstests uitvoeren met verschillende integraties en opslagprofielen.
- Bekende problemen documenteren en alle releaseblokkerende fouten oplossen.

### 1.0.0 — Eerste stabiele versie
### 1.0.0 — Eerste publieke testversie

- Gepubliceerd voor gecontroleerde vroege tests; meld onverwacht gedrag met het leesbare en technische scanrapport.
- Stabiel quarantaine- en herstelcontract.
Expand All @@ -49,7 +54,7 @@ Veiligheid gaat vóór extra opruimwinst. Een release gaat pas door wanneer risi
- Betere opslagtrends en geschatte winst per integratie.
- Optionele meldingen voor verlopen quarantaine en langdurige entityproblemen.
- Uitbreiding naar extra talen via losse vertaalbestanden.
- Entityverwijdering uitsluitend onderzoeken als Home Assistant daarvoor een officiële, controleerbare en herstelbare API biedt.
- Registerverwijdering blijft een bewuste keuze; herstel vereist een Home Assistant-back-up.

---

Expand All @@ -69,12 +74,15 @@ Safety takes priority over reclaimed space. A release proceeds only when risky s
| 0.9.0 | Completed | Supervisor backup verification, restore testing, retention and explicit post-expiry deletion. |
| 0.9.1 | Completed | Permitted backup verification, reusable evidence, an explicit optional backup choice and selectable entity reviews. |
| 1.0.0 | Released | User-directed cleanup, registry execution, personal content, clean-start controls and hard core-system protection. |
| 1.0.1 | Prepared | Technical hardening: crash-safe execution, pagination, atomic storage, accessibility and reliable frontend caching. |
| 1.0.2 | Prepared | Recovery and registry journals, safe configuration synchronization, bounded scan memory, robust request validation and improved bilingual exports. |
| 1.0.1 | Released | Technical hardening: crash-safe execution, pagination, atomic storage, accessibility and reliable frontend caching. |
| 1.0.2 | Released | Recovery and registry journals, safe configuration synchronization, bounded scan memory, robust request validation and improved bilingual exports. |
| 1.1.0 | Released | Companion reference checks and native Repairs. |
| 1.1.1 | Released | HACS installation support and instructions. |
| 1.1.2 | Prepared | Atomic quarantine, diagnostics, list refresh and documentation/translations. |

### Practical checks for early testers

- Install or update 1.0.2 through the real GitHub/GHCR workflow.
- Install or update the new release through the real GitHub/GHCR and HACS workflows.
- Start a full backup and verify completion on Home Assistant OS.
- Move both a safe file and an explicitly accepted review candidate into quarantine.
- Run the restore test and restore that file to its original location.
Expand All @@ -86,7 +94,7 @@ Safety takes priority over reclaimed space. A release proceeds only when risky s
- Run user tests across several integrations and storage profiles.
- Document known issues and resolve every release-blocking defect.

### 1.0.0 — First stable release
### 1.0.0 — First public test release

- Released for controlled early testing; report unexpected behaviour with the readable and technical scan reports.
- Stable quarantine and recovery contract.
Expand All @@ -100,4 +108,4 @@ Safety takes priority over reclaimed space. A release proceeds only when risky s
- Better storage trends and estimated savings per integration.
- Optional notifications for expired quarantine and persistent entity problems.
- Additional languages through separate translation files.
- Consider entity deletion only if Home Assistant provides an official, verifiable and recoverable API.
- Keep registry deletion user-directed; recovery requires a Home Assistant backup.
11 changes: 10 additions & 1 deletion custom_components/hass_cleaner/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import asyncio
import logging
import traceback
from datetime import timedelta

import voluptuous as vol
Expand Down Expand Up @@ -84,21 +85,29 @@ async def refresh(self, _now=None):
self.report = {"schema_version": 1, "status": "starting", "summary": {}, "sources": [], "references": []}
return
try:
stage = "sources"
sources = await collect_sources(hass)
stage = "registries"
known = {"entity": set(er.async_get(hass).entities) | set(hass.states.async_entity_ids()),
"entity_aliases": {e.id: e.entity_id for e in er.async_get(hass).entities.values()},
"device": set(dr.async_get(hass).devices), "area": set(ar.async_get(hass).areas),
"action": {f"{domain}.{service}" for domain, services in hass.services.async_services().items() for service in services}}
stage = "statistics"
known["statistic"] = await statistic_ids(hass)
stage = "analysis"
report = await hass.async_add_executor_job(analyze, sources, known)
if self.closed:
return
stage = "repairs"
self.reconcile(report)
self.report = report
except Exception as exc:
if not self.report or self.report.get("status") != "unavailable":
_LOGGER.warning("Reference check could not complete (%s)", type(exc).__name__)
# Code locations only: no exception text, source lines or locals.
locations = " -> ".join(f"{frame.name}:{frame.lineno}" for frame in traceback.extract_tb(exc.__traceback__))
_LOGGER.warning("Reference check failed: stage=%s type=%s locations=%s", stage, type(exc).__name__, locations)
self.report = {"schema_version": 1, "status": "unavailable", "summary": {}, "sources": [], "references": [],
"reason": "check_failed", "stage": stage,
"error": "Reference check failed; previous repair issues have been retained"}

@callback
Expand Down
2 changes: 1 addition & 1 deletion custom_components/hass_cleaner/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"iot_class": "local_polling",
"issue_tracker": "https://github.com/dkwolf1/Hass-Cleaner/issues",
"requirements": [],
"version": "1.1.1"
"version": "1.1.2"
}
15 changes: 12 additions & 3 deletions custom_components/hass_cleaner/references.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ def walk(value, location="$", key="", depth=0, statistic_context=False):
record["status"] = "partial"
return
if isinstance(value, dict):
statistic_context = statistic_context or (record["kind"] == "dashboard" and value.get("type") in {"statistic", "statistics-graph"})
card_type = value.get("type")
if record["kind"] == "dashboard" and card_type is not None and not isinstance(card_type, str):
record["status"] = "partial"
statistic_context = statistic_context or (record["kind"] == "dashboard" and isinstance(card_type, str) and card_type in {"statistic", "statistics-graph"})
if key == "entities" and record["kind"] == "scene":
for entity_id in value:
add("entity", entity_id, f"{location}[{entity_id}]")
Expand Down Expand Up @@ -140,8 +143,14 @@ def walk(value, location="$", key="", depth=0, statistic_context=False):
if source.get("error") or not isinstance(source.get("config"), dict):
record.update(status="unavailable", error=str(source.get("error") or "Configuration is unavailable"))
else:
walk(source["config"])
if record["dynamic"] or record["custom_cards"]:
start = len(references)
try:
walk(source["config"])
except Exception:
# Never expose config values or resolve issues for failed sources.
del references[start:]
record.update(status="unavailable", error="Source analysis failed")
if record["status"] != "unavailable" and (record["dynamic"] or record["custom_cards"]):
record["status"] = "partial"
coverage.append(record)
references.sort(key=lambda r: (r["source_id"], r["location"], r["target_id"]))
Expand Down
8 changes: 4 additions & 4 deletions docs/reference-checks.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Reference checks and Home Assistant Repairs

Development preview for Hass-Cleaner 1.1.0. Keep a complete backup and test on a non-critical installation first. This feature does not provide Spook feature parity or prove that anything is safe to delete.
Reference checks were introduced in 1.1.0; HACS support shipped in 1.1.1. This checkout prepares the unreleased 1.1.2 fixes. Keep a complete backup and test on a non-critical installation first. This feature does not provide Spook feature parity or prove that anything is safe to delete.

## Two components

Expand All @@ -26,7 +26,7 @@ HACS manages only `custom_components/hass_cleaner`, not the app container. Insta

**Already installed from ZIP?** Back up first, then download the same integration through HACS and restart Core. Keep the existing integration entry; do not remove/re-add it or create a second nested folder. HACS may replace local edits to the integration files.

**Publishing note:** the HACS metadata must be merged to the default branch. Publish a new release containing these changes for the fully packaged installation route; existing release tags are not updated by a merge. Do not move an existing release tag. Installation through a real HACS instance still needs verification.
**Publishing note:** HACS support is available from release 1.1.1. Future changes need a new release; existing tags are not updated by a merge. Do not move an existing release tag. Validate each update in a real Home Assistant installation.

### Manual installation (without HACS)

Expand Down Expand Up @@ -118,9 +118,9 @@ On a disposable Home Assistant 2026.9 instance:

De zeven categorieën uit deel 1 zijn aangesloten, inclusief scènes, groepen, ondersteunde helpers, losse templates en energie/statistieken. Geldige historische/externe statistieken worden niet als verdwenen entiteit gemeld. Zonder Recorder is de statistiekcontrole expliciet onbekend. Niet alle aangepaste helpers of dynamische templates zijn interpreteerbaar; praktijktests blijven nodig voordat dit releaseklaar is.

- Met HACS en Home Assistant 2026.9.0 of nieuwer: voeg `https://github.com/dkwolf1/Hass-Cleaner` toe via **HACS → menu (⋮) → Aangepaste repositories**, type **Integratie**. Download **Hass-Cleaner Companion**, herstart Home Assistant Core en voeg de integratie toe via **Instellingen → Apparaten & diensten**. Kies dezelfde releaseversie als de app. De HACS-wijzigingen moeten eerst gepubliceerd zijn; de integratie staat niet in de standaardcatalogus.
- Met HACS en Home Assistant 2026.9.0 of nieuwer: voeg `https://github.com/dkwolf1/Hass-Cleaner` toe via **HACS → menu (⋮) → Aangepaste repositories**, type **Integratie**. Download **Hass-Cleaner Companion**, herstart Home Assistant Core en voeg de integratie toe via **Instellingen → Apparaten & diensten**. Kies dezelfde releaseversie als de app. HACS-ondersteuning is beschikbaar vanaf 1.1.1; de integratie staat niet in de standaardcatalogus.
- De ZIP blijft een alternatief zonder HACS. Al handmatig geïnstalleerd? Maak een back-up, download via HACS en herstart Core; behoud de bestaande integratie. Werk voortaan de companion via HACS bij en de app via de App Store.
- Start een nieuwe appscan. Onder **Entiteiten → Referentiecontrole** staan bronnen, doelen, exacte configuratiepaden en beperkte dekking.
- Meldingen staan bij **Instellingen → Systeem → Reparaties**. Corrigeer zelf de configuratie; de companion controleert iedere vijf minuten. Er wordt niets automatisch hersteld of verwijderd.
- App en companion zijn afzonderlijke onderdelen en moeten afzonderlijk worden bijgewerkt. Versie 1.1.0 is nog een ontwikkelversie; praktijktests zijn nodig.
- App en companion zijn afzonderlijke onderdelen en moeten afzonderlijk worden bijgewerkt. 1.1.1 is gepubliceerd; deze checkout bereidt 1.1.2 voor. Praktijktests blijven nodig.
- Geen verwijzingen gevonden betekent **niet** veilig verwijderen. Templates, blueprints, aangepaste kaarten en onleesbare bronnen kunnen gebruik verbergen. Maak een volledige back-up en controleer de gevolgen.
13 changes: 13 additions & 0 deletions hass_cleaner/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## 1.1.2 — Unreleased

- Use atomic, same-filesystem quarantine moves in protected configuration storage instead of copy/delete; retain compatibility with existing app-storage quarantine and preserve concurrent writes for recovery.
- Refresh the visible paginated list after a completed scan.
- Distinguish reference-bridge timeouts, connection failures, permission refusals and missing companion commands without exposing server error text.
- Align release documentation and complete the reviewed English entity-detail translations.

- Fetch entity results when switching from the empty attention view to temporary signals.
- Handle non-scalar dashboard type fields and isolate unexpected source-analysis failures; failed sources remain explicitly unavailable and retain their Repairs.
- Report companion failure stages in the app and log code locations without exception messages or configuration values.
- Fill visible English translation gaps in group actions, bundle review and entity details.
- Live verification is still required: the reported TypeError did not include a traceback, so the reproduced dashboard defect is not yet confirmed as the cause on the affected installation.

## 1.1.1

- Add HACS custom-repository metadata for the optional companion (Home Assistant 2026.9.0 minimum), with English and Dutch installation and migration guidance.
Expand Down
Loading