Der HODOR-Sensor

Ich bin auf ein sehr schlecht abgedrehtes Video auf Youtube gestoßen, dass zeigt, wie man sich an die Gegensprecheinrichtung eines Ritto-Telefons hängt, um so zum Beispiel digital die Türöffnung zu bedienen. Klar war nun die nächste Idee geboren. Ich möchte die Tür mit meinem Handy öffnen können. Sowohl von meiner Wohnung aus, als auch wenn ich davor stehe. Zusätzlich möchte ich aber meinen Router nicht via VPN kontakten und diesen auch sonst nicht ins Netz stellen.

Home Assistant und Automatisierung

Als Konfiguration für meine ersten Automatisierungen nutze ich einen Raspberry Pi 3 mit USB Zigbee Dongle in Kombination mit einer FritzBox. Folgende Schritte sind beschrieben:

  • Das PHP Skript – Das Skript zur Verwaltung des aktuellen Wertes
  • Android App als Publisher – Den Wert des Türöffners beim Webspace setzen
  • Home Assistant – Stati abfragen, darauf reagieren und Status zurücksetzen
  • Home Assistant als Broker für MQTT
  • Raspberry Pi zero als Subscriber – Provisorisch
HODOR – Game of Thrones Spoiler (AI Content)

Der Name Hodor aus der Serie Game of Thrones hat eine tragische Bedeutung, die in der Episode „The Door“ (Staffel 6, Episode 5) enthüllt wird. Es wird gezeigt, dass Hodor sein ganzes Leben lang nur dieses eine Wort sagen konnte, und der Grund dafür hängt mit seiner Vergangenheit und der magischen Verbindung zwischen Bran Stark und der Fähigkeit, die Zeit zu beeinflussen, zusammen.

  • „Hodor“ ist eine verzerrte Form von „Hold the door“ (Halte die Tür!).
  • In einem entscheidenden Moment in der Vergangenheit beeinflusst Bran versehentlich den jungen Wylis (Hodors richtiger Name) durch eine Verbindung mit der Gegenwart. Während Wylis das Kommando hört, die Tür gegen angreifende White Walkers zu halten, erleidet er ein traumatisches Erlebnis, das ihn für den Rest seines Lebens prägt.
  • Der junge Wylis erlebt diesen Moment so intensiv, dass sein Verstand bricht und er nur noch das Wort „Hodor“ wiederholen kann.

Diese Enthüllung verleiht Hodor eine tiefere Tragik, da sein gesamtes Leben durch diesen heroischen Moment definiert wird, der für die Rettung von Bran und Meera entscheidend ist.

Hodor!

Zuerst dachte ich, ich käme ganz locker damit weg. Mobiltelefon auch außerhalb der Wohnung im WLAN. Leider nein, leider gar nicht. Bei einem erneuten Detailtest musste ich aber feststellen, dass es wohl eher vom Wetter oder der Mondphase abhängig sei. Auch ein dazugekaufter WLAN Repeater brachte keine Besserung. Zumindest hab ich nun auch auf Klo ein super Netz. Klar bietet FritzBox auch die Möglichkeit eines DynDNS-Ähnlichen Dienstes, der der FritzBox eine feste IP-Adresse beschert und mir somit Zugriff auf das Heimnetz von unterwegs gewährleistet, allerdings möchte ich das möglichst vermeiden.

Das PHP Skript

Kurz drüber nachdenken. Was ist nochmal mein Job? Achja, Programmierer. Könnte ganz praktisch sein.
Also ab dafür, fix die IDE hochgefahren und ein kleines Skript basteln, dass von nun an auf nem Webspace wohnt. Die genutzte Lösung hier ist nur eine Rohfassung, zwar könnt ihr das so betreiben, ich rate aber dazu entweder einen richtig dicken „key“ alias Passwort zu nutzen, oder/und noch einen htaccess Schutz davor zu setzen. Das Hodor-Skript liest eine Json-Datei ein, in der durchgängig 1 zurückgegeben wird. Über eine URL kann ich den Status lesen, mit einer anderen kann ich den Status aber auch beschreiben. Neben dem bereits beschriebenen htaccess und read/write keys solltest du auch der json Datei einen unleserlichen Namen geben.

Das PHP Skript

<?php
/**
 * Script Name: Hodor
 * Description: script to read and write json file for home assistant
 * Author: Stefan Wilhelm
 * Version: 0.1
 * Date: 2025-01-20
 */

define('WRITE_KEY', 'my_very_secure_key');
define('READ_KEY', 'my_very_secure_key');
define('JSON_FILE', 'my_json_file.json');

if(WRITE_KEY === 'my_very_secure_key' || READ_KEY  === 'my_very_secure_key'){
    die('change your keys!');
}

$jsonFile = JSON_FILE;

if(isset($_GET['action']) && $_GET['action'] === 'read'){

    if(isset($_GET['key']) && $_GET['key'] === READ_KEY){
        if (file_exists($jsonFile)) {

            $jsonData = file_get_contents($jsonFile);
            header('Content-Type: application/json');
    
            echo $jsonData;
        } else {
            header('Content-Type: application/json');
            echo json_encode(['error' => 'File not found']);
        }
    }

} else if(isset($_GET['action']) && $_GET['action'] === 'write') {
    if(isset($_GET['key']) && $_GET['key'] === WRITE_KEY && isset($_GET['value']) && $_GET['value'] !== ''){

        if (file_exists($jsonFile)) {

            $newContent = [
                "hodor" => intval($_GET['value'])
            ];
            
            $jsonData = json_encode($newContent, JSON_PRETTY_PRINT);
            
            if (file_put_contents($jsonFile, $jsonData)) {
                header('Content-Type: application/json');
                echo json_encode(['success' => 'File updated successfully.']);
            } else {
                header('Content-Type: application/json');
                echo json_encode(['fail' => 'Failed to write to file.']);
            }

        } else {
            header('Content-Type: application/json');
            echo json_encode(['error' => 'File not found']);
        }
    }
}

Home Assistant Sensor und Automation

Also nächstes gehts in Home Assistant. Ich brauche den Hodor-Sensor, der die ‚API‘ Schnittstelle, also das Hodor-Skript abfragt. Hierzu erstelle ich einen neuen Sensor, der die REST Bibliothek nutzt und damit meine URL aufruft. Leider kann man bisher keine Inline-Secret in Strings integrieren. Somit landet die gesamte Lese-URL, als auch Schreibe-URL in meiner secret.yaml.


### configuration.yaml
# Loads default set of integrations. Do not remove.
# ... bla

# Load frontend themes from the themes folder
# ... bla
# ... bla
sensor: !include sensor.yaml
### sensor.yaml
- platform: rest
  resource: !secret hodor_read  # Ersetze mit deiner URL
  name: "Hodor Sensor"
  value_template: "{{ value_json.hodor }}"  # Liest den Wert von "hodor"
  scan_interval: 5

Damit bekomme ich nun auch den aktuellen Status im Dashboard angezeigt. Der Leseintervall ist bei mir auf 5 Sekunden gestellt. Das ist dann nun auch die theoretische Maximalzeit, die ich auf eine Reaktion vor der Tür nach dem Betätigen des Schalters warten muss. Latenzen und Schaltzeiten außer Acht gelassen. Nun noch eine Automation erstellen, die einen weiteren REST Command ausführt, um den Status des Skriptes auf der Website wieder auf „1“ zu setzen.

### rest_command.yaml
hodor_off:
  url: !secret hodor_write
  method: GET  # Change to POST if necessary
  headers:
    Content-Type: application/json
### automations.yaml
- alias: Hodor changes state to 0
  description: 'Call URL, mqtt impuls when Hodor changes from 1 to 0'
  trigger:
    platform: state
    entity_id: sensor.hodor_sensor
    from: "1"
    to: "0"
  action:
    - service: rest_command.hodor_off
    - service: input_boolean.turn_on
      target:
        entity_id: input_boolean.impuls
  mode: single

Android App als Türöffner

Nun – ich könnte, wenn ich mit dem Handy vor der Tür stehe, jedes mal kurz die URL zum Öffnen im Browser öffnen, ich könnte aber auch – weil ich zum Erstellen dieses Artikels sowieso noch auf den Pi Zero warte – auch noch eine Android App bauen, mit der ich Schalter drücken und damit URLs aufrufen kann :D
Ich hab für euch hier zwar aktuell noch nicht den Quelltext, aber hier könnt ihr eine unsigned APK herunterladen. Die Applikation setzt auf Apache Cordova mit Angular und Materials. Es benötigt zum Aufrufen von Urls, the Internet und zum Darstellen von Fonts auch Google. Ihr könnt beliebige URLs per GET Aufrufen und diese für jeden Knopf speichern. Zum Speichern der URLs wird der Local Storage benutzt. Ich musste die App beim Installieren von Google Play Protect testen lassen, ansonsten verweigerte mein Handy die Installation.
Einige Fallstricke auf dem Weg zu einer fertigen APK: der Installer von Cordova und der verbundene Befehl „cordova requirements“ will JDK 8. Verwendet wurde letztendlich unter einer Qual von Libraries und Bla, JDK 11. Immer mit dem Hintergrund, dass Oracle irgendeinen dummen Login vor seiner Downloadseite hat, bei dem bei mir die Registrierung nicht funktioniert hat. Also musste eine andere Quelle für die JDK her. Einige Artikel wiesen daraufhin, dass man das auch irgendwie mit OpenJDK lösen könne, aber ich hab davon mal echt keinen Plan und wollte nur irgendwie zum Ziel gelangen.

Zwischenstand und weitere Todos

Wir können nun also mit der App die API ansteuern und HODOR auf 0 setzen. Home Assistant fragt alle 5 Sekunden nach dem Wert online und rennt los, wenn sich der Status durch die App ändert. Nun habe ich noch einen Raspberry Pi zero im Einsatz, der die Schaltung des Relais in der Nähe der Gegensprechanlage steuern wird.

Der Pi Zero

Der Pi Zero (im Nachfolgenden „Subscriber“) sollte über das WLAN ansprechbar sein, leider fand ich auf amazon nur „WIFI Intelligenter Schalter mit Ewelink App“. Ich hoffte, ich würde die App nur zur Einrichtung gebrauchen und könnte dem Schalter anschließend einfach die Rechte für Internetkommunikation von Seiten der Fritzbox kappen. Fehlanzeige. Der Schalter funktionierte erstens nur in 25% der Fälle zuverlässig und verweigerte zweitens ohne Internetverbindung vollständig den Dienst. Nach einem Firmware-Update tat der Schalter dann auch gar nichts mehr und eigentlich bereue ich den Kauf zutiefst.
Keinen Dyn-DNS Dienst verwenden, aber diesen China-Schrott-Dienst dauerhauft in mein privates WLAN lassen. No-Go! Was anderes musste her. Also auf Amazon noch einen Raspberry Pi Zero W gekauft und schauen, was das Internet so über Schalter sagt. In Zukunft ersetze ich den Pi vllt noch durch ein ESP

Zunächst hab ich auf dem Zero noch Mosquitto (client) und auf dem Home Assistant „MQTT Broker“ Plugin installiert.

MQTT und Mosquitto (AI Content)

MQTT (Message Queuing Telemetry Transport) und Mosquitto sind zwei eng miteinander verbundene Begriffe im Bereich der Kommunikation zwischen Geräten, insbesondere in der IoT-Welt (Internet of Things).

MQTT ist ein Nachrichtenprotokoll, das für die Kommunikation zwischen Geräten mit eingeschränkten Ressourcen entwickelt wurde. Es wird häufig in IoT-Systemen verwendet.

Mosquitto ist eine Open-Source-Implementierung eines MQTT-Brokers. Es dient als Vermittler zwischen den MQTT-Clients (Publishern und Subscribern) und verwaltet den Nachrichtenaustausch.

Wir werden also die Daten, die wir benötigen, in diesem Fall also nur den Wechsel von 1 auf 0 über MQTT per WLAN vom Home Assistant and den Pi Zero schicken. Bei MQTT gibt es 3 Akteure. Den Publisher, also den Auslöser, in unserem Fall die API, bzw. das Handy, dass den Vorgang in Gang setzt. Den Broker, der die Publisher Daten empfängt (HA) und diese auf festgelegten Kanälen zur Verfügung stellt. Das Endgerät Subscriber (Pi zero), der oder die, die die vom Broker bereitgestellten Kanäle und ihre Daten abonnieren kann.

Bei der Gegensprechanlange wurde zum Glück auch der Autor benannt, der das Schaltbild für das Telefon bereitstellte – Und auch, wenn Schaltbild und Ritto Telefonanlage nicht ganz zusammenpassen wollen, stimmt die Belegung wenigstens für die Türöffnung überein. Schaut für weitere Details unbedingt auch bei dem Autor und seiner Site vorbei


Nun noch den Pi zero Schalter und die Gegensprecheinrichtung zusammenlöten und dann kann es auch schon => endlich losgehen.

Schreibe einen Kommentar