Garagentor mit dem Smartphone öffnen: Shelly 2.5

Shelly ist ein preisgünstiges, per WLAN mittels HTTP, Cloud oder Smart Home Produkten steuerbares Relais von Allterco Robotics. Entscheidend für mich gegenüber üblichen Smart Home Produkten war nicht nur der Preis, sondern vor allem die Möglichkeit, per Webinterface aus dem lokalen Netzwerk auf ein Shelly zu zugreifen und ebenfalls Aktionen ohne Abhängigkeit von Clouds oder Apps von Drittanbietern ausführen zu können. Shellys können direkt an Netzspannung betrieben werden und eignen sich durch ihre Größe von etwa einer Streichholzschachtel perfekt zum Einbau in andere Geräte oder Elektroinstallationsdosen.

Zur Fernsteuerung eines Garagentorantriebs habe ich ein Shelly 2.5, also die Variante mit zwei Relais verwendet. Der Garagentorantrieb ist alt und hat einen hohen Standby-Verbrauch und wird nicht täglich benutzt, daher möchte ich die Möglichkeit haben, den Antrieb aus der Ferne ein-/ausschalten zu können und das Öffnen / Schließen des Tores zu veranlassen. Es gibt vom Hersteller eine eigene App, welche aber meiner Meinung nach nicht so gut funktioniert und den Zugriff aus dem Internet auf die Geräte beinhaltet. Meine Lösung wird über ein PHP Skript aus dem lokalen Netzwerk gesteuert. Das PHP Skript zum Steuern des Shelly Relais kann zum Beispiel auf einer NAS oder einem Miniaturrechner wie dem Raspberry Pi abgelegt werden. Die Seite kann dann per WLAN auf einem Smartphone aufgerufen werden und so das Tor geöffnet werden.

Vorgehen zur Umsetzung

  1. Einstellungen und Test erledigt man am einfachsten auf dem Schreibtisch. Dazu das Shelly mit Netzspannung an den Klemmen L (Phase) und N (Neutralleiter) versorgen. Die beiden Klemmen L sind intern verbunden, es spielt also keine Rolle, welche L-Klemme gewählt wird.
  1. Nach ein paar Sekunden stellt das Shelly sein eigenes WLAN Netz mit dem Namen shellyswitch25-… zur Verfügung. Mit einem Rechner eine Verbindung zu diesem Netz herstellen. Es ist kein Kennwort erforderlich.
  2. Im Webbrowser die Adresse 192.168.33.1 öffnen. Nun sollte das Webinterface sichtbar sein.
  3. Über „Internet & Security“ kann nun eine Verbindung zum WLAN Netz des Hauses hergestellt werden. Dazu Name des Netzes und Kennwort eingeben. Zusätzlich sollte dem Shelly eine statische IP zugewiesen werden, damit das Gerät später für das PHP Skript zum Öffnen des Tores erreichbar ist. Außerdem sollte unter Gateway und DNS die IP Adresse des Routers angetragen werden (Für Datum, Uhrzeit und Firmwareupdates).
  1. Den Rechner wieder mit dem WLAN des Hauses verbinden. Das temporäre shellyswitch25-… WLAN Netz sollte nun verschwunden sein und das Shelly sollte im Webbrowser über die eben eingetragene IP Adresse ansprechbar sein. Anschließend ein Firmwareupdate durchführen und Benutzer und Passwort setzen.
  2. Die beiden Relais des Shellys benennen. Ich werde das erste Relais zum Schalten der Stromversorgung des Antriebs nutzen und das zweite Relais als Trigger zum Öffnen / Schließen des Tores. Daher habe ich beim zweiten Relais die Einstellung gesetzt, dass das Relais eine Sekunde nach dem Einschalten wieder abgeschaltet wird.
  3. PHP Skript anpassen, auf ein Gerät im lokalen Netzwerk mit Webserver hochladen und testen.
PHP Code: Shelly per PHP steuern
<?php
session_start();
//Zugangsdaten und Secretkeys anpassen
$username = 'user';
$password = 'pass';
$random1 = 'secretkey1';
$random2 = 'secretkey2';
$hash = md5($random1.$password.$random2);
$self = $_SERVER['REQUEST_URI'];

//Hier die Zugangsdaten zum Shelly eintragen
$devices = array(
    array("[ShellyIP]", "[ShellyUser]", "[ShellyPass]")
);

//Funktion zur Kommunikation mittels HTTP mit dem Shelly
function callURL($method, $url, $data){
    $curl = curl_init();
    switch ($method){
        case "POST":
            curl_setopt($curl, CURLOPT_POST, 1);
            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            break;
        case "PUT":
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            break;
        default:
            if ($data)
                $url = sprintf("%s?%s", $url, http_build_query($data));
    }
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
    ));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    $result = curl_exec($curl);
    if(!$result){die("Connection Failure");}
    curl_close($curl);
    return $result;
}

//Funktion ermittelt Schaltzustand des Shellys
function getRelayStatus($deviceNo, $relayNo) {
    global $devices;
    $get_data = callURL('GET', 'http://'.$devices[$deviceNo][1].':'.$devices[$deviceNo][2].'@'.$devices[$deviceNo][0].'/relay/'.$relayNo, false);
    $response = json_decode($get_data, true);
    if($response["ison"] === TRUE)
       return true;
    if($response["ison"] === FALSE)
        return false;
}

//Funktion liefert HTML Code zum Schaltzustand
function getRelayStatusHTMLOutput($deviceNo, $relayNo) {
    $response = getRelayStatus($deviceNo, $relayNo);
    if($response === true)
        return "<span style=\"font-size: 40px; color: mediumseagreen;\"><i class=\"fas fa-plug\"></i></span><br><strong>Ein</strong>";
    if($response === false)
        return "<span style=\"font-size: 40px; color: darkgray;\"><i class=\"fas fa-plug\"></i></span><br><strong>Aus</strong>";
}

//Funktion schaltet Relais
function toggleRelay($deviceNo, $relayNo) {
global $devices;
callURL('POST', 'http://'.$devices[$deviceNo][1].':'.$devices[$deviceNo][2].'@'.$devices[$deviceNo][0].'/relay/'.$relayNo.'?turn=toggle', false);
}
?>
    <!doctype html>
    <html lang="de">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
        <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
        <title>Schalter</title>
    </head>
    <body>

<?php

// logout
if(isset($_GET['logout'])) {
    unset($_SESSION['login']);
}


// user is logged in
if (isset($_SESSION['login']) && $_SESSION['login'] == $hash) {

    if (isset($_POST['toggle'])) {
        toggleRelay($_POST['deviceNo'], $_POST['relayNo']);
    }
    ?>
    <div class="container">
        <h2>Torantrieb</h2>
        <div class="row d-flex justify-content-center">
            <div class="col text-center" >
                <h5>Stromversorgung</h5>
                <?php echo getRelayStatusHTMLOutput(0,0); ?>
                <form action="<?php echo $self; ?>" method='post'>
                    <input type="hidden" name="deviceNo" value="0">
                    <input type="hidden" name="relayNo" value="0">
                    <input class="btn btn-lg btn-success" type="submit" name="toggle" value="Umschalten">
                </form>
            </div>
            <div class="col text-center">
                <h5>Tor</h5>
                <span style="font-size: 40px; color: darkgray;"><i class="fas fa-warehouse"></i></span></br>
                &nbsp;
                <form action="<?php echo $self; ?>" method='post'>
                    <input type="hidden" name="deviceNo" value="0">
                    <input type="hidden" name="relayNo" value="1">
                    <input class="btn btn-lg btn-warning" type="submit" name="toggle" value="Auf / Zu">
                </form>
            </div>
        </div>
    </div>
    <br>

    <a href="?logout=true">Abmelden</a>
    <?php
}
else if (isset($_POST['submit'])) {

    if ($_POST['username'] == $username && $_POST['password'] == $password){
        $_SESSION["login"] = $hash;
        header("Location: $_SERVER[PHP_SELF]");

    } else {
        display_login_form();
        echo '<p>Benutzer / Passwort falsch.</p>';
    }
}

else {
    display_login_form();
}

?>
    </body>
</html>

<?php
function display_login_form() {
        global $self; ?>
    <form action="<?php echo $self; ?>" method='post' class="form-signin">
        <h2 class="h3 mb-3 font-weight-normal">Bitte anmelden</h2>
        <label for="username" class="sr-only">Benutzer</label>
        <input type="text" name="username" id="username" class="form-control" placeholder="Benutzer" required autofocus>
        <label for="password" class="sr-only">Passwort</label>
        <input type="password" name="password" id="password" class="form-control" placeholder="Passwort" required>
        <button class="btn btn-lg btn-primary btn-block" name="submit" type="submit">Anmelden</button>
    </form>
<?php } ?>
  1. Anschließend kann das Shelly umziehen und im Gehäuse des Torantriebs eingebaut werden. Zum Auslösen der Torsteuerung ist bei meinem Antrieb ein weiteres Relais oder Installationsschutz erforderlich, da die Steuerung des Torantriebes mit einer Kleinspannung arbeitet und am Ausgang des Shellys Netzspannung anliegt. Ich habe das Shelly wie folgt angeschlossen. In schwarz sind ein Schalter und ein Taster dargestellt, die eine Bedienung des Tores direkt am Antrieb, also ohne Smartphone ermöglichen. Die beiden Komponenten sind optional.
Schaltplan für Garagentoröffner mit Shelly 2.5
Screenshot

Update: Schlechter WLAN-Empfang bei Shelly

Nach einigen Tagen Praxistest wurde deutlich, das die Signalstärke des WLAN-Netzes für das Shelly im Garagentorantrieb unzureichend ist. Mal bestand eine Verbindung zum Access Point, mal war die Verbindung unterbrochen. Um das Problem zu beheben, habe ich das Shelly wieder an ein Netzkabel mit Verlängerungsleitung angeschlossen. Damit kann dass Gerät frei im Raum bewegt werden. Im Webinterface des Shelly kann in der Kopfzeile die Signalstärke abgelesen werden. Zur bestmöglichen Positionierung ist das Ampelsystem mit nur drei Farben jedoch zu unpräzise. Auf der Seite „Settings“ kann unter „Device Info“ der Wert WiFi RSSI (für Received Signal Strength Indicator) abgelesen werden. Je kleiner der Wert ist, desto besser ist die Signalstärke. Beim Bewegen des Shellys wird der Wert periodisch aktualisiert. Ich habe die Erfahrung gemacht, dass nicht nur die Position im Raum, sondern auch die Orientierung von Vorder- und Rückseite einen gravierenden Unterschied macht. Nach dem ich eine Postion mit guter Signalstärke gefunden hatte, habe ich mit Bleistift die Position des Shellys auf die Decke gezeichnet und an der Stelle einen Abzweigkasten gesetzt. Seitdem das Shelly in der neu positionierten Abzweigdose sitzt, hat es einen unterbrechungsfreien, guten WLAN-Empfang.

Schreibe einen Kommentar