Files
FabledSteward/plugins/homeassistant/__init__.py
T
bvandeusenandClaude Opus 5.5 b2a6e92ed3
CI / lint (push) Failing after 2s
CI / unit (push) Failing after 1m42s
CI / integration (push) Successful in 1m51s
CI / publish (push) Skipped
feat(homeassistant): waiting updates, backup age, and updates installed after a confirmed backup (#6355)
A new plugin reads Home Assistant with a read-only token every 5 minutes and
shows which Core, OS and add-on updates are waiting and how old the last backup
is. Install takes a backup through a local-only webhook, confirms Home
Assistant's last-backup time moved, installs, and follows the update to its end,
through Home Assistant's and Steward's own restarts. One runs at a time. Each
ends as one timeline entry.

Steward holds nothing that can act on the house: the webhook's automation can
only take a backup or install an allowed update (System 231's ruling). A refused
token stops polling, as Home Assistant bans an address after a few refusals.

Milestone 576 steps 1 to 5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:09:27 -04:00

46 lines
1.1 KiB
Python

# plugins/homeassistant/__init__.py
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from quart import Quart
_app: "Quart | None" = None
def setup(app: "Quart") -> None:
global _app
_app = app
from .models import HomeAssistantConnection, HomeAssistantUpdate # noqa: F401 — registers the tables
from .timeline import register
register()
def get_scheduled_tasks() -> list:
from .scheduler import make_tick_task
return [make_tick_task(_app)]
def get_blueprint():
from .routes import homeassistant_bp
return homeassistant_bp
def get_nav() -> list[dict]:
return [{"label": "Home Assistant", "href": "/plugins/homeassistant/"}]
def get_alert_metrics() -> dict[str, list[str]]:
"""What the poll records, all under the resource "homeassistant"."""
return {"homeassistant": ["is_up", "backup_age_hours", "updates_waiting"]}
def register_mcp_tools(register) -> None:
from .mcp_tools import register_tools
register_tools(register)
async def mcp_overview(db) -> list[dict]:
from .mcp_tools import mcp_overview as findings
return await findings(db)