{"id":51082049,"url":"https://github.com/michailjovic/anyvac","last_synced_at":"2026-07-02T05:01:21.422Z","repository":{"id":365819941,"uuid":"1273807650","full_name":"Michailjovic/anyvac","owner":"Michailjovic","description":null,"archived":false,"fork":false,"pushed_at":"2026-07-01T22:32:02.000Z","size":186,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-02T00:17:12.896Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Michailjovic.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-18T22:29:22.000Z","updated_at":"2026-07-01T22:17:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Michailjovic/anyvac","commit_stats":null,"previous_names":["michailjovic/anyvac"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Michailjovic/anyvac","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Michailjovic%2Fanyvac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Michailjovic%2Fanyvac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Michailjovic%2Fanyvac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Michailjovic%2Fanyvac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Michailjovic","download_url":"https://codeload.github.com/Michailjovic/anyvac/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Michailjovic%2Fanyvac/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35033492,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-02T02:00:06.368Z","response_time":173,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-23T19:02:15.220Z","updated_at":"2026-07-02T05:01:21.416Z","avatar_url":"https://github.com/Michailjovic.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AnyVac (companion integration)\n\nCompanion Home Assistant integration for the [AnyVac card](https://github.com/Michailjovic/anyvac-card).\n\nThe official Roborock integration already parses the vacuum map into structured\ndata — robot position, cleaning path, room geometry and calibration points — but\nit only renders that to a PNG image entity and never exposes the structured data.\n**AnyVac reads that already-parsed data out of the Roborock integration and\nre-publishes it**, so the AnyVac card can draw the robot and its path on a custom\nfloorplan and run zone / pin-and-go cleaning with **no manual calibration**.\n\n## Requirements\n\n- The official **Roborock** integration set up and working (AnyVac reads from it;\n  it does not open its own Roborock connection).\n- Home Assistant 2024.1.0 or newer.\n\n## Install\n\n1. Add this repository to HACS as a custom repository (category: *Integration*).\n2. Install **AnyVac** and restart Home Assistant.\n3. Add the **AnyVac** integration (Settings → Devices \u0026 services → Add integration).\n   There is nothing to configure — it discovers your Roborock vacuums automatically.\n\n## What it exposes\n\nFor each Roborock vacuum, a sensor (e.g. `sensor.\u003cvacuum\u003e_anyvac_map`) whose state\nis the current path-point count and whose attributes carry the map payload:\n\n| Attribute | Meaning |\n| --- | --- |\n| `vacuum_position` | `{x, y, a}` robot position + angle, in millimetres |\n| `charger` | `{x, y}` dock position, in millimetres |\n| `calibration_points` | `[{vacuum:{x,y}, map:{x,y}}, …]` — pixel ↔ mm calibration |\n| `path` | decimated cleaning path, list of `{x, y}` in millimetres |\n| `rooms` | `[{segment_id, name, x0,y0,x1,y1, pos_x,pos_y}, …]` |\n| `image_dims` | `{top,left,width,height,scale,rotation}` of the rendered map |\n| `rooms_progress` | per-room debug progress: `{room: {spatial_pct, visited_cells, total_cells, time_pct, elapsed_s, est_s}}` |\n\n## Recorder\n\nNothing to configure — the large map attributes (`path`, `rooms`, `calibration_points`, …) are marked\nas unrecorded by the integration, so they stay out of your recorder database automatically. No\n`recorder: exclude` in `configuration.yaml` is needed.\n\n## Notifications\n\nAnyVac never writes notification text itself — it exposes **data + events**, and you write the\nmessage (in any language) when you create an automation. Building blocks:\n\n**Per-room timestamp sensors** (on the *AnyVac Rooms* device): `sensor.\u003croom\u003e_last_dry` and\n`sensor.\u003croom\u003e_last_wet` (`device_class: timestamp`), keyed by room name across all vacuums. Use them\nfor \"overdue\" logic (`now() - states(sensor) \u003e N days`).\n\n**Events:**\n\n| Event | Data |\n| --- | --- |\n| `anyvac_clean_started` | `{ vacuum, duid, clean_type }` |\n| `anyvac_clean_finished` | `{ vacuum, duid, clean_type, rooms, duration_min }` plus `calibrated_room, estimate_before, estimate_after` when the session was a single-room calibration |\n| `anyvac_room_done` | `{ vacuum, duid, room, reason }` — fired when a vacuum has truly left a room it was cleaning (`reason: \"left\"`, debounced over 2 polls) or on return-to-dock (`reason: \"docked\"`). The orchestrator's per-room \"wet follows dry\" signal. |\n\nBoth events are fired **server-side** on the vacuum's cleaning transitions, so notifications built on\nthem fire reliably whether or not the AnyVac card (or any dashboard) is open. `rooms` is the set of\nrooms actually visited during the session; `duration_min` is the measured session length in minutes.\n\n**Errors:** use the existing Roborock `sensor.\u003cvacuum\u003e_vacuum_error`.\n\n**Auto-installed blueprints.** On first setup AnyVac copies three automation blueprints into\n`config/blueprints/automation/anyvac/`:\n\n- *AnyVac — Room overdue* — pick a room timestamp sensor + threshold days + notify service + message.\n- *AnyVac — Clean finished* — fires on `anyvac_clean_finished`; message can use `{{ vacuum }}`,\n  `{{ clean_type }}`, `{{ rooms }}`.\n- *AnyVac — Vacuum error* — pick the error sensor + notify service + message (`{{ error }}`).\n\nCreate an automation from one (Settings → Automations → Blueprints), choose your notify service and\nwrite your own message. Existing (edited) blueprints are never overwritten.\n\n## Orchestration service\n\n`anyvac.run_job` executes a plan of gated vacuum tasks **server-side** (so it survives the dashboard\nclosing). The AnyVac card builds the plan — which robot cleans which rooms, and the dry→wet ordering —\nand calls this service. Each task runs once its `after` conditions (`anyvac_room_done` per room, or\n`anyvac_clean_finished` per vacuum) are met, so a wet robot follows a dry robot per room without\ncolliding. See the service's docstring for the task shape.\n\n## Status\n\nExperimental v0.11.0. AnyVac reads the Roborock integration's internal runtime\ndata; if a future Roborock release changes that structure, AnyVac degrades\ngracefully (no data) rather than breaking — please open an issue if that happens.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichailjovic%2Fanyvac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichailjovic%2Fanyvac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichailjovic%2Fanyvac/lists"}