Monitoring

Home Assistant mit Checkmk 2.5 überwachen – Proxmox, Web, REST API und Updates

Ein grüner VM-Status bedeutet noch lange nicht, dass Home Assistant wirklich funktioniert. In diesem Projekt überwachen wir Home Assistant auf mehreren Ebenen: die VM über Proxmox-Piggyback, das Webinterface per HTTP, die authentifizierte REST API und schließlich Core-, Supervisor- und Betriebssystem-Updates mit einem eigenen Checkmk-2.5-Special-Agent.

Datenschutz im Artikel: Alle Hostnamen, IP-Adressen, Benutzernamen, Pfade und Screenshots wurden neutralisiert oder nachgebaut. Verwende in den Befehlen deine eigenen Werte für <HOME_ASSISTANT_IP>, <HOME_ASSISTANT_TOKEN> und <CHECKMK_SITE>. Es werden keine Daten aus dem produktiven HomeLab veröffentlicht.

1. Ziel und Ergebnis

Wir wollen nicht jede einzelne Home-Assistant-Entity nach Checkmk ziehen. Messwerte, Energieverläufe und historische Dashboards gehören später eher nach Grafana. Checkmk soll stattdessen die Dinge beantworten, bei denen ein Ausfall oder eine Abweichung wirklich eine Meldung rechtfertigt.

Ebene Check Was wir damit wissen
Virtualisierung Proxmox VE Piggyback VM läuft, CPU/RAM/Disk/Netzwerk, Backup, Snapshot und Uptime
Application HomeAssistant Web Webfrontend auf Port 8123 antwortet
Application/API HomeAssistant API REST API funktioniert mit Authentifizierung
Home Assistant HomeAssistant Updates Core, Supervisor oder HAOS haben ein Update

2. Architektur

Wir trennen bewusst zwischen Infrastruktur, Anwendung und Home-Assistant-Daten. So ist später sofort erkennbar, ob nur die VM läuft oder ob Home Assistant selbst wirklich funktioniert.

Proxmox VE

  • VM-Status und Uptime
  • CPU und RAM
  • Disk und Netzwerk
  • Backup und Snapshot
Piggyback

Checkmk 2.5

  • Proxmox-Piggyback
  • HTTP Active Checks
  • REST-API-Prüfung
  • Home-Assistant-Special-Agent
HTTP / REST API

Home Assistant

  • Webinterface auf Port 8123
  • authentifizierte REST API
  • Core-Updates
  • Supervisor-Updates
  • HAOS-Updates
✓ VM gesund✓ Web erreichbar✓ API authentifiziert✓ Updates erkannt

Die Trennung ist absichtlich: Proxmox kann sehen, ob die VM läuft. Das beweist aber nicht, dass das Home-Assistant-Frontend oder die API funktionieren. Umgekehrt liefert die REST API Informationen, die Proxmox überhaupt nicht kennen kann.

3. Voraussetzungen

Komponente Anforderung
Checkmk Getestet mit Checkmk Community 2.5.0p11; Check API V2
Home Assistant Home Assistant mit erreichbarer REST API
Proxmox Optional, aber für VM-Metriken und Piggyback sehr praktisch
Netzwerk Checkmk-Server erreicht Home Assistant auf dem konfigurierten HTTP/HTTPS-Port
Home-Assistant-Account Eigener Nicht-Admin-Benutzer für Monitoring empfohlen
Tools curl; für manuelle Filter optional jq
Hinweis: Wenn du Home Assistant OS verwendest, installiere nicht krampfhaft einen normalen Checkmk-Agenten in HAOS. Wir überwachen die Appliance von außen und ergänzen gezielt API-Daten.

4. Home Assistant als VM über Proxmox überwachen

Wenn die Home-Assistant-VM bereits über die Checkmk-Proxmox-Integration erkannt wird, bekommst du ohne Agent in HAOS bereits eine starke Basis. Typische Services sind CPU Utilization, Memory Usage, Disk Throughput, Network Throughput, VM Backup Status, VM Info und Snapshot Age.

Anonymisierte Checkmk Serviceübersicht
Beispielansicht mit generischem Hostnamen; keine Daten aus dem produktiven Netz.

Diese Daten kommen per Piggyback vom Proxmox-Host. Die VM muss dafür nicht selbst den Checkmk-Agenten bereitstellen.

5. RAM-Warnung: nicht blind mehr Speicher geben

Bei HAOS kann Proxmox eine sehr hohe RAM-Nutzung melden, obwohl Home Assistant nicht unter echtem Speicherdruck steht. Linux nutzt ungenutzten RAM sinnvoll als Cache. Deshalb prüfen wir zusätzlich, ob Swap oder Memory Pressure auftreten, bevor wir einfach mehr RAM zuweisen.

Was wirklich interessant ist

  • Swap-in / Swap-out
  • Memory Pressure
  • OOM-Ereignisse
  • tatsächliche Core-Nutzung
Beispiel für HAOS

  • VM: 4 GiB RAM
  • Proxmox meldet knapp 90 %
  • kein Swap
  • kein Memory Pressure

In so einem Fall kann eine host-spezifische Checkmk-Regel sinnvoller sein als ein unnötiges RAM-Upgrade. Im Beispiel verwenden wir WARN 95 % und CRIT 98 % nur für die HAOS-VM.

Beispielregel für HAOS RAM Schwellwerte
Die Regel gilt nur für den Home-Assistant-Host.
Nicht pauschal übernehmen: 95/98 ist kein universeller Idealwert. Erst Swap, Pressure und tatsächliche Nutzung prüfen; dann eine passende Grenze für die eigene Umgebung setzen.

6. Webinterface mit Checkmk überwachen

Der erste Application-Check prüft, ob Home Assistant überhaupt per HTTP(S) antwortet. In Checkmk legst du unter Setup → Services → HTTP, TCP, email, … → Check HTTP web service eine Regel an.

Service name HomeAssistant Web
URL http://<HOME_ASSISTANT_IP>:8123/
Host homeassistant01

Nach Aktivierung sollte der Service einen HTTP-Status 200 und eine Antwortzeit liefern. Damit wissen wir: Das Frontend reagiert.

7. Dedizierten Monitoring-Benutzer und Long-Lived Access Token anlegen

Für die API-Abfrage verwenden wir bewusst nicht den persönlichen Admin-Account. Lege in Home Assistant einen separaten Benutzer wie checkmk-monitoring an und lasse die Administrator-Rolle deaktiviert. Melde dich einmal mit diesem Benutzer an und erstelle unter Profil → Sicherheit → Langlebige Zugriffstoken einen Token.

Token nicht in Screenshots, Tickets oder Blogposts kopieren. Ein Long-Lived Access Token ist ein Credential. Wenn er kompromittiert wurde, widerrufe ihn und erstelle einen neuen.

Home Assistant erwartet bei HTTP-Requests den Header Authorization: Bearer TOKEN. Der folgende Test sollte HTTP 200 und die Meldung API running. liefern:

curl -i 
  -H "Authorization: Bearer <HOME_ASSISTANT_TOKEN>" 
  -H "Content-Type: application/json" 
  http://<HOME_ASSISTANT_IP>:8123/api/

HTTP/1.1 200 OK
Content-Type: application/json
...
{"message":"API running."}

8. REST API als eigenen Checkmk-Service überwachen

Jetzt erstellen wir einen zweiten HTTP-Service, diesmal auf /api/ und mit Authentifizierung. Dadurch prüft Checkmk nicht nur einen offenen Port, sondern eine funktionierende authentifizierte Home-Assistant-API.

Anonymisierte Checkmk Regel für die Home Assistant REST API
Service HomeAssistant API
URL http://<HOME_ASSISTANT_IP>:8123/api/
Authentication Token based authentication
API key header Authorization
API key Bearer <HOME_ASSISTANT_TOKEN>
Status code 200
Search in body API running.
Damit prüfst du die komplette Kette: TCP/HTTP erreichbar → Token akzeptiert → REST API antwortet → erwarteter Inhalt vorhanden.

9. Update-Entities in Home Assistant finden

Über /api/states können wir die Update-Entities auslesen. Relevant sind in unserem Check drei Entitäten:

  • update.home_assistant_core_update
  • update.home_assistant_supervisor_update
  • update.home_assistant_operating_system_update

curl -s 
  -H "Authorization: Bearer <HOME_ASSISTANT_TOKEN>" 
  http://<HOME_ASSISTANT_IP>:8123/api/states 
  | grep -o '"entity_id":"update.[^"]*"' 
  | grep -i 'home_assistant|supervisor|operating'

Bei diesen Update-Entities bedeutet im Normalfall off, dass kein Update bereitsteht, und on, dass ein Update verfügbar ist. Genau daraus bauen wir später OK und WARN.

10. Eigenen Checkmk-2.5-Special-Agent installieren

Der HTTP-Check ist für Erreichbarkeit ideal. Für strukturierte Daten aus der REST API ist ein Special Agent sauberer. Checkmk 2.5 legt lokale Erweiterungen unter ~/local/lib/python3/cmk_addons/plugins/<familie>/ ab. Unser Paket enthält vier Komponenten:

Datei Aufgabe
libexec/agent_homeassistant fragt die Home-Assistant-REST-API ab und liefert JSON als Checkmk-Agentensektion
rulesets/special_agent.py erzeugt die GUI-Regel unter Other integrations
server_side_calls/special_agent.py übersetzt die Regel in den Aufruf des Special Agents
agent_based/homeassistant_updates.py wertet die Sektion aus und erzeugt den Service HomeAssistant Updates
Fertiges Checkmk-Plugin als ZIP
Enthält alle vier Dateien plus README. Keine internen IPs, Hostnamen oder Tokens.

Plugin als ZIP herunterladen

Installation als Checkmk-Site-User:

su - <CHECKMK_SITE>
cd /tmp
unzip checkmk-homeassistant-special-agent.zip
cp -a homeassistant ~/local/lib/python3/cmk_addons/plugins/
chmod 755 ~/local/lib/python3/cmk_addons/plugins/homeassistant/libexec/agent_homeassistant
cmk-validate-plugins
cmk -U
omd restart

Wenn du lieber alles selbst anlegst, ist die benötigte Struktur:

su - <CHECKMK_SITE>
mkdir -p ~/local/lib/python3/cmk_addons/plugins/homeassistant/{libexec,rulesets,server_side_calls,agent_based}

Vollständiger Quellcode zum Kopieren

Die ZIP ist bequemer, aber für Nachvollziehbarkeit steht jede Datei hier zusätzlich vollständig bereit.

1. libexec/agent_homeassistant

#!/usr/bin/env python3

import argparse
import json
import sys
import urllib.error
import urllib.request

ENTITIES = (
    "update.home_assistant_core_update",
    "update.home_assistant_supervisor_update",
    "update.home_assistant_operating_system_update",
)


def get_entity(base_url: str, token: str, entity_id: str) -> dict:
    request = urllib.request.Request(
        f"{base_url.rstrip('/')}/api/states/{entity_id}",
        headers={
            "Authorization": f"Bearer {token}",
            "Accept": "application/json",
        },
    )
    with urllib.request.urlopen(request, timeout=10) as response:
        return json.loads(response.read().decode("utf-8"))


def main() -> None:
    parser = argparse.ArgumentParser(description="Checkmk special agent for Home Assistant")
    parser.add_argument("--url", required=True, help="Home Assistant base URL")
    args = parser.parse_args()

    token = sys.stdin.read().strip()
    if not token:
        print("<<<homeassistant_updates:sep(0)>>>")
        print(json.dumps({"status": "error", "error": "No API token received"}))
        return

    result = {"status": "ok", "components": []}

    try:
        for entity_id in ENTITIES:
            data = get_entity(args.url, token, entity_id)
            attributes = data.get("attributes", {})
            result["components"].append(
                {
                    "entity_id": entity_id,
                    "state": data.get("state", "unknown"),
                    "title": attributes.get("title")
                    or attributes.get("friendly_name")
                    or entity_id,
                    "installed_version": attributes.get("installed_version", "unknown"),
                    "latest_version": attributes.get("latest_version", "unknown"),
                }
            )
    except (urllib.error.URLError, urllib.error.HTTPError, TimeoutError, ValueError) as exc:
        result = {"status": "error", "error": str(exc)}

    print("<<<homeassistant_updates:sep(0)>>>")
    print(json.dumps(result, separators=(",", ":")))


if __name__ == "__main__":
    main()
2. rulesets/special_agent.py

#!/usr/bin/env python3

from cmk.rulesets.v1 import Help, Title
from cmk.rulesets.v1.form_specs import (
    DefaultValue,
    Dictionary,
    DictElement,
    Password,
    String,
    migrate_to_password,
)
from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic


def _formspec():
    return Dictionary(
        title=Title("Home Assistant via REST API"),
        help_text=Help(
            "Monitor Home Assistant Core, Supervisor and Operating System "
            "update status using the Home Assistant REST API."
        ),
        elements={
            "url": DictElement(
                required=True,
                parameter_form=String(
                    title=Title("Home Assistant URL"),
                    prefill=DefaultValue("http://<HOME_ASSISTANT_IP>:8123"),
                ),
            ),
            "token": DictElement(
                required=True,
                parameter_form=Password(
                    title=Title("Long-lived access token"),
                    migrate=migrate_to_password,
                ),
            ),
        },
    )


rule_spec_homeassistant = SpecialAgent(
    topic=Topic.APPLICATIONS,
    name="homeassistant",
    title=Title("Home Assistant via REST API"),
    parameter_form=_formspec,
)
3. server_side_calls/special_agent.py

#!/usr/bin/env python3

from cmk.server_side_calls.v1 import SpecialAgentCommand, SpecialAgentConfig, noop_parser


def _agent_arguments(params, host_config):
    # The secret is passed via stdin rather than as a command-line argument.
    # This avoids exposing it in the process list.
    yield SpecialAgentCommand(
        command_arguments=["--url", params["url"]],
        stdin=params["token"].unsafe(),
    )


special_agent_homeassistant = SpecialAgentConfig(
    name="homeassistant",
    parameter_parser=noop_parser,
    commands_function=_agent_arguments,
)
4. agent_based/homeassistant_updates.py

#!/usr/bin/env python3

import itertools
import json

from cmk.agent_based.v2 import AgentSection, CheckPlugin, Result, Service, State


def parse_homeassistant_updates(string_table):
    try:
        raw = " ".join(itertools.chain.from_iterable(string_table))
        return json.loads(raw)
    except (json.JSONDecodeError, TypeError, ValueError):
        return {
            "status": "error",
            "error": "Invalid data received from Home Assistant special agent",
        }


def discover_homeassistant_updates(section):
    if section:
        yield Service()


def check_homeassistant_updates(section):
    if section.get("status") != "ok":
        yield Result(
            state=State.CRIT,
            summary=f"Home Assistant API error: {section.get('error', 'unknown error')}",
        )
        return

    components = section.get("components", [])
    if not components:
        yield Result(state=State.CRIT, summary="No Home Assistant update information received")
        return

    updates = []
    details = []

    for component in components:
        title = component.get("title", "Unknown component")
        state = component.get("state", "unknown")
        installed = component.get("installed_version", "unknown")
        latest = component.get("latest_version", "unknown")
        details.append(f"{title}: {installed} -> {latest}")

        if state == "on":
            updates.append(f"{title} {installed} -> {latest}")
        elif state != "off":
            yield Result(
                state=State.CRIT,
                summary=f"{title} returned unexpected state '{state}'",
            )
            return

    if updates:
        yield Result(
            state=State.WARN,
            summary=f"{len(updates)} update(s) available: {', '.join(updates)}",
            details="n".join(details),
        )
    else:
        yield Result(
            state=State.OK,
            summary="Core, Supervisor and Operating System are up to date",
            details="n".join(details),
        )


agent_section_homeassistant_updates = AgentSection(
    name="homeassistant_updates",
    parse_function=parse_homeassistant_updates,
)

check_plugin_homeassistant_updates = CheckPlugin(
    name="homeassistant_updates",
    service_name="HomeAssistant Updates",
    discovery_function=discover_homeassistant_updates,
    check_function=check_homeassistant_updates,
)
Security-Detail: Im mitgelieferten Paket wird der Token vom Server-Side-Call über stdin an den Special Agent übergeben. Damit landet er nicht als Klartext-Argument in der Prozessliste. Das ist besser als --token … auf der Kommandozeile.

11. Regel für den Home-Assistant-Special-Agent anlegen

Nach cmk-validate-plugins und einem Neustart der Site erscheint unter Setup → Agents → Other integrations der neue Eintrag Home Assistant via REST API.

Anonymisierte Checkmk Special Agent Regel

Trage die URL der eigenen Home-Assistant-Instanz ein, wähle Explicit oder den Checkmk-Passwortspeicher für den Token und beschränke die Regel auf den Home-Assistant-Host.

12. Host für API-Integration und Piggyback konfigurieren

Wenn der Host seine Infrastruktur-Daten bereits per Proxmox-Piggyback bekommt, muss der Special Agent zusätzlich ausgeführt werden dürfen. In unserem Aufbau ist kein normaler Checkmk-Agent in HAOS installiert. Deshalb steht Checkmk agent / API integrations auf Configured API integrations, no Checkmk agent.

Anonymisierte Checkmk Host-Eigenschaften
Piggyback bleibt trotzdem aktiv: Proxmox liefert VM-Daten, der Home-Assistant-Special-Agent liefert zusätzlich die API-Sektion. Checkmk kombiniert beide Datenquellen für denselben Host.

13. CLI-Test, Discovery und Service-Check

Bevor du in der GUI suchst, prüfe auf der Shell, ob die neue Agentensektion wirklich ankommt:

cmk -d homeassistant01 | grep -A3 -B2 homeassistant_updates
cmk -vv --debug -d homeassistant01
cmk -IIv homeassistant01
cmk -Rv homeassistant01

Eine funktionierende Ausgabe enthält ungefähr:

<<<homeassistant_updates:sep(0)>>>
{"status":"ok","components":[{"entity_id":"update.home_assistant_core_update","state":"off","title":"Home Assistant Core","installed_version":"<VERSION>","latest_version":"<VERSION>"}, ...]}

Anschließend findet die Service Discovery den neuen Service HomeAssistant Updates. Wenn alle drei Komponenten aktuell sind, ist der Service OK. Sobald mindestens eine Update-Entity on meldet, wird er WARN.

14. Ergebnis: sinnvolle Aufgabenteilung

Anonymisierte Checkmk Gesamtübersicht
Service Datenquelle Zweck
HomeAssistant Web HTTP Active Check Frontend erreichbar
HomeAssistant API HTTP Active Check + Bearer Token authentifizierte REST API funktioniert
HomeAssistant Updates Custom Special Agent Core/Supervisor/OS Updates
Proxmox VE CPU Utilization Piggyback VM CPU
Proxmox VE Memory Usage Piggyback VM RAM
Proxmox VE Disk Throughput Piggyback I/O
Proxmox VE Network Throughput Piggyback Netzwerk
Proxmox VE VM Backup Status Piggyback Backup
Proxmox VE VM Info Piggyback Status und Uptime
Proxmox VE VM Snapshot age Piggyback Snapshot-Zustand

15. Troubleshooting

Problem Typische Ursache Prüfung
HomeAssistant Web CRIT Port, URL, Firewall oder HTTP/HTTPS falsch curl -I http://<HOME_ASSISTANT_IP>:8123/
API liefert 401 Token ungültig oder widerrufen Bearer-Header mit curl testen
API OK, String-Check CRIT Trailing Slash oder Suchtext falsch /api/ verwenden; Antwort prüfen
Special Agent fehlt in GUI Ruleset-Plugin wird nicht geladen cmk-validate-plugins, dann Web/Site neu starten
cmk -d zeigt nur Piggyback API integrations am Host nicht aktiviert oder Regel greift nicht cmk -D homeassistant01 und Host Properties prüfen
Service wird nicht entdeckt Agentensektion fehlt oder Pluginname passt nicht cmk -d homeassistant01 | grep homeassistant_updates
RAM permanent WARN Linux Cache wird als benutzt gezählt Swap und Memory Pressure prüfen, erst dann Limits anpassen

16. Fazit und Ausblick

Damit überwacht Checkmk Home Assistant nicht nur als VM, sondern als Anwendung. Proxmox liefert die Infrastruktur-Sicht, der HTTP-Check prüft das Frontend, der authentifizierte API-Check prüft Home Assistant selbst und der Special Agent ergänzt Update-Informationen. Genau diese Trennung macht das Setup belastbar und nachvollziehbar.

Was ich bewusst nicht in Checkmk kippen würde: hunderte Sensoren, Energiezeitreihen, Temperaturhistorien oder Wasserverbrauch. Dafür ist Grafana die bessere Oberfläche. Checkmk bleibt für Zustände, Erreichbarkeit, Schwellenwerte und Alarmierung zuständig.

Mögliche Erweiterungen des Special Agents

  • kritische unavailable-Entities überwachen
  • Add-on-Updates auswerten
  • Recorder-/Datenbank-Zustand prüfen
  • MQTT oder Zigbee2MQTT als eigene Services abbilden
  • Home-Assistant-Backup-Zustand ergänzen
  • Zertifikatsablauf überwachen

Quellen und weiterführende Dokumentation

Getesteter Aufbau: Checkmk Community 2.5.0p11. Menünamen und Plugin-APIs können sich in späteren Versionen ändern. Vor Updates eigene Erweiterungen mit cmk-validate-plugins prüfen.