Zurück zur Startseite

Hilfe & Anleitungen

Alles was du brauchst, um CampMatic einzubauen, einzurichten und loszulegen.

  1. Datenverbindung herstellen (RJ12)

    Die CampMatic Box wird per RJ12-Kabel an den LinBUS der Truma angeschlossen. Dafür gibt es drei Wege — nimm den, der bei deinem Fahrzeug passt.

    Variante 1 — Am CP Plus abzweigen (empfohlen):
    Der einfachste Weg: An die Truma Heizung selbst musst du gar nicht heran — der komplette Anschluss dort entfällt, das Öffnen der Abdeckung eingeschlossen. Auf der Rückseite der Truma CP Plus Steuerung das dort eingesteckte RJ12-Kabel abziehen und in den Eingang des RJ12-Splitters stecken. Vom Splitter geht ein Ausgang mit demselben Kabel zurück ins CP Plus, der zweite Ausgang führt über das zusätzliche RJ12-Kabel zur CampMatic Box. CP Plus und CampMatic hängen dann parallel am selben LinBUS und stören sich nicht. Splitter und Zusatzkabel gibt es bei der Bestellung als RJ12 Splitter-Set dazu.

    Variante 2 — Direkt an der Truma Heizung:
    Kommst du an die Rückseite des CP Plus nicht heran oder ist dahinter zu wenig Platz für Splitter und Stecker: Abdeckung über der Truma Heizung abnehmen (markiert mit Pfeil und Aufschrift "open") und den RJ12-Stecker der CampMatic Box in die rechte freie Buchse der Truma Heizung stecken. Hierfür wird kein Splitter benötigt.Variante 3 — Eine vorhandene Truma iNet Box ersetzen:
    Sitzt in deinem Fahrzeug bereits eine Truma iNet Box und soll die CampMatic an ihre Stelle treten: Das RJ12-Kabel von der iNet Box abziehen und die iNet Box ausbauen. Du hast dann zwei Kabelenden mit jeweils einem männlichen RJ12-Stecker — dein vorhandenes Kabel und das Kabel der CampMatic Box. Die beiden lassen sich nicht direkt zusammenstecken; dazwischen kommt eine RJ12-Kupplung (Buchse auf Buchse), dann ist die Verbindung fertig. Die Kupplung gibt es bei der Bestellung als Zubehör dazu — für die Varianten 1 und 2 wird sie nicht gebraucht.



    Variante 1 ist im Video Schritt für Schritt gezeigt — Splitter einstecken, Kabel zurück ins CP Plus, zweiter Ausgang zur Box.

  2. 12V Stromversorgung anschließen

    Die CampMatic Box benötigt lediglich eine 12V Stromversorgung — egal woher. Eine Verbindung mit dem CP Plus ist nicht erforderlich. Du hast zwei Möglichkeiten:

    Option A — Über 12V Kabel (rot/schwarz):
    Das mitgelieferte rot/schwarze Kabel an eine beliebige 12V Stromquelle im Camper anschließen. So funktioniert die Box völlig unabhängig vom CP Plus.

    Option B — Bequem am CP Plus abgreifen (JST-PH Stecker):
    Wenn du den Strom direkt am CP Plus abgreifen möchtest: Auf der Rückseite der Truma CP Plus Steuerung den roten 12V Stromstecker abziehen. Diesen in den weiblichen JST-PH Stecker der CampMatic Box stecken, dann den männlichen JST-PH Stecker der Box in die Steuerung einstecken. Hierbei wird nur die 12V Versorgungsspannung genutzt — keine Datenverbindung.

  3. Reset durchführen

    3 Minuten warten, damit die CampMatic Box starten kann. Dann im Menü der Truma Steuerung zu Reset → PR SET navigieren und den Reset starten.

  4. CampMatic erkennen lassen

    Nach dem Reset im Menü Index prüfen, ob ein neuer (dritter) Eintrag vorhanden ist. Dieser muss T23.700 anzeigen — dann ist die CampMatic Box erkannt und betriebsbereit. Falls nicht, den Reset nochmal durchführen.

  1. CampMatic Box

    Das ist die CampMatic Box — kompakt, fertig verkabelt und bereit zum Einbau.

  2. Sitzbank lokalisieren

    Die Sitzbank im VW Grand California, unter der sich das Servicefach befindet. Hier wird die CampMatic Box eingebaut.

  3. Sitzauflage entfernen

    Die Sitzauflage ist mit Klettklebeband befestigt. Einfach abheben — kein Werkzeug nötig.

  4. Holzplatte abschrauben

    Nach dem Entfernen der Auflage werden die Schrauben der Holzplatte sichtbar. Alle Schrauben lösen und Platte abnehmen.

  5. Steuerung (CP Plus) abschrauben

    Das Truma CP Plus Bedienteil ist mit 3 Schrauben befestigt. Alle lösen und Steuerung vorsichtig umdrehen.

  6. Datenverbindung herstellen (RJ12)

    Die CampMatic Box wird per RJ12-Kabel an den LinBUS der Truma angeschlossen. Dafür gibt es drei Wege — nimm den, der bei deinem Fahrzeug passt.

    Variante 1 — Am CP Plus abzweigen (empfohlen):
    Der einfachste Weg: An die Truma Heizung selbst musst du gar nicht heran — der komplette Anschluss dort entfällt, das Öffnen der Abdeckung eingeschlossen. Auf der Rückseite der Truma CP Plus Steuerung das dort eingesteckte RJ12-Kabel abziehen und in den Eingang des RJ12-Splitters stecken. Vom Splitter geht ein Ausgang mit demselben Kabel zurück ins CP Plus, der zweite Ausgang führt über das zusätzliche RJ12-Kabel zur CampMatic Box. CP Plus und CampMatic hängen dann parallel am selben LinBUS und stören sich nicht. Splitter und Zusatzkabel gibt es bei der Bestellung als RJ12 Splitter-Set dazu.

    Variante 2 — Direkt an der Truma Heizung:
    Kommst du an die Rückseite des CP Plus nicht heran oder ist dahinter zu wenig Platz für Splitter und Stecker: Abdeckung über der Truma Heizung abnehmen (markiert mit Pfeil und Aufschrift "open") und den RJ12-Stecker der CampMatic Box in die rechte freie Buchse der Truma Heizung stecken. Hierfür wird kein Splitter benötigt.Variante 3 — Eine vorhandene Truma iNet Box ersetzen:
    Sitzt in deinem Fahrzeug bereits eine Truma iNet Box und soll die CampMatic an ihre Stelle treten: Das RJ12-Kabel von der iNet Box abziehen und die iNet Box ausbauen. Du hast dann zwei Kabelenden mit jeweils einem männlichen RJ12-Stecker — dein vorhandenes Kabel und das Kabel der CampMatic Box. Die beiden lassen sich nicht direkt zusammenstecken; dazwischen kommt eine RJ12-Kupplung (Buchse auf Buchse), dann ist die Verbindung fertig. Die Kupplung gibt es bei der Bestellung als Zubehör dazu — für die Varianten 1 und 2 wird sie nicht gebraucht.



    Variante 1 ist im Video Schritt für Schritt gezeigt — Splitter einstecken, Kabel zurück ins CP Plus, zweiter Ausgang zur Box.

  7. CampMatic Box anschließen

    Auf der Rückseite der Steuerung den roten 12V Stromstecker abziehen. Diesen in den weiblichen JST-PH Stecker der CampMatic Box stecken. Dann den männlichen JST-PH Stecker der Box in die Truma Steuerung einstecken. Die CampMatic Box wird praktisch zwischen die bestehende Stromversorgung geschaltet.

  8. Steuerung wieder befestigen

    Die Steuerung mit den 3 Schrauben wieder befestigen. Dann 3 Minuten warten, damit die CampMatic Box starten kann.

  9. Reset durchführen

    Im Menü der Truma Steuerung zu Reset → PR SET navigieren und den Reset starten.

  10. CampMatic erkennen lassen

    Nach dem Reset im Menü Index prüfen, ob ein neuer (dritter) Eintrag vorhanden ist. Dieser muss T23.700 anzeigen — dann ist die CampMatic Box erkannt und betriebsbereit. Falls nicht, den Reset nochmal durchführen.

  1. CampMatic Box einschalten & warten

    Schließe die CampMatic Box an die Stromversorgung an und warte ca. 3 Minuten, bis das Gerät vollständig hochgefahren ist und der Access Point bereit ist.

  2. Mit CampMatic Access Point verbinden

    Verbinde dein Smartphone oder Laptop mit dem CampMatic WLAN-Netzwerk. Das Passwort findest du auf dem Sticker auf der CampMatic Box oder in der CampMatic App auf der Status-Seite.

  3. Konfigurationsseite öffnen

    Sobald dein Gerät mit dem CampMatic-Netzwerk verbunden ist, öffne http://192.168.4.1/ im Browser. Du wirst nach einem Login gefragt — Benutzername: admin, Passwort: steht auf dem Sticker der Box oder in der CampMatic App auf der Status-Seite.

    Wichtig: Falls nach dem Login nicht die WLAN-Auswahl erscheint, sondern die normale Steuerungsoberfläche, öffne direkt http://192.168.4.1/captiveportal — dort findest du die WLAN-Auswahl.

  4. WLAN-Netzwerk verbinden

    Wähle dein WLAN-Netzwerk aus und gib das Passwort ein. Die CampMatic Box verbindet sich und zeigt nach erfolgreicher Verbindung die lokale Truma-Steuerung an.

  5. WLAN später ändern

    Wenn du das WLAN-Netzwerk später ändern möchtest: Die CampMatic Box öffnet automatisch einen eigenen Access Point, sobald das konfigurierte Netzwerk nicht erreichbar ist. Verbinde dich erneut mit dem CampMatic-Netzwerk und rufe http://192.168.4.1/captiveportal auf, um ein neues WLAN zu konfigurieren.

  1. SIM-Karte vorbereiten

    Bevor die 4G CampMatic Box in Betrieb genommen werden kann, muss eine SIM-Karte eingelegt werden.

    Wichtig: Die SIM-Karte darf keine PIN-Code-Sperre haben. Sonst kann sich die Box nicht ins Mobilfunknetz einbuchen. Wie deaktiviere ich die PIN-Sperre?

  2. Box im ausgeschalteten Zustand öffnen

    Trenne die CampMatic Box vor dem Öffnen unbedingt von der Stromversorgung. Das Gehäuse vorsichtig öffnen: Auf dem Deckel ist die GSM-Antenne montiert, die über ein Kabel mit der Platine verbunden ist. Deckel nur langsam und ohne Zug am Antennenkabel abheben.

  3. SIM-Slot öffnen

    Auf der Platine befindet sich der SIM-Kartenhalter. Schiebe die Metallverriegelung in Pfeilrichtung (siehe Bild), um den Halter zu entriegeln, und klappe ihn vorsichtig nach oben.

  4. SIM einlegen & Box schließen

    SIM-Karte mit den Kontakten nach unten in den Halter einlegen (abgeschrägte Ecke beachten). Halter zuklappen und die Verriegelung gegen die Pfeilrichtung schieben, bis sie einrastet. Deckel wieder vorsichtig aufsetzen — das Antennenkabel darf nicht eingeklemmt werden — und das Gehäuse verschrauben.

  5. CampMatic Box einschalten & warten

    Box wieder mit der Stromversorgung verbinden und ca. 3 Minuten warten, bis das Gerät hochgefahren ist und sich ins Mobilfunknetz eingebucht hat.

  6. Mit CampMatic Access Point verbinden

    Bei 4G-Geräten ist der Access Point immer aktiv — eine WLAN-Konfiguration ist nicht nötig. Verbinde dein Smartphone oder Laptop mit dem CampMatic WLAN-Netzwerk. Das Passwort findest du auf dem Sticker auf der CampMatic Box oder in der CampMatic App auf der Status-Seite.

  7. Lokale Steuerung öffnen

    Öffne http://192.168.4.1/ im Browser. Login: Benutzername admin, Passwort vom Sticker bzw. aus der CampMatic App. Die Truma-Steuerung wird lokal angezeigt — die 4G Box kommuniziert unabhängig vom lokalen WLAN direkt über das Mobilfunknetz mit der CampMatic Cloud.

  1. Registrierungsseite öffnen

    Gehe zu campmatic.de/app/register.php und fülle das Registrierungsformular aus. Die PIN für die Registrierung findest du auf dem Sticker auf deiner CampMatic Box.

  2. E-Mail-Adresse bestätigen

    Nach der Registrierung wird eine Bestätigungsmail an die angegebene E-Mail-Adresse gesendet. Klicke auf den Link in der E-Mail, um dein Konto zu aktivieren. Prüfe ggf. auch den Spam-Ordner.

  3. Anmelden und losheizen

    Nach der Bestätigung kannst du dich unter campmatic.de/app anmelden und deine Heizung steuern.

Dein CampMatic-Gerät publiziert seine Sensoren und Steuerungen über MQTT. Damit Home Assistant alle Entitäten per Auto-Discovery findet, brauchst du eine MQTT-Verbindung zum CampMatic-Broker — entweder über einen lokalen Mosquitto als Bridge (empfohlen, robust gegen WAN-Aussetzer und für mehrere Geräte) oder direkt aus Home Assistant heraus.

Die Reiter im Überblick: Bridge und Direkt sind die zwei Wege, HA mit dem Broker zu verbinden — einen davon brauchst du. Truma zeigt fertige Lovelace-Karten für Heizung, Warmwasser und Energiemix. Gasflasche, Bordbatterie und Innenklima decken die BLE-Zusatzsensorik ab (Mopeka, BM2, Ruuvi): komplette YAML-Beispiele inklusive der Umrechnungen, die diese Sensoren brauchen — Füllstand aus der Ultraschall-Laufzeit, Ladezustand aus der Ruhespannung, Taupunkt aus Temperatur und Feuchte.

📦 Alles davon gibt es auch als fertiges Paket zum Herunterladen: campmatic-homeassistant.zip

  1. Zugangsdaten von der Status-Seite holen

    Melde dich auf campmatic.de/app an und öffne die Status-Seite. Die Karte „MQTT Bridge (Home Assistant)" zeigt: Host (immer campmatic.de), Port (8883, TLS), Benutzername (z. B. campmatic_003), Passwort (Auge-Symbol zum Anzeigen) und Topic-Prefix (z. B. campmatic/003). Diese Werte ersetzen unten alle <Platzhalter>. Die spitzen Klammern werden dabei mitentfernt — aus remote_username <mqtt_user> wird also remote_username campmatic_003, nicht <campmatic_003>.

    Ein Wert steht nicht auf der Status-Seite: der interne Gerätename <node>. Er wird für die Discovery-Zeile der Bridge gebraucht und ergibt sich aus der Gerätenummer:
    • Gerät 001–051grand-cali-<NNN>, z. B. grand-cali-003
    • Gerät 052 und höher → campmatic-<NNN>, z. B. campmatic-054
    Im Zweifel im MQTT Explorer auf homeassistant/# lauschen: die Config-Topics heißen homeassistant/<Typ>/<node>/<Entität>/config.

  2. Mosquitto starten

    Es gibt zwei Wege — die folgenden Schritte zeigen jeweils beide.

    A · Home Assistant OS / Supervised (Add-on): Einstellungen → Add-ons → Add-on-Store → Mosquitto broker (offiziell) installieren und starten. Damit ist dieser Schritt erledigt — der Code unten ist nur für Weg B.

    B · Docker / Compose (z. B. Synology, Pi, NUC): mit der Datei unten einen eigenen Mosquitto starten.

    Wichtig: Weder diese docker-compose.yml noch die mosquitto.conf aus Schritt 4 gehören in die configuration.yaml von Home Assistant. Es sind Dateien des MQTT-Brokers — Home Assistant sieht sie nie.

    # Weg B (Docker/Compose) — beim Add-on nicht nötig
    # docker-compose.yml
    services:
      mqtt:
        image: eclipse-mosquitto:latest
        container_name: mqtt5
        restart: unless-stopped
        ports:
          - "1883:1883"
        volumes:
          - ./config:/mosquitto/config
          - ./data:/mosquitto/data
          - ./log:/mosquitto/log
  3. Lokales Passwort anlegen

    Lege einen HA-seitigen Benutzer im lokalen Broker an. Dieses Passwort hat nichts mit dem CampMatic-Passwort zu tun — es schützt nur die lokale Verbindung zwischen HA und Mosquitto.

    A · Add-on: Im Add-on Mosquitto broker → Reiter Konfiguration den Benutzer unter logins: eintragen, speichern, Add-on neu starten. Kein Terminal nötig.
    B · Docker: Den Befehl unten einmal ausführen.

    # Weg A (Add-on) — Konfiguration des Mosquitto-Add-ons
    logins:
      - username: homeassistant
        password: <lokales_passwort>
    # Weg B (Docker)
    docker exec -it mqtt5 mosquitto_passwd -c /mosquitto/config/pwfile homeassistant
    # enter a HA-side password
  4. Bridge konfigurieren

    Ersetze jeden <Platzhalter> mit dem Wert von der Status-Seite. bridge_capath /etc/ssl/certs nutzt den System-CA-Speicher — kein CA-File zu pflegen, Hostname-Prüfung bleibt an.

    Es sind zwei topic-Zeilen, und beide werden gebraucht:
    topic # both 0 <prefix>/ <prefix>/ holt die Messwerte und schickt Schaltbefehle zurück.
    topic homeassistant/+/<node>/# in 0 holt die Auto-Discovery-Nachrichten. Die liegen nach MQTT-Standard unter homeassistant/… und damit außerhalb deines Prefixes — ohne diese Zeile legt Home Assistant keine einzige Entität an, obwohl im MQTT Explorer alle Werte ankommen. Das + steht für den Entitätstyp (sensor, climate, …), in heißt: nur vom CampMatic-Broker zu dir. Die Nachrichten sind auf dem Broker dauerhaft gespeichert („retained") und treffen daher normalerweise sofort beim Verbinden ein. Kommt trotz korrekter Zeile nichts an, die Box einmal kurz stromlos machen: beim nächsten Verbinden meldet sie ihre Entitäten neu an.

    A · Add-on: Im Add-on → Konfiguration die Option customize auf active: true setzen. Dann den Ordner /share/mosquitto anlegen und dort die Datei campmatic.conf ablegen: nur der connection-Block, ohne listener, password_file und persistence — die bringt das Add-on schon mit. Anschließend Add-on neu starten.

    Achtung, häufigste Stolperfalle: /share liegt neben dem Konfigurationsverzeichnis (/homeassistant bzw. /config), nicht darin. Ein Ordner /homeassistant/share/mosquitto wird vom Add-on nicht gefunden. Drei Wege, ihn richtig anzulegen:
    Terminal & SSH (am schnellsten): mkdir -p /share/mosquitto
    File editor: über das Ordner-Symbol so weit nach oben navigieren, bis homeassistant und share nebeneinander stehen, dann in share wechseln
    Samba: im Explorer die Freigabe share öffnen (nicht config)
    B · Docker: config/mosquitto.conf neben der Passwort-Datei anlegen, danach docker restart mqtt5.

    # Weg A (Add-on) — 1. Konfiguration des Mosquitto-Add-ons
    customize:
      active: true
      folder: mosquitto
    # Weg A (Add-on) — 2. Datei /share/mosquitto/campmatic.conf
    connection campmatic-<NNN>
    address campmatic.de:8883
    bridge_capath /etc/ssl/certs
    remote_username <mqtt_user>
    remote_password <mqtt_pass>
    # Messwerte rein, Schaltbefehle raus
    topic # both 0 <prefix>/ <prefix>/
    # Auto-Discovery — ohne diese Zeile bleiben die Entitaeten aus
    topic homeassistant/+/<node>/# in 0
    # Weg B (Docker) — config/mosquitto.conf
    # Local listener — only HA talks to this
    allow_anonymous false
    listener 1883
    password_file /mosquitto/config/pwfile
    
    persistence true
    persistence_file mosquitto.db
    persistence_location /mosquitto/data/
    
    # --- Bridge to CampMatic ---
    connection campmatic-<NNN>
    address campmatic.de:8883
    bridge_capath /etc/ssl/certs
    remote_username <mqtt_user>
    remote_password <mqtt_pass>
    # Messwerte rein, Schaltbefehle raus
    topic # both 0 <prefix>/ <prefix>/
    # Auto-Discovery — ohne diese Zeile bleiben die Entitaeten aus
    topic homeassistant/+/<node>/# in 0
  5. Bridge prüfen

    In den Logs sollte „Connecting bridge" erscheinen, ohne TLS-Fehler — beim Add-on im Reiter Protokoll, bei Docker mit dem Befehl unten.

    Zuerst die wichtigste Frage: steht die Zeile überhaupt da? Sie erscheint im Startprotokoll nach den Opening … listen socket-Zeilen und vor mosquitto version 2.x running, und enthält den Namen Ihres connection-Blocks: Connecting bridge campmatic-003 (campmatic.de:8883). Je nach Version kann dort auch Connecting bridge (step 1) … stehen — suchen Sie das Protokoll einfach nach Connecting bridge ab. Fehlt die Zeile, ist die Bridge-Datei gar nicht eingelesen worden — dann bringt es nichts, im Log nach Fehlermeldungen zu suchen, denn Mosquitto weiß nichts von der Bridge. Beim Add-on liegt das fast immer an einem von drei Punkten: customize: steht nicht auf active: true (der Ordner allein genügt nicht), die Datei liegt in /homeassistant/share/mosquitto statt in /share/mosquitto, oder sie heißt nicht auf .conf (manche Editoren hängen unbemerkt .txt an).

    Nicht erschrecken: Die Zeilen Protocol error from ::1: First packet not CONNECT und Client ::1 disconnected: protocol error stehen bei jedem Start des Add-ons im Protokoll. Das ist ein interner Portcheck und kein Fehler — die Ursache eines Problems ist es nie.

    Steht „Connecting bridge" da, aber die Verbindung klappt nicht: Bei Connection refused Benutzername/Passwort von der Status-Seite neu kopieren. Bei certificate verify failed fehlt der System-CA-Store — Add-on bzw. Image aktualisieren. Meldet das Add-on Unable to open include_dir '/share/mosquitto' und beendet sich, fehlt der Ordner aus Schritt 4 — meist wurde er versehentlich im Konfigurationsverzeichnis angelegt (/homeassistant/share/mosquitto) statt daneben. Steht der Benutzername im Log in spitzen Klammern, wurden beim Ersetzen die <> stehen gelassen.

    # Weg B (Docker)
    docker logs --tail 20 mqtt5 | grep -iE 'bridge|tls|connect'
  6. Home Assistant mit dem lokalen Broker verbinden

    In HA: Einstellungen → Geräte & Dienste → Integration hinzufügen → MQTT. Broker: beim Add-on core-mosquitto, bei Docker Hostname/IP des Containers (z. B. mqtt5). Port: 1883. Benutzer/Passwort: der lokale HA-Benutzer aus Schritt 3. SSL aus. Nach dem Speichern erscheinen die CampMatic-Entitäten automatisch über MQTT-Discovery.

    Es kommen Werte an, aber keine Entitäten? Dann fehlt die zweite topic-Zeile aus Schritt 4. Zum Prüfen im MQTT Explorer auf dem lokalen Broker (nicht auf campmatic.de) auf homeassistant/# lauschen: bleibt der Zweig leer, während unter deinem Prefix Werte eintreffen, ist genau das die Ursache. Zeile ergänzen, Mosquitto neu starten — die Entitäten erscheinen binnen Sekunden. Ansonsten unter MQTT → Konfigurieren prüfen, dass „Discovery aktivieren" an ist und das Discovery-Präfix homeassistant lautet.

  7. Mehrere Geräte über eine Bridge

    Pro Gerät einen weiteren connection-Block in mosquitto.conf ergänzen — alle laufen über denselben lokalen Broker, HA bleibt mit einer einzigen MQTT-Integration verbunden. Jeder Block braucht beide topic-Zeilen. Achte darauf, dass der Gerätename in der Discovery-Zeile bei Geräten bis 051 grand-cali-… lautet, nicht campmatic-… (siehe Schritt 1).

    connection campmatic-003
    address campmatic.de:8883
    bridge_capath /etc/ssl/certs
    remote_username campmatic_003
    remote_password <pw_003>
    topic # both 0 campmatic/003/ campmatic/003/
    topic homeassistant/+/grand-cali-003/# in 0
    
    connection campmatic-004
    address campmatic.de:8883
    bridge_capath /etc/ssl/certs
    remote_username campmatic_004
    remote_password <pw_004>
    topic # both 0 campmatic/004/ campmatic/004/
    topic homeassistant/+/grand-cali-004/# in 0
  1. Zugangsdaten von der Status-Seite holen

    Melde dich auf campmatic.de/app an und öffne die Status-Seite. Die Karte „MQTT Bridge (Home Assistant)" zeigt: Host (immer campmatic.de), Port (8883, TLS), Benutzername (z. B. campmatic_003), Passwort (Auge-Symbol zum Anzeigen) und Topic-Prefix (z. B. campmatic/003). Diese Werte ersetzen unten alle <Platzhalter>. Die spitzen Klammern werden dabei mitentfernt — aus remote_username <mqtt_user> wird also remote_username campmatic_003, nicht <campmatic_003>.

    Ein Wert steht nicht auf der Status-Seite: der interne Gerätename <node>. Er wird für die Discovery-Zeile der Bridge gebraucht und ergibt sich aus der Gerätenummer:
    • Gerät 001–051grand-cali-<NNN>, z. B. grand-cali-003
    • Gerät 052 und höher → campmatic-<NNN>, z. B. campmatic-054
    Im Zweifel im MQTT Explorer auf homeassistant/# lauschen: die Config-Topics heißen homeassistant/<Typ>/<node>/<Entität>/config.

  2. MQTT-Integration in Home Assistant einrichten

    Einstellungen → Geräte & Dienste → Integration hinzufügen → MQTT. Broker: campmatic.de, Port: 8883, Benutzername/Passwort von der Status-Seite, SSL/TLS an, Zertifikatsprüfung „Auto" (System-Trust-Store). Kein CA-File hochladen — der Broker nutzt ein öffentliches TLS-Zertifikat, das HA out of the box vertraut.

  3. Wann lieber Bridge statt direkt?

    Direkt ist okay für ein einzelnes Gerät auf einer HA-Instanz mit stabilem Internet. Bei mehreren CampMatic-Geräten oder häufigen WAN-Aussetzern ist die lokale Bridge (Tab „Bridge") die einzig praktische Lösung — HA-Entitäten bleiben verfügbar, auch wenn die Cloud-Verbindung kurz weg ist.

  1. Auto-Discovery prüfen

    Nach erfolgreicher MQTT-Einrichtung erscheinen die Entitäten automatisch.

    In den YAML-Beispielen unten steht <entity> als Platzhalter. Dafür setzt du den Namensteil ein, den Home Assistant deinem Gerät gegeben hat — er hängt vom Auslieferungsstand ab:
    • Gerät 001–044grand_california_<NNN>, z. B. climate.grand_california_003_truma_heizung
    • Gerät 045 und höher → campmatic_<NNN>, z. B. climate.campmatic_054_truma_heizung
    Nachschauen kannst du es unter Entwicklerwerkzeuge → Zustände mit dem Filter truma: übernimm den ganzen Namensteil vor _truma. Im Downloadpaket erledigt das personalize.sh automatisch.

    Entitäten, die bereits campmatic_<NNN> im Beispiel tragen (Gasflasche, Aufbaubatterie, Ruuvi), bleiben so wie sie sind — die vergibt das Downloadpaket selbst.

    So kann ein fertiges Lovelace-Dashboard aussehen — Klimakarte oben, Statistik-Chips in der Mitte, 24-Stunden-Verlauf darunter, dazu Wassersteuerung, Energiemix und Statusboard:

  2. Raumheizung — Klimakarte mit Chips und 24-h-Graph

    Die polierte Variante: Steuerkarte oben, Chip-Reihe mit Live-Statuswerten, 24-Stunden-Temperaturverlauf unten. Benötigt die HACS-Karten Mushroom, stack-in-card und mini-graph-card. <NNN> durch deine Gerätenummer ersetzen.

    type: custom:stack-in-card
    mode: vertical
    keep:
      background: false
      border_radius: true
    cards:
      - type: custom:mushroom-climate-card
        entity: climate.<entity>_truma_heizung
        name: Raumheizung
        show_temperature_control: true
        hvac_modes:
          - "off"
          - heat
        collapsible_controls: false
        fill_container: true
    
      - type: custom:mushroom-chips-card
        alignment: center
        chips:
          - type: template
            icon: mdi:fire
            content: "{{ states('sensor.<entity>_truma_heizmodus') }}"
            icon_color: >-
              {% if is_state('binary_sensor.<entity>_truma_heizung_aktiv','on') %}
              orange{% else %}disabled{% endif %}
          - type: template
            icon: mdi:thermometer-check
            content: "{{ states('sensor.<entity>_truma_soll_raumtemperatur') | round(0) }} °C"
            icon_color: amber
          - type: template
            icon: mdi:lightning-bolt
            content: "{{ states('sensor.<entity>_truma_elektrische_leistung') }} W"
            icon_color: >-
              {% if is_state('binary_sensor.<entity>_truma_elektro_aktiv','on') %}
              yellow{% else %}disabled{% endif %}
          - type: template
            icon: mdi:fuel
            content: "{{ states('sensor.<entity>_truma_energiemix_status') }}"
            icon_color: >-
              {% if is_state('binary_sensor.<entity>_truma_diesel_aktiv','on') %}
              deep-orange{% else %}disabled{% endif %}
          - type: template
            icon: mdi:check-network
            content: ""
            content_info: none
            icon_color: >-
              {% if is_state('binary_sensor.<entity>_truma_cp_plus_alive','on') %}
              green{% else %}red{% endif %}
    
      - type: custom:mini-graph-card
        name: Temperaturverlauf (24 h)
        icon: mdi:thermometer-lines
        hours_to_show: 24
        points_per_hour: 4
        line_width: 3
        smoothing: true
        show:
          icon: true
          name: true
          labels: true
          extrema: true
          average: true
          fill: fade
          legend: true
          points: false
        entities:
          - entity: sensor.<entity>_truma_raumtemperatur
            name: Raum
            color: "#FF7A00"
          - entity: sensor.<entity>_truma_soll_raumtemperatur
            name: Soll
            color: "#FFC107"
            show_state: true
            y_axis: secondary
  3. Warmwasser — 3-Tasten-Auswahl (Aus / 40 °C / 60 °C)

    Die Truma-Wasserheizung kennt nur Aus / 40 / 60. Statt Schieber drei Chips, die den aktiven Wert hervorheben:

    type: custom:mushroom-chips-card
    alignment: center
    chips:
      - type: template
        icon: mdi:water-off
        content: Aus
        icon_color: >-
          {% if state_attr('climate.<entity>_truma_wasser',
            'temperature') | float(99) == 0 %}red{% else %}disabled{% endif %}
        tap_action:
          action: call-service
          service: climate.set_temperature
          target:
            entity_id: climate.<entity>_truma_wasser
          data:
            temperature: 0
      - type: template
        icon: mdi:thermometer-low
        content: 40 °C
        icon_color: >-
          {% if state_attr('climate.<entity>_truma_wasser',
            'temperature') | float(0) == 40 %}orange{% else %}disabled{% endif %}
        tap_action:
          action: call-service
          service: climate.set_temperature
          target:
            entity_id: climate.<entity>_truma_wasser
          data:
            temperature: 40
      - type: template
        icon: mdi:thermometer-high
        content: 60 °C
        icon_color: >-
          {% if state_attr('climate.<entity>_truma_wasser',
            'temperature') | float(0) == 60 %}red{% else %}disabled{% endif %}
        tap_action:
          action: call-service
          service: climate.set_temperature
          target:
            entity_id: climate.<entity>_truma_wasser
          data:
            temperature: 60
  4. Energiemix-Auswahl

    Eine kompakte Karte für die Auswahl Gas / Elektrisch / Mix:

    type: custom:mushroom-entity-card
    entity: select.<entity>_truma_energiemix
    name: Energiemix
    icon: mdi:fuel
    icon_color: deep-orange
    fill_container: true
  5. Entitäten ausblenden

    Nur in einem Dashboard ausblenden: Karte einfach weglassen. Überall in HA ausblenden: Einstellungen → Geräte & Dienste → MQTT → Gerät → Entität → Zahnrad → „Entität deaktivieren". Die Entität wird auf der Geräteseite nicht gelöscht, nur in HA versteckt.

  1. Warum diese drei Sensoren Handarbeit brauchen

    Truma- und CampMatic-Entitäten meldet die Box per Auto-Discovery an Home Assistant — nach dem Einrichten der MQTT-Verbindung sind sie einfach da. Dazu gehören auch zwei Werte des Batteriewächters: „Bordspannung" und „Bordbatterie Ladezustand" — allerdings nur vom BM2 mit der niedrigsten Slot-Nummer. Für alles Übrige aus der BLE-Sensorik — Mopeka, Ruuvi und die Slot-Topics des BM2 — gilt das nicht: die Box veröffentlicht deren Werte auf eigenen Roh-Topics campmatic/<NNN>/<integration>/<gerät>_<slot>/<feld>, ohne Discovery-Konfiguration. Der Grund: die Sensoren senden teilweise nur Rohbytes, aus denen erst gerechnet werden muss — in der CampMatic App passiert das serverseitig, damit Kalibrierung und neue Flaschentypen ohne Firmware-Update funktionieren.

    In Home Assistant baust du beides einmalig selbst: die MQTT-Sensoren für die Rohwerte und die Template-Sensoren mit der Rechnung. Danach läuft es dauerhaft. Alle Formeln in diesem Bereich sind 1:1 die, die auch die CampMatic App verwendet — App und Home Assistant zeigen also denselben Wert.

    Drei Dinge, die sonst Zeit kosten:
    • Die Roh-Topics sind nicht retained. Nach einem HA-Neustart bleiben die Entitäten unknown, bis das nächste BLE-Paket kommt (Mopeka/Ruuvi ≤ 60 s, BM2 ≤ 30 s). Das ist normal.
    • Deshalb überall expire_after: 2700 (45 min): so zeigt HA einen abgezogenen oder leeren Sensor als nicht verfügbar statt ewig den letzten Wert.
    • Die entity_id setzt sich aus Gerätename + Sensorname zusammen und wird kleingeschrieben und entumlautet: aus „Gasflasche Füllstand" wird sensor.gasflasche_fullstand, aus „Messqualität" wird ..._messqualitat. Nach dem ersten Neustart unter Entwicklerwerkzeuge → Zustände nachsehen und die Templates ggf. anpassen.

    Lieber nicht abtippen? Alle YAML-Blöcke dieses Bereichs gibt es fertig als Paket zum Herunterladen — Package-Datei, Automatisierungen, komplette Dashboard-Ansicht, Mosquitto-Bridge-Vorlage und ein Skript, das die Platzhalter interaktiv ersetzt: campmatic-homeassistant.zip (ca. 20 kB). Die Schritte hier erklären, was in den Dateien passiert — das Paket spart das Tippen.

  2. Slot-Nummer und Tanktyp herausfinden

    Die CampMatic App speichert die Kopplung in einem retained MQTT-Topic. Daraus liest du die slot-Nummer (sie steckt im Topic-Namen als bottle_<S>) und den gekoppelten tank_type. Achtung: beim Neu-Koppeln kann sich der Slot ändern — dann die Topics in der YAML nachziehen.

    # Über die lokale Bridge (Tab "Bridge"):
    mosquitto_sub -h localhost -u homeassistant -P <lokales_pw> \
      -v -t 'campmatic/<NNN>/mopeka/config' -W 5
    
    # Oder direkt gegen den CampMatic-Broker:
    mosquitto_sub -h campmatic.de -p 8883 --capath /etc/ssl/certs \
      -u <mqtt_user> -P <mqtt_pass> \
      -v -t 'campmatic/<NNN>/mopeka/config' -W 5
    
    # Ausgabe (retained, kommt sofort):
    # campmatic/<NNN>/mopeka/config [{"slot":1,"mac":"AA:BB:CC:00:11:22","tank_type":"EUROPE_6KG","medium":"lpg"}]
    #                                       ^^^^^^^^                      ^^^^^^^^^^^^^^^^^^^^^^
    #                                       Slot -> bottle_1              Tanktyp -> full_mm unten
  3. Roh-Sensoren anlegen

    Der Mopeka Pro Check misst per Ultraschall die Laufzeit bis zur Flüssigkeitsoberfläche und sendet ausschließlich rohe Bytes: raw_tof (Laufzeit in µs), raw_t (Temperaturbyte 0–127), battery_raw (Batteriebyte), quality (Echoqualität 0–3) und rssi. Diese fünf kommen hier als MQTT-Sensoren in die configuration.yaml — als Diagnose-Entitäten, weil sie ohne Umrechnung nutzlos sind.

    # configuration.yaml
    # <NNN> = Gerätenummer, <S> = Mopeka-Slot aus dem Schritt davor.
    mqtt:
      sensor:
        - name: "Gasflasche Roh-Laufzeit"
          unique_id: campmatic_<NNN>_gas_raw_tof
          state_topic: "campmatic/<NNN>/mopeka/bottle_<S>/raw_tof"
          state_class: measurement
          icon: mdi:radar
          entity_category: diagnostic
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          payload_available: "online"
          payload_not_available: "offline"
          # YAML-Anker: einmal definieren, in allen weiteren Sensoren nur
          # noch "device: *campmatic_dev" schreiben. Alle Entitäten landen
          # dadurch unter EINEM Gerät in Home Assistant.
          device: &campmatic_dev
            identifiers: ["campmatic_<NNN>"]
            name: "CampMatic <NNN>"
            manufacturer: "CampMatic"
    
        - name: "Gasflasche Roh-Temperaturbyte"
          unique_id: campmatic_<NNN>_gas_raw_t
          state_topic: "campmatic/<NNN>/mopeka/bottle_<S>/raw_t"
          state_class: measurement
          icon: mdi:thermometer
          entity_category: diagnostic
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          device: *campmatic_dev
    
        - name: "Gasflasche Roh-Batteriebyte"
          unique_id: campmatic_<NNN>_gas_raw_batt
          state_topic: "campmatic/<NNN>/mopeka/bottle_<S>/battery_raw"
          state_class: measurement
          icon: mdi:battery-unknown
          entity_category: diagnostic
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          device: *campmatic_dev
    
        - name: "Gasflasche Messqualität"
          unique_id: campmatic_<NNN>_gas_quality
          state_topic: "campmatic/<NNN>/mopeka/bottle_<S>/quality"
          state_class: measurement
          icon: mdi:signal-cellular-2
          entity_category: diagnostic
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          device: *campmatic_dev
    
        - name: "Gasflasche Signalstärke"
          unique_id: campmatic_<NNN>_gas_rssi
          state_topic: "campmatic/<NNN>/mopeka/bottle_<S>/rssi"
          unit_of_measurement: "dBm"
          device_class: signal_strength
          state_class: measurement
          entity_category: diagnostic
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          device: *campmatic_dev
  4. Distanz, Füllstand, Temperatur und Batterie berechnen

    Jetzt die eigentliche Mathematik. Die Schallgeschwindigkeit im Flüssiggas ist temperaturabhängig, deshalb ein Polynom zweiten Grades über das Roh-Temperaturbyte — die Koeffizienten stammen aus dem Mopeka Pro Developers Integration Guide v7. Aus der Distanz wird über zwei Schwellen der Prozentwert. Die Batterieprozente sind die Formel der offiziellen Mopeka-App.

    Wichtig zu wissen: Mopeka weist die 80-%-Sicherheitsfüllmarke als 100 % aus — eine frisch gefüllte Flasche zeigt also korrekt 100 % und nicht 80 %. Und der Füllstand atmet: dieselbe Flasche misst bei 30 °C ein paar Prozent anders als bei 5 °C. Das ist Physik, kein Sensorfehler.

    # configuration.yaml — abgeleitete Werte
    #
    # distance_mm = raw_tof * (c0 + c1*raw_t + c2*raw_t^2)
    #   LPG (Propan/Butan):  c = [ 0.573045, -0.002822, -5.35e-6  ]
    #   Wasser (Pro Check H2O): c = [ 0.600592,  0.003124, -1.368e-5 ]
    # raw_t ist das ROHE Temperaturbyte 0..127, NICHT der °C-Wert.
    template:
      - sensor:
          - name: "Gasflasche Distanz"
            unique_id: campmatic_<NNN>_gas_distanz
            unit_of_measurement: "mm"
            state_class: measurement
            icon: mdi:arrow-expand-vertical
            availability: >-
              {{ has_value('sensor.campmatic_<NNN>_gasflasche_roh_laufzeit')
                 and has_value('sensor.campmatic_<NNN>_gasflasche_roh_temperaturbyte') }}
            state: >-
              {% set tof = states('sensor.campmatic_<NNN>_gasflasche_roh_laufzeit') | float(0) %}
              {% set t   = states('sensor.campmatic_<NNN>_gasflasche_roh_temperaturbyte') | float(0) %}
              {{ (tof * (0.573045 - 0.002822 * t - 5.35e-6 * t * t)) | round(1) }}
    
          # Prozent = (Distanz - empty_mm) / (full_mm - empty_mm) * 100, geklemmt.
          # empty_mm ist bei allen Presets 38 (Restabstand Puck <-> Bodenplatte).
          # full_mm je Tanktyp -> Tabelle im nächsten Schritt.
          - name: "Gasflasche Füllstand"
            unique_id: campmatic_<NNN>_gas_fuellstand
            unit_of_measurement: "%"
            state_class: measurement
            icon: mdi:propane-tank
            availability: "{{ has_value('sensor.gasflasche_distanz') }}"
            state: >-
              {% set mm       = states('sensor.gasflasche_distanz') | float(0) %}
              {% set empty_mm = 38 %}
              {% set full_mm  = 333 %}
              {{ [[ (mm - empty_mm) / (full_mm - empty_mm) * 100, 0 ] | max, 100 ] | min | round(1) }}
    
          # Das Rohbyte ist um 40 versetzt, damit Minusgrade in ein
          # vorzeichenloses Byte passen.
          - name: "Gasflasche Temperatur"
            unique_id: campmatic_<NNN>_gas_temperatur
            unit_of_measurement: "°C"
            device_class: temperature
            state_class: measurement
            availability: "{{ has_value('sensor.campmatic_<NNN>_gasflasche_roh_temperaturbyte') }}"
            state: >-
              {{ (states('sensor.campmatic_<NNN>_gasflasche_roh_temperaturbyte') | float(0)) - 40 }}
    
          # Zellspannung = Byte / 32;  Prozent = (V - 2.2) / 0.65 * 100, geklemmt.
          # Gleiche Formel wie die offizielle Mopeka-App.
          - name: "Gasflasche Sensorbatterie"
            unique_id: campmatic_<NNN>_gas_sensorbatterie
            unit_of_measurement: "%"
            device_class: battery
            state_class: measurement
            availability: "{{ has_value('sensor.campmatic_<NNN>_gasflasche_roh_batteriebyte') }}"
            state: >-
              {% set v = (states('sensor.campmatic_<NNN>_gasflasche_roh_batteriebyte') | float(0)) / 32.0 %}
              {{ [[ (v - 2.2) / 0.65 * 100, 0 ] | max, 100 ] | min | round(0) }}
            attributes:
              spannung_v: >-
                {{ ((states('sensor.campmatic_<NNN>_gasflasche_roh_batteriebyte') | float(0)) / 32.0) | round(2) }}
  5. Flaschentyp anpassen und feinkalibrieren

    Im Füllstand-Template steht full_mm: 333 — das ist die 6-kg-Stahlflasche. Für andere Flaschen nur diese Zahl austauschen. empty_mm: 38 bleibt immer gleich; das ist der Restabstand zwischen Sensorpuck und Bodenplatte, den auch eine leere Flasche noch misst.

    # full_mm je Tanktyp — nur diese eine Zahl im Füllstand-Template ändern.
    # empty_mm ist überall 38.
    #
    #   EUROPE_6KG        6 kg Stahl                full_mm: 333
    #   EUROPE_11KG      11 kg Stahl                full_mm: 358
    #   EUROPE_14KG      14 kg Stahl                full_mm: 408
    #   EUROPE_6KG_ALU    6 kg Alu                  full_mm: 300
    #   EUROPE_11KG_ALU  11 kg Alu (TRAVELmate)     full_mm: 460
    #   CAMPINGGAZ_907   CampingGaz 907             full_mm: 130
    #   20LB_V           US 20 lb                   full_mm: 248
    #   30LB_V           US 30 lb                   full_mm: 381
    #   40LB_V           US 40 lb                   full_mm: 508
    #
    # Feinkalibrierung: Flasche wiegen, Tara vom Flaschenhals abziehen ->
    # tatsächliche kg Gas. Weicht der angezeigte Prozentwert ab, full_mm so
    # lange in 5-mm-Schritten korrigieren, bis es passt.
  6. Lovelace-Karte

    Tacho für den Füllstand, Kacheln für Füllhöhe, Temperatur, Sensorbatterie und Messqualität, darunter ein 7-Tage-Verlauf. Der lange Zeitraum ist Absicht: eine Gasflasche leert sich in Tagen, ein 24-h-Graph wäre eine flache Linie. Der Verlauf braucht die HACS-Karte mini-graph-card, alles andere sind Bordmittel.

    type: grid
    cards:
      - type: heading
        heading: Gasflasche
        icon: mdi:propane-tank
    
      - type: gauge
        entity: sensor.gasflasche_fullstand
        name: Füllstand
        min: 0
        max: 100
        needle: true
        severity:
          red: 0
          yellow: 20
          green: 40
        grid_options:
          columns: 6
    
      - type: tile
        entity: sensor.gasflasche_distanz
        name: Füllhöhe
        icon: mdi:arrow-expand-vertical
        grid_options:
          columns: 6
    
      - type: tile
        entity: sensor.gasflasche_temperatur
        name: Temperatur
        grid_options:
          columns: 6
    
      - type: tile
        entity: sensor.gasflasche_sensorbatterie
        name: Sensorbatterie
        grid_options:
          columns: 6
    
      - type: tile
        entity: sensor.campmatic_<NNN>_gasflasche_messqualitat
        name: Messqualität
        icon: mdi:signal-cellular-2
        grid_options:
          columns: 6
    
      - type: custom:mini-graph-card
        name: Füllstand (7 Tage)
        icon: mdi:propane-tank
        hours_to_show: 168
        points_per_hour: 1
        line_width: 3
        smoothing: true
        show:
          icon: true
          name: true
          labels: true
          extrema: true
          average: true
          fill: fade
          legend: false
          points: false
        entities:
          - entity: sensor.gasflasche_fullstand
            name: Füllstand
            color: "#FF7A00"
  7. Automatisierung: Warnung bevor das Gas ausgeht

    Zwei Details, die den Unterschied zwischen einer nützlichen und einer nervigen Automation ausmachen: die Halte-Zeit (for), damit die Temperaturschwankung des Füllstands keinen Fehlalarm auslöst, und die Qualitätsprüfung — bei quality < 2 ist das Echo zu schwach, dann lieber schweigen.

    # automations.yaml
    - alias: "Gasflasche wird knapp"
      mode: single
      triggers:
        # "for" ist wichtig: der Füllstand atmet mit der Flaschentemperatur.
        # Ohne Halte-Zeit meldet die Automation an einem sonnigen Nachmittag.
        - trigger: numeric_state
          entity_id: sensor.gasflasche_fullstand
          below: 20
          for: "00:30:00"
      conditions:
        # Messqualität 0..3. Unter 2 ist das Echo zu schwach — dann lieber
        # gar nicht melden als falsch melden.
        - condition: numeric_state
          entity_id: sensor.campmatic_<NNN>_gasflasche_messqualitat
          above: 1
      actions:
        - action: notify.persistent_notification
          data:
            title: "Gas wird knapp"
            message: >-
              Nur noch {{ states('sensor.gasflasche_fullstand') }} %
              ({{ states('sensor.gasflasche_distanz') }} mm Füllhöhe,
              {{ states('sensor.gasflasche_temperatur') }} °C an der Flasche).
  8. Bonus: steht die Flasche schief?

    Der Mopeka Pro hat einen Lagesensor. Steht das Fahrzeug schief, misst der Ultraschall an der Flüssigkeitsoberfläche vorbei und der Füllstand wird unzuverlässig — mit diesem Sensor siehst du den Grund statt zu rätseln. Die Firmware veröffentlicht die zwei Achsen ab Version 1.11.

    # 1) Roh-Topics ergänzen (Firmware ab 1.11)
    mqtt:
      sensor:
        - name: "Gasflasche Neigung X"
          unique_id: campmatic_<NNN>_gas_accel_x
          state_topic: "campmatic/<NNN>/mopeka/bottle_<S>/accel_x"
          unit_of_measurement: "G"
          entity_category: diagnostic
          expire_after: 2700
          device: *campmatic_dev
        - name: "Gasflasche Neigung Y"
          unique_id: campmatic_<NNN>_gas_accel_y
          state_topic: "campmatic/<NNN>/mopeka/bottle_<S>/accel_y"
          unit_of_measurement: "G"
          entity_category: diagnostic
          expire_after: 2700
          device: *campmatic_dev
    
    # 2) Gesamtneigung: theta = asin(sqrt(x^2 + y^2)), umgerechnet in Grad.
    #    Der Beschleunigungssensor sättigt bauartbedingt bei ±0,125 G
    #    (~7,2°) — mehr als "7,2" zeigt er nie an, das heißt dann schlicht
    #    "deutlich schief".
    template:
      - sensor:
          - name: "Gasflasche Neigung"
            unique_id: campmatic_<NNN>_gas_neigung
            unit_of_measurement: "°"
            icon: mdi:angle-acute
            availability: >-
              {{ has_value('sensor.campmatic_<NNN>_gasflasche_neigung_x')
                 and has_value('sensor.campmatic_<NNN>_gasflasche_neigung_y') }}
            state: >-
              {% set gx = states('sensor.campmatic_<NNN>_gasflasche_neigung_x') | float(0) %}
              {% set gy = states('sensor.campmatic_<NNN>_gasflasche_neigung_y') | float(0) %}
              {% set m  = [ sqrt(gx*gx + gy*gy), 1 ] | min %}
              {{ (asin(m) * 57.2958) | round(1) }}
  1. Warum diese drei Sensoren Handarbeit brauchen

    Truma- und CampMatic-Entitäten meldet die Box per Auto-Discovery an Home Assistant — nach dem Einrichten der MQTT-Verbindung sind sie einfach da. Dazu gehören auch zwei Werte des Batteriewächters: „Bordspannung" und „Bordbatterie Ladezustand" — allerdings nur vom BM2 mit der niedrigsten Slot-Nummer. Für alles Übrige aus der BLE-Sensorik — Mopeka, Ruuvi und die Slot-Topics des BM2 — gilt das nicht: die Box veröffentlicht deren Werte auf eigenen Roh-Topics campmatic/<NNN>/<integration>/<gerät>_<slot>/<feld>, ohne Discovery-Konfiguration. Der Grund: die Sensoren senden teilweise nur Rohbytes, aus denen erst gerechnet werden muss — in der CampMatic App passiert das serverseitig, damit Kalibrierung und neue Flaschentypen ohne Firmware-Update funktionieren.

    In Home Assistant baust du beides einmalig selbst: die MQTT-Sensoren für die Rohwerte und die Template-Sensoren mit der Rechnung. Danach läuft es dauerhaft. Alle Formeln in diesem Bereich sind 1:1 die, die auch die CampMatic App verwendet — App und Home Assistant zeigen also denselben Wert.

    Drei Dinge, die sonst Zeit kosten:
    • Die Roh-Topics sind nicht retained. Nach einem HA-Neustart bleiben die Entitäten unknown, bis das nächste BLE-Paket kommt (Mopeka/Ruuvi ≤ 60 s, BM2 ≤ 30 s). Das ist normal.
    • Deshalb überall expire_after: 2700 (45 min): so zeigt HA einen abgezogenen oder leeren Sensor als nicht verfügbar statt ewig den letzten Wert.
    • Die entity_id setzt sich aus Gerätename + Sensorname zusammen und wird kleingeschrieben und entumlautet: aus „Gasflasche Füllstand" wird sensor.gasflasche_fullstand, aus „Messqualität" wird ..._messqualitat. Nach dem ersten Neustart unter Entwicklerwerkzeuge → Zustände nachsehen und die Templates ggf. anpassen.

    Lieber nicht abtippen? Alle YAML-Blöcke dieses Bereichs gibt es fertig als Paket zum Herunterladen — Package-Datei, Automatisierungen, komplette Dashboard-Ansicht, Mosquitto-Bridge-Vorlage und ein Skript, das die Platzhalter interaktiv ersetzt: campmatic-homeassistant.zip (ca. 20 kB). Die Schritte hier erklären, was in den Dateien passiert — das Paket spart das Tippen.

  2. Slot-Nummer herausfinden

    Wie bei Mopeka steht die Kopplung in einem retained Topic. Der Slot landet im Topic-Namen als monitor_<S>. Mehrere Wächter (z. B. Aufbau- und Starterbatterie) bekommen jeweils einen eigenen Slot.

    mosquitto_sub -h localhost -u homeassistant -P <lokales_pw> \
      -v -t 'campmatic/<NNN>/bm2/config' -W 5
    
    # campmatic/<NNN>/bm2/config [{"slot":2,"mac":"AA:BB:CC:00:33:44"}]
    #                                    ^^^^^^^^  -> monitor_2
  3. MQTT-Sensoren anlegen

    Der BM2 liefert bereits fertige Werte — voltage in Volt, charge als Ladezustand in Prozent, dazu rssi. Hier ist also keine Umrechnung nötig, nur die Sensordefinition.

    Nicht verwechseln: Die Box spiegelt zusätzlich einen Wächter auf die per Auto-Discovery gefundenen Entitäten „Bordspannung" und „Bordbatterie Ladezustand" — aber nur den mit der niedrigsten Slot-Nummer. Bei zwei Batteriewächtern sind die Slot-Topics hier der einzige eindeutige Weg.

    # configuration.yaml
    # <NNN> = Gerätenummer, <S> = BM2-Slot aus dem Schritt davor.
    # Steht der Anker &campmatic_dev schon weiter oben in der Datei, hier
    # nur noch "device: *campmatic_dev" schreiben.
    mqtt:
      sensor:
        - name: "Aufbaubatterie Spannung"
          unique_id: campmatic_<NNN>_bm2_voltage
          state_topic: "campmatic/<NNN>/bm2/monitor_<S>/voltage"
          unit_of_measurement: "V"
          device_class: voltage
          state_class: measurement
          suggested_display_precision: 2
          icon: mdi:car-battery
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          payload_available: "online"
          payload_not_available: "offline"
          device: &campmatic_dev
            identifiers: ["campmatic_<NNN>"]
            name: "CampMatic <NNN>"
            manufacturer: "CampMatic"
    
        - name: "Aufbaubatterie Ladezustand"
          unique_id: campmatic_<NNN>_bm2_charge
          state_topic: "campmatic/<NNN>/bm2/monitor_<S>/charge"
          unit_of_measurement: "%"
          device_class: battery
          state_class: measurement
          suggested_display_precision: 0
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          device: *campmatic_dev
    
        - name: "Aufbaubatterie Signalstärke"
          unique_id: campmatic_<NNN>_bm2_rssi
          state_topic: "campmatic/<NNN>/bm2/monitor_<S>/rssi"
          unit_of_measurement: "dBm"
          device_class: signal_strength
          state_class: measurement
          entity_category: diagnostic
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          device: *campmatic_dev
  4. Ladezustand ehrlich rechnen

    Der charge-Wert des BM2 ist eine Schätzung aus der Spannung — und sie ist auf Blei-Batterien geeicht. An einer LiFePO4 zeigt der BM2 deshalb fast immer 100 %: eine Lithium-Batterie liegt über fast ihren gesamten Bereich bei 13,0–13,3 V, was der BM2 als „voll" liest. Das ist kein Defekt, sondern die falsche Kennlinie.

    Der Template-Sensor unten interpoliert stattdessen über eine echte Kennlinie und macht sich bewusst nicht verfügbar, solange geladen wird. Denn Spannung sagt nur im Ruhezustand etwas über den Ladezustand: unter Last bricht sie ein, am Lader liegt sie zu hoch. Verlässlich wird der Wert erst nach etwa zwei Stunden ohne nennenswerte Last.

    # configuration.yaml
    template:
      - binary_sensor:
          # Ab ~13,2 V arbeitet ein Lader (Landstrom, Lichtmaschine, Solar).
          # Die Spannung sagt dann nichts mehr über den Ladezustand aus.
          - name: "Aufbaubatterie lädt"
            unique_id: campmatic_<NNN>_bm2_laedt
            device_class: battery_charging
            state: >-
              {{ states('sensor.campmatic_<NNN>_aufbaubatterie_spannung') | float(0) >= 13.2 }}
    
      - sensor:
          - name: "Aufbaubatterie Ladezustand (Ruhespannung)"
            unique_id: campmatic_<NNN>_bm2_soc_ruhe
            unit_of_measurement: "%"
            device_class: battery
            state_class: measurement
            icon: mdi:battery-heart-variant
            # Nur im Ruhezustand aussagekräftig: unter Last bricht die Spannung
            # ein, beim Laden liegt sie zu hoch.
            availability: >-
              {{ has_value('sensor.campmatic_<NNN>_aufbaubatterie_spannung')
                 and is_state('binary_sensor.aufbaubatterie_ladt', 'off') }}
            state: >-
              {% set v = states('sensor.campmatic_<NNN>_aufbaubatterie_spannung') | float(0) %}
              {# Blei / AGM / Gel, 12 V, ca. 20 °C, mind. 2 h ohne Last #}
              {% set tbl = [[11.80,0],[12.00,10],[12.10,20],[12.20,30],[12.30,40],
                            [12.40,50],[12.50,65],[12.60,80],[12.70,90],[12.80,100]] %}
              {# LiFePO4 stattdessen:                                              #}
              {# [[12.00,0],[12.80,10],[12.90,20],[13.00,30],[13.10,50],           #}
              {#  [13.15,60],[13.20,80],[13.30,90],[13.40,100]]                    #}
              {% set ns = namespace(p = 100 if v >= tbl[-1][0] else 0) %}
              {% for i in range(tbl | length - 1) %}
                {% if v >= tbl[i][0] and v < tbl[i+1][0] %}
                  {% set ns.p = tbl[i][1] + (v - tbl[i][0]) / (tbl[i+1][0] - tbl[i][0])
                                * (tbl[i+1][1] - tbl[i][1]) %}
                {% endif %}
              {% endfor %}
              {{ ns.p | round(0) }}
  5. Lovelace-Karte

    Zwei Tachos und ein 24-Stunden-Verlauf mit zwei Achsen — Spannung links, Ladezustand rechts. Im Verlauf erkennst du die Ladephasen als Plateaus und den nächtlichen Verbrauch als sanftes Gefälle. Die Farbschwellen der Spannungsanzeige (rot ab 10 V, gelb ab 12 V, grün ab 12,8 V) passen zu Blei/AGM; für LiFePO4 auf 12,8 / 13,0 / 13,2 V setzen.

    type: grid
    cards:
      - type: heading
        heading: Bordbatterie
        icon: mdi:car-battery
    
      - type: gauge
        entity: sensor.campmatic_<NNN>_aufbaubatterie_ladezustand
        name: Ladezustand
        min: 0
        max: 100
        needle: true
        severity:
          red: 0
          yellow: 40
          green: 60
        grid_options:
          columns: 6
    
      - type: gauge
        entity: sensor.campmatic_<NNN>_aufbaubatterie_spannung
        name: Spannung
        min: 10
        max: 15
        needle: true
        severity:
          red: 10
          yellow: 12
          green: 12.8
        grid_options:
          columns: 6
    
      - type: custom:mini-graph-card
        name: Bordspannung (24 h)
        icon: mdi:car-battery
        hours_to_show: 24
        points_per_hour: 4
        line_width: 3
        smoothing: true
        show:
          icon: true
          name: true
          labels: true
          extrema: true
          average: true
          fill: fade
          legend: true
          points: false
        entities:
          - entity: sensor.campmatic_<NNN>_aufbaubatterie_spannung
            name: Spannung
            color: "#4CAF50"
          - entity: sensor.campmatic_<NNN>_aufbaubatterie_ladezustand
            name: Ladung
            color: "#2196F3"
            y_axis: secondary
            show_state: true
  6. Automatisierungen: Tiefentladung und Ladeende

    Die erste Automation schützt die Batterie: unter 12,0 V (Blei) beginnt die Sulfatierung, und jede Stunde darunter kostet Kapazität dauerhaft. Die zweite meldet, wenn der Ladestrom wegfällt — praktisch, um mitzubekommen, dass am Stellplatz der Landstrom ausgefallen ist, bevor der Kühlschrank die Batterie leer zieht.

    # automations.yaml
    - alias: "Aufbaubatterie kritisch"
      mode: single
      triggers:
        # Blei/AGM: 12,0 V unter Ruhe = praktisch leer, ab hier beginnt die
        # Sulfatierung. LiFePO4: stattdessen 12,8 V eintragen.
        - trigger: numeric_state
          entity_id: sensor.campmatic_<NNN>_aufbaubatterie_spannung
          below: 12.0
          for: "00:15:00"
      conditions:
        - condition: state
          entity_id: binary_sensor.aufbaubatterie_ladt
          state: "off"
      actions:
        - action: notify.persistent_notification
          data:
            title: "Bordbatterie kritisch"
            message: >-
              {{ states('sensor.campmatic_<NNN>_aufbaubatterie_spannung') }} V —
              bitte laden. Verbraucher abschalten.
    
    - alias: "Landstrom weg — Batterie entlädt"
      mode: single
      triggers:
        - trigger: state
          entity_id: binary_sensor.aufbaubatterie_ladt
          from: "on"
          to: "off"
          for: "00:10:00"
      actions:
        - action: notify.persistent_notification
          data:
            title: "Kein Ladestrom mehr"
            message: >-
              Ladung beendet bei
              {{ states('sensor.campmatic_<NNN>_aufbaubatterie_spannung') }} V.
  1. Warum diese drei Sensoren Handarbeit brauchen

    Truma- und CampMatic-Entitäten meldet die Box per Auto-Discovery an Home Assistant — nach dem Einrichten der MQTT-Verbindung sind sie einfach da. Dazu gehören auch zwei Werte des Batteriewächters: „Bordspannung" und „Bordbatterie Ladezustand" — allerdings nur vom BM2 mit der niedrigsten Slot-Nummer. Für alles Übrige aus der BLE-Sensorik — Mopeka, Ruuvi und die Slot-Topics des BM2 — gilt das nicht: die Box veröffentlicht deren Werte auf eigenen Roh-Topics campmatic/<NNN>/<integration>/<gerät>_<slot>/<feld>, ohne Discovery-Konfiguration. Der Grund: die Sensoren senden teilweise nur Rohbytes, aus denen erst gerechnet werden muss — in der CampMatic App passiert das serverseitig, damit Kalibrierung und neue Flaschentypen ohne Firmware-Update funktionieren.

    In Home Assistant baust du beides einmalig selbst: die MQTT-Sensoren für die Rohwerte und die Template-Sensoren mit der Rechnung. Danach läuft es dauerhaft. Alle Formeln in diesem Bereich sind 1:1 die, die auch die CampMatic App verwendet — App und Home Assistant zeigen also denselben Wert.

    Drei Dinge, die sonst Zeit kosten:
    • Die Roh-Topics sind nicht retained. Nach einem HA-Neustart bleiben die Entitäten unknown, bis das nächste BLE-Paket kommt (Mopeka/Ruuvi ≤ 60 s, BM2 ≤ 30 s). Das ist normal.
    • Deshalb überall expire_after: 2700 (45 min): so zeigt HA einen abgezogenen oder leeren Sensor als nicht verfügbar statt ewig den letzten Wert.
    • Die entity_id setzt sich aus Gerätename + Sensorname zusammen und wird kleingeschrieben und entumlautet: aus „Gasflasche Füllstand" wird sensor.gasflasche_fullstand, aus „Messqualität" wird ..._messqualitat. Nach dem ersten Neustart unter Entwicklerwerkzeuge → Zustände nachsehen und die Templates ggf. anpassen.

    Lieber nicht abtippen? Alle YAML-Blöcke dieses Bereichs gibt es fertig als Paket zum Herunterladen — Package-Datei, Automatisierungen, komplette Dashboard-Ansicht, Mosquitto-Bridge-Vorlage und ein Skript, das die Platzhalter interaktiv ersetzt: campmatic-homeassistant.zip (ca. 20 kB). Die Schritte hier erklären, was in den Dateien passiert — das Paket spart das Tippen.

  2. Slot-Nummer herausfinden

    Auch hier steht die Kopplung in einem retained Topic; der Slot landet als tag_<S> im Topic-Namen. Mehrere Tags — z. B. einer im Wohnraum, einer im Kühlschrank, einer außen — bekommen je einen eigenen Slot.

    mosquitto_sub -h localhost -u homeassistant -P <lokales_pw> \
      -v -t 'campmatic/<NNN>/ruuvi/config' -W 5
    
    # campmatic/<NNN>/ruuvi/config [{"slot":3,"mac":"AA:BB:CC:00:55:66"}]
    #                                      ^^^^^^^^  -> tag_3
  3. MQTT-Sensoren anlegen

    Der RuuviTag sendet im Format RAWv2 (Data Format 5) und liefert fertig umgerechnete Werte: Temperatur, Luftfeuchte, Luftdruck, Batteriespannung und Signalstärke. Zusätzlich einen Bewegungszähler, der hochzählt sobald der Tag bewegt wird — daraus lässt sich ein Türkontakt oder eine „Fahrzeug bewegt"-Meldung bauen, ohne weitere Hardware.

    # configuration.yaml
    # <NNN> = Gerätenummer, <S> = Ruuvi-Slot aus dem Schritt davor.
    mqtt:
      sensor:
        - name: "Ruuvi Temperatur"
          unique_id: campmatic_<NNN>_ruuvi_temp
          state_topic: "campmatic/<NNN>/ruuvi/tag_<S>/temp_c"
          unit_of_measurement: "°C"
          device_class: temperature
          state_class: measurement
          suggested_display_precision: 1
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          payload_available: "online"
          payload_not_available: "offline"
          device: &campmatic_dev
            identifiers: ["campmatic_<NNN>"]
            name: "CampMatic <NNN>"
            manufacturer: "CampMatic"
    
        - name: "Ruuvi Luftfeuchtigkeit"
          unique_id: campmatic_<NNN>_ruuvi_hum
          state_topic: "campmatic/<NNN>/ruuvi/tag_<S>/humidity"
          unit_of_measurement: "%"
          device_class: humidity
          state_class: measurement
          suggested_display_precision: 1
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          device: *campmatic_dev
    
        - name: "Ruuvi Luftdruck"
          unique_id: campmatic_<NNN>_ruuvi_press
          state_topic: "campmatic/<NNN>/ruuvi/tag_<S>/pressure_hpa"
          unit_of_measurement: "hPa"
          device_class: pressure
          state_class: measurement
          suggested_display_precision: 1
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          device: *campmatic_dev
    
        - name: "Ruuvi Batteriespannung"
          unique_id: campmatic_<NNN>_ruuvi_batt
          state_topic: "campmatic/<NNN>/ruuvi/tag_<S>/battery_v"
          unit_of_measurement: "V"
          device_class: voltage
          state_class: measurement
          suggested_display_precision: 3
          entity_category: diagnostic
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          device: *campmatic_dev
    
        - name: "Ruuvi Signalstärke"
          unique_id: campmatic_<NNN>_ruuvi_rssi
          state_topic: "campmatic/<NNN>/ruuvi/tag_<S>/rssi"
          unit_of_measurement: "dBm"
          device_class: signal_strength
          state_class: measurement
          entity_category: diagnostic
          expire_after: 2700
          availability_topic: "campmatic/<NNN>/status"
          device: *campmatic_dev
    
        # Bewegungszähler des Tags — zählt hoch, sobald der Tag bewegt wird.
        # Als Trigger brauchbar ("Schranktür auf", "Fahrzeug bewegt").
        - name: "Ruuvi Bewegungszähler"
          unique_id: campmatic_<NNN>_ruuvi_moves
          state_topic: "campmatic/<NNN>/ruuvi/tag_<S>/moves"
          state_class: total_increasing
          icon: mdi:motion-sensor
          entity_category: diagnostic
          expire_after: 2700
          device: *campmatic_dev
  4. Taupunkt, absolute Feuchte und echter Luftdruck

    Drei Rechnungen, die aus drei Messwerten die eigentlich nützlichen Zahlen machen:

    Taupunkt — die Temperatur, bei der die Luft ihr Wasser abgibt. Liegt eine Fläche im Fahrzeug darunter (Fensterscheibe, Blech, Aufstelldach), bildet sich dort Kondenswasser. Der Abstand zwischen Raumtemperatur und Taupunkt ist damit das ehrlichste Maß für Schimmelgefahr.

    Absolute Feuchte in g/m³ — die relative Feuchte allein sagt beim Lüften nichts, weil sie mit der Temperatur springt: 80 % bei 5 °C draußen sind trockener als 55 % bei 22 °C drinnen. Nur der Vergleich der absoluten Werte beantwortet die Frage, ob Lüften die Feuchtigkeit tatsächlich rausträgt.

    Luftdruck auf Meereshöhe — der Tag misst den absoluten Druck am Ort. Auf 1000 m Höhe sind das rund 120 hPa weniger als im Wetterbericht. Ohne Umrechnung sieht jeder Alpenpass nach einem Orkantief aus.

    # configuration.yaml
    template:
      - sensor:
          # --- Taupunkt (Magnus-Formel) ---
          # gamma = ln(RH/100) + (17.62*T) / (243.12+T)
          # Td    = 243.12*gamma / (17.62-gamma)
          # Unterschreitet eine Fläche im Fahrzeug (Fenster, Blech, Aufstelldach)
          # den Taupunkt, schlägt sich dort Wasser nieder.
          - name: "Innenklima Taupunkt"
            unique_id: campmatic_<NNN>_ruuvi_taupunkt
            unit_of_measurement: "°C"
            device_class: temperature
            state_class: measurement
            availability: >-
              {{ has_value('sensor.campmatic_<NNN>_ruuvi_temperatur')
                 and has_value('sensor.campmatic_<NNN>_ruuvi_luftfeuchtigkeit') }}
            state: >-
              {% set t  = states('sensor.campmatic_<NNN>_ruuvi_temperatur') | float(0) %}
              {% set rh = [ states('sensor.campmatic_<NNN>_ruuvi_luftfeuchtigkeit') | float(1), 1 ] | max %}
              {% set g  = log(rh / 100) + (17.62 * t) / (243.12 + t) %}
              {{ (243.12 * g / (17.62 - g)) | round(1) }}
    
          # --- Absolute Luftfeuchte in g/m³ ---
          # AH = 216.7 * (RH/100 * 6.112 * e^(17.62*T/(243.12+T)) / (273.15+T))
          # Das ist die Zahl, auf die es beim Lüften ankommt: relative Feuchte
          # allein sagt nichts, weil sie mit der Temperatur springt.
          - name: "Innenklima absolute Feuchte"
            unique_id: campmatic_<NNN>_ruuvi_abs_feuchte
            unit_of_measurement: "g/m³"
            state_class: measurement
            icon: mdi:water-percent
            availability: >-
              {{ has_value('sensor.campmatic_<NNN>_ruuvi_temperatur')
                 and has_value('sensor.campmatic_<NNN>_ruuvi_luftfeuchtigkeit') }}
            state: >-
              {% set t  = states('sensor.campmatic_<NNN>_ruuvi_temperatur') | float(0) %}
              {% set rh = states('sensor.campmatic_<NNN>_ruuvi_luftfeuchtigkeit') | float(0) %}
              {{ (2.1674 * rh * 6.112 * e ** (17.62 * t / (243.12 + t)) / (273.15 + t)) | round(2) }}
    
          # --- Luftdruck auf Meereshöhe ---
          # Der Tag misst den ABSOLUTEN Druck. Wetterberichte nennen den auf
          # Meereshöhe reduzierten — auf 1000 m Höhe sind das ~120 hPa
          # Unterschied. Ohne diese Umrechnung wirkt jeder Bergstellplatz wie
          # ein Orkantief.  <HOEHE_M> = Höhe des Stellplatzes in Metern.
          - name: "Luftdruck (Meereshöhe)"
            unique_id: campmatic_<NNN>_ruuvi_press_msl
            unit_of_measurement: "hPa"
            device_class: pressure
            state_class: measurement
            availability: "{{ has_value('sensor.campmatic_<NNN>_ruuvi_luftdruck') }}"
            state: >-
              {% set p = states('sensor.campmatic_<NNN>_ruuvi_luftdruck') | float(0) %}
              {% set t = states('sensor.campmatic_<NNN>_ruuvi_temperatur') | float(15) %}
              {% set h = <HOEHE_M> %}
              {{ (p * (1 - (0.0065 * h) / (t + 0.0065 * h + 273.15)) ** -5.257) | round(1) }}
    
      - binary_sensor:
          # --- Lüften bringt jetzt etwas ---
          # Nur wenn die Außenluft absolut trockener ist als die Innenluft,
          # trocknet Lüften das Fahrzeug. Zweiter Ruuvi draußen = <A> ;
          # alternativ die Werte einer weather.*-Entität einsetzen.
          - name: "Lüften empfohlen"
            unique_id: campmatic_<NNN>_lueften
            icon: mdi:window-open-variant
            state: >-
              {% set ti  = states('sensor.campmatic_<NNN>_ruuvi_temperatur') | float(0) %}
              {% set hi  = states('sensor.campmatic_<NNN>_ruuvi_luftfeuchtigkeit') | float(0) %}
              {% set ta  = states('sensor.campmatic_<NNN>_ruuvi_temperatur_<A>') | float(0) %}
              {% set ha  = states('sensor.campmatic_<NNN>_ruuvi_luftfeuchtigkeit_<A>') | float(0) %}
              {% set ai  = 2.1674 * hi * 6.112 * e ** (17.62 * ti / (243.12 + ti)) / (273.15 + ti) %}
              {% set aa  = 2.1674 * ha * 6.112 * e ** (17.62 * ta / (243.12 + ta)) / (273.15 + ta) %}
              {{ hi > 60 and (ai - aa) > 1.0 }}
  5. Lovelace-Karte

    Temperatur und Luftfeuchte als Tachos mit Warnbereichen (gelb ab 65 % Feuchte, rot ab 80 % — darüber wird es im Fahrzeug schnell klamm), Luftdruck, Tag-Batterie und Taupunkt als Kacheln, darunter der 24-Stunden-Verlauf mit zwei Achsen.

    type: grid
    cards:
      - type: heading
        heading: Ruuvi Innenklima
        icon: mdi:home-thermometer
    
      - type: gauge
        entity: sensor.campmatic_<NNN>_ruuvi_temperatur
        name: Temperatur
        min: 0
        max: 35
        needle: true
        severity:
          green: 0
          yellow: 24
          red: 28
        grid_options:
          columns: 6
    
      - type: gauge
        entity: sensor.campmatic_<NNN>_ruuvi_luftfeuchtigkeit
        name: Luftfeuchtigkeit
        min: 0
        max: 100
        needle: true
        severity:
          green: 0
          yellow: 65
          red: 80
        grid_options:
          columns: 6
    
      - type: tile
        entity: sensor.campmatic_<NNN>_ruuvi_luftdruck
        name: Luftdruck
        icon: mdi:gauge
        grid_options:
          columns: 6
    
      - type: tile
        entity: sensor.campmatic_<NNN>_ruuvi_batteriespannung
        name: Tag-Batterie
        icon: mdi:battery-outline
        grid_options:
          columns: 6
    
      - type: tile
        entity: sensor.innenklima_taupunkt
        name: Taupunkt
        icon: mdi:water-thermometer
        grid_options:
          columns: 6
    
      - type: custom:mini-graph-card
        name: Innenklima (24 h)
        icon: mdi:home-thermometer
        hours_to_show: 24
        points_per_hour: 4
        line_width: 3
        smoothing: true
        show:
          icon: true
          name: true
          labels: true
          extrema: true
          average: true
          fill: fade
          legend: true
          points: false
        entities:
          - entity: sensor.campmatic_<NNN>_ruuvi_temperatur
            name: Temperatur
            color: "#FF7A00"
          - entity: sensor.campmatic_<NNN>_ruuvi_luftfeuchtigkeit
            name: Feuchte
            color: "#2196F3"
            y_axis: secondary
            show_state: true
  6. Automatisierungen: Frost, Kondensat, Batterie

    Die erste Automation ist die nützlichste im Winterlager: fällt es im Fahrzeug unter 3 °C, setzt sie die Truma selbst auf Frostschutz-Niveau — die Verbindung zwischen Ruuvi und Heizung, die aus zwei Sensoren ein System macht. Die zweite warnt, bevor sich Kondenswasser bildet. Die dritte meldet die leere Knopfzelle rechtzeitig: der Tag läuft mit einer CR2477, unter 2,5 V wird es Zeit. Bei Frost sackt die Spannung übrigens vorübergehend ab, ohne dass die Zelle leer wäre — deshalb die lange Halte-Zeit von 6 Stunden.

    # automations.yaml
    - alias: "Frostgefahr im Fahrzeug"
      mode: single
      triggers:
        - trigger: numeric_state
          entity_id: sensor.campmatic_<NNN>_ruuvi_temperatur
          below: 3
          for: "00:10:00"
      actions:
        # Beispiel: Truma automatisch auf Frostschutz-Niveau setzen.
        - action: climate.set_temperature
          target:
            entity_id: climate.<entity>_truma_heizung
          data:
            temperature: 8
            hvac_mode: heat
        - action: notify.persistent_notification
          data:
            title: "Frostgefahr"
            message: >-
              {{ states('sensor.campmatic_<NNN>_ruuvi_temperatur') }} °C im
              Fahrzeug — Heizung auf 8 °C gesetzt.
    
    - alias: "Kondensat-Warnung"
      mode: single
      triggers:
        # Taupunkt nah an der Raumtemperatur = die kalten Flächen sind schon
        # drunter. 2 K Abstand ist eine brauchbare Vorwarnstufe.
        - trigger: template
          value_template: >-
            {{ (states('sensor.campmatic_<NNN>_ruuvi_temperatur') | float(99)
                - states('sensor.innenklima_taupunkt') | float(0)) < 2 }}
          for: "00:20:00"
      actions:
        - action: notify.persistent_notification
          data:
            title: "Feuchtigkeit im Fahrzeug"
            message: >-
              Taupunkt {{ states('sensor.innenklima_taupunkt') }} °C bei
              {{ states('sensor.campmatic_<NNN>_ruuvi_temperatur') }} °C
              Raumtemperatur — lüften oder heizen.
    
    - alias: "Ruuvi Tag-Batterie leer"
      mode: single
      triggers:
        - trigger: numeric_state
          entity_id: sensor.campmatic_<NNN>_ruuvi_batteriespannung
          below: 2.5
          for: "06:00:00"
      actions:
        - action: notify.persistent_notification
          data:
            title: "Ruuvi Tag: Batterie wechseln"
            message: >-
              Nur noch {{ states('sensor.campmatic_<NNN>_ruuvi_batteriespannung') }} V
              (CR2477).
  1. Sensor mit Hersteller-App einrichten

    CampMatic unterstützt zusätzliche Bluetooth-Sensoren: Mopeka Gas-Füllstandsanzeigen (z. B. Mopeka Pro Check), BM2 Batteriemonitore für die Bord-/Aufbaubatterie und Ruuvi Umgebungssensoren (Temperatur, Luftfeuchte, Luftdruck).

    Richte das jeweilige Gerät nach dem Kauf zuerst mit der App des Herstellers auf deinem Smartphone ein (z. B. die Mopeka-, BM2- bzw. Ruuvi-App). Dabei wird der Sensor per Bluetooth aktiviert und kalibriert. Führe diesen Schritt einmalig durch — danach wird das Gerät dauerhaft von CampMatic erkannt.

  2. Gerät in CampMatic hinzufügen

    Öffne in CampMatic die Einstellungen → Geräte und wähle Gerät hinzufügen. Wähle den passenden Gerätetyp aus (Mopeka Gas-Sensor, BM2 Batteriemonitor oder Ruuvi Umgebungssensor). Du kannst mehrere Sensoren hinzufügen — z. B. eine Haupt- und eine Reserve-Gasflasche, mehrere Batterien oder mehrere Umgebungssensoren.

  3. Automatische Erkennung & Anzeige im Dashboard

    CampMatic findet den Sensor anschließend automatisch in Reichweite und zeigt ihn als eigene Kachel auf dem Dashboard an — mit Live-Werten wie Gas-Füllstand und Flaschentemperatur, Batteriespannung und Ladezustand (SoC) bzw. Temperatur, Luftfeuchte und Luftdruck.

  4. Und in Home Assistant?

    In der CampMatic App ist damit alles erledigt — Füllstand, Ladezustand und Klimawerte werden serverseitig berechnet und erscheinen von selbst im Dashboard.

    Wenn du die Sensoren zusätzlich in Home Assistant haben möchtest, ist etwas Handarbeit nötig: die drei BLE-Integrationen senden auf eigenen Roh-Topics ohne Auto-Discovery. Im Abschnitt Home Assistant Integration findest du dafür je einen eigenen Reiter — Gasflasche (Mopeka), Bordbatterie (BM2) und Innenklima (Ruuvi) — mit kompletten YAML-Beispielen, den Umrechnungsformeln, fertigen Lovelace-Karten und Automatisierungen.

  1. Die Truma erkennt die CampMatic Box nicht (kein Eintrag T23.700)

    Nach dem Anschließen zuerst ca. 3 Minuten warten, bis die Box vollständig gestartet ist. Dann im Menü der Truma Steuerung Reset → PR SET ausführen und anschließend im Menü Index prüfen, ob ein neuer (dritter) Eintrag mit T23.700 erscheint. Falls nicht: den Sitz der RJ12-Verbindung prüfen und den Reset wiederholen. Bei Einbau über den Splitter am CP Plus müssen beide Splitter-Ausgänge fest sitzen und das Originalkabel wieder im CP Plus stecken; beim Direktanschluss an der Heizung gehört der Stecker in die rechte freie Buchse (siehe Einbau).

  2. Nach dem Login erscheint keine WLAN-Auswahl

    Wenn nach dem Login auf der Konfigurationsseite statt der WLAN-Auswahl die normale Steuerungsoberfläche erscheint, öffne direkt http://192.168.4.1/captiveportal — dort findest du die WLAN-Auswahl.

  3. Box ist offline / WLAN hat sich geändert

    Sobald das konfigurierte WLAN nicht erreichbar ist, öffnet die Box automatisch ihren eigenen Access Point (SSID und Passwort stehen auf dem Sticker der Box und in der App auf der Status-Seite unter „Fallback WiFi"). Verbinde dein Handy damit und öffne http://192.168.4.1 — dort kannst du die Heizung auch ohne Internet lokal steuern und über /captiveportal ein neues WLAN hinterlegen. Eine Offline-Benachrichtigung wird ausgelöst, wenn die Box länger als 5 Minuten keine Daten gesendet hat (einmal pro Offline-Phase).

  4. Die 4G-Box verbindet sich nicht mit dem Mobilfunknetz

    Häufigste Ursache: Die SIM-Karte hat noch eine PIN-Abfrage aktiv. Deaktiviere die SIM-PIN vorher in einem Handy (Anleitung für iOS und Android in der Einrichtung, Reiter 4G Box). Prüfe außerdem, ob die SIM korrekt eingelegt ist und Guthaben bzw. einen aktiven Datentarif hat.

  5. Registrierungs- oder Passwort-Mail kommt nicht an

    Prüfe zuerst den Spam-Ordner. Ein neues Passwort für die App bekommst du über „Passwort vergessen?" auf der Login-Seite — der Link in der E-Mail ist 30 Minuten gültig. Die Zugangsdaten der lokalen Konfigurationsseite der Box (Benutzer admin) stehen auf dem Sticker der Box und in der App auf der Status-Seite.

  6. Telegram-Bot einrichten und Befehle

    In der App: Einstellungen → Telegram → „Link Telegram", dann „Open Telegram" antippen und im Bot @camp_matic_bot auf „Start" tippen (der Link ist 10 Minuten gültig — die Verknüpfung wird automatisch erkannt). Befehle: /status (Temperaturen, Heizstatus — inklusive Gasflaschen, Bordbatterie und Klimasensoren, falls gekoppelt), /control (Tastenfeld für Heizung, Wasser, Energiemix, Lüfter), /set 22 (Raumtemperatur 0–30 °C, /set 0 = aus), /help und /unlink. Mehrere Telegram-Nutzer pro Gerät und mehrere Geräte pro Chat werden unterstützt.

  7. Benachrichtigungen konfigurieren

    Im Dashboard die Karte „Benachrichtigungen" aufklappen. Für jedes Ereignis lassen sich E-Mail und Telegram einzeln aktivieren: Box offline, Zieltemperatur erreicht, Heizung/Warmwasser ein- oder ausgeschaltet, Raumtemperatur unter/über einer frei wählbaren Schwelle (z. B. Frostschutz bei 5 °C). Für gekoppelte Sensoren kommen eigene Zeilen dazu: Gas-Füllstand (Mopeka), Bordspannung (BM2) und Sensor-Temperatur (Ruuvi). Hinweis: Temperatur-Alarme funktionieren nur bei eingeschalteter Heizung. Mit „Test Email" / „Test Telegram" kannst du den Empfang direkt prüfen.

  8. Heizpläne und Zeitsteuerung

    Im Dashboard oben „Scheduler" öffnen. Planbar sind Raumheizung und Warmwasser (ein/aus mit Zieltemperatur), Energiemix und Lüftermodus — täglich, an bestimmten Wochentagen oder einmalig, minutengenau. Die Pläne laufen serverseitig in deiner Zeitzone (einstellbar in den Einstellungen) — die Box muss dafür nichts speichern. Ist das Gerät zur geplanten Zeit offline, wird der Plan übersprungen und du wirst benachrichtigt. Einmalige Pläne löschen sich nach der Ausführung selbst; die Historie findest du auf der Status-Seite.

  9. Muss ich an die Truma Heizung heran?

    In den allermeisten Fällen nicht. Mit dem RJ12-Splitter entfällt der Anschluss an der Heizung komplett — du arbeitest ausschließlich hinten am Truma CP Plus: vorhandenes RJ12-Kabel abziehen, in den Splitter stecken, ein Ausgang zurück ins CP Plus, der andere zur CampMatic Box. Die Abdeckung über der Heizung bleibt dabei zu. Nur wenn du an die Rückseite des CP Plus nicht herankommst oder dort zu wenig Platz ist, brauchst du die Buchse an der Heizung selbst (siehe Einbau, Variante 2).

  10. Brauche ich den Truma CP Plus?

    Nein. Die CampMatic Box braucht nur eine 12V-Stromversorgung — aus einer beliebigen Quelle im Camper. Der JST-PH-Anschluss am CP Plus ist lediglich eine bequeme Möglichkeit, den Strom abzugreifen; eine Datenverbindung zum CP Plus ist nicht nötig.

  11. Home-Assistant-Bridge verbindet sich nicht

    In den Mosquitto-Logs nach bridge-, tls- und connect-Meldungen suchen. Der erste Blick gilt der Zeile Connecting bridge … im Startprotokoll: fehlt sie, wurde die Bridge-Datei nie eingelesen (beim Add-on fehlt dann meist customize: active: true, oder die Datei liegt in /homeassistant/share/mosquitto statt /share/mosquitto). Bei „Connection refused": Benutzername und Passwort neu von der Status-Seite kopieren. Bei „certificate verify failed": der CA-Speicher des Containers fehlt — Image aktualisieren oder den Host-CA-Store einbinden.

    Kein Fehler, auch wenn es so aussieht: Protocol error from ::1: First packet not CONNECT steht bei jedem Start des Mosquitto-Add-ons im Protokoll und ist ein interner Portcheck. Diese Meldung ist nie die Ursache eines Problems.

    Die vollständigen Schritte stehen in der Karte Home Assistant Integration unter „Bridge prüfen".

Du hast Fragen oder brauchst Hilfe? Wir helfen dir gerne weiter.