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.
<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
Checkmk 2.5
- Proxmox-Piggyback
- HTTP Active Checks
- REST-API-Prüfung
- Home-Assistant-Special-Agent
Home Assistant
- Webinterface auf Port 8123
- authentifizierte REST API
- Core-Updates
- Supervisor-Updates
- HAOS-Updates
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 |
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.

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.
- Swap-in / Swap-out
- Memory Pressure
- OOM-Ereignisse
- tatsächliche Core-Nutzung
- 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.

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.
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.

| 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. |
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_updateupdate.home_assistant_supervisor_updateupdate.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 |
Enthält alle vier Dateien plus README. Keine internen IPs, Hostnamen oder Tokens.
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,
)
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.

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.

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

| 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
- Checkmk: Spezialagenten entwickeln
- Checkmk: Agentenbasierte Check-Plugins entwickeln
- Checkmk Plug-in API Reference
- Home Assistant REST API
- Home Assistant Authentication
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.
