Hauptmenü

Gerät über Internet schalten

Begonnen von hugo, 27 Oktober 2024, 08:26:12

Vorheriges Thema - Nächstes Thema

hugo

Hallo zusammen,
jetzt habe ich schon viel gelesen, aber noch keine gute passende Lösung gefunden.
Am liebsten möchte meine Frau einen Knopf :) (App) auf dem Handy (IPhone) haben und dann nur ein Device schalten können z.b. Garagentor.
Der Zugriff sollte sicher sein, keine Portweiterleitung. Könnte mir als Verbindung VPN on demand vorstellen, dass sich aber nach dem senden des Befehls wieder trennt.

Hat jemand eine solche Lösung oder einen Tipp wie ich das lösen könnte.

Viel Dank für eure Ideen.

Gruß Josef
Raspi 3 mit CUL HM-MOD-UART; nanoCUL
Homematic: HM-SEC-SCo 5x;HM-LC-SW1-BA-PCB 3x;HM-Dis-EP-WM55; HM-LC-SW4-PCB; ARLO;
Somfy RTS Rollo 14x; Alexa; GardenaSmartDevice; Stromzähler(GPIO); shelly1; shelly2.5;Wasserzähler(GPIO);Brennerstuhlsteckdosen;

tobi01001

Hi,

ich nutze für externe "Kommunkation" - sprich Empfang gewisser Ereignisse sowie diverese Schaltvorgänge Telegram mit entsprechenden Telegrambot.

Ungetestet - aber theoretisch möglich - Shortcut in iOS der über Telegram eine Nachricht an den Bot schickt und über fhem die Aktion auslöst.

Gruß,
Tobias
FHEM@UbuntuServer on Lenovo ThinkCentre M900 [i5-6500T / 8GB RAM] MySQL-DbLog, Grafana, FTUI3 / HmIP incl. CCU3 / LGESS / Wärempumpe über TA CMI und CANoE / Shellies u.v.m.

DeeSPe

Warum nicht Apples Bordmittel verwenden, HomeKit?
Damit ist kein VPN nötig, es ist mit Siri nutzbar und man hat mannigfaltige Möglichkeiten inkl. zugehöriger App.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

hugo

Hallo Dan,
für Homekit brauche ich doch eine Zentrale oder habe ich das falsch gelesen. AppleTV oder Homepod?

Aber sowas besitze ich zur Zeit nicht oder gibts hier andere Zentralen.

Gruß Josef
Raspi 3 mit CUL HM-MOD-UART; nanoCUL
Homematic: HM-SEC-SCo 5x;HM-LC-SW1-BA-PCB 3x;HM-Dis-EP-WM55; HM-LC-SW4-PCB; ARLO;
Somfy RTS Rollo 14x; Alexa; GardenaSmartDevice; Stromzähler(GPIO); shelly1; shelly2.5;Wasserzähler(GPIO);Brennerstuhlsteckdosen;

Torxgewinde

#4
Man kann das auf viele Arten lösen, eine davon wäre NTFY.sh zu verwenden (Forum Thread dazu: 📬 NTFY.sh: Push Nachrichten an iOS, Android, PC, Command-Line, E-Mail & Telefon). FHEM kann auf NTFY Nachrichten reagieren, der NTFY Server läuft gut erreichbar im WAN. Du musst dir lediglich ein nicht zu erratendes Topic überlegen, falls du den öffentlichen Server nutzt (bei einem privatem Server hättest du mehr Arbeit aber dafür freie Wahl).

  • Der "One-Button-User" braucht minimal nur einen HTTPS-Request auslösen. Sowas kann ein iOS Handy mit den Kurzbefehlen, Apple-Shortcuts, für Android gibt es HTTP-Shortcuts (Tracker- und werbefrei im F-Droid-Store und auch im Play-Store).
  • Auf den NTFY kann dann FHEM reagieren

HTH!

Links:
https://gitea.federationhq.de/byterazor/FHEM-NTFY

Jamo

#5
Wenn es nur ein Knopf sein soll, und Du / deine Frau ein Apple Geraet hat,koenntest Du auch in der "Shortcuts App" auf dem iPhone, einen neuen Shortcut "Garagentor" erstellen, und dort einen HTTP request hinterlegen, mit dem FHEM command das Garagentor zu oeffnen, also so etwa:

http://<fhem>:8083/fhem?cmd=set%20Garagentor%20open&XHR=1
 http://192.168.178.1:8083/fhem?cmd=set%20Garagentor%20open&fwcsrf=123456789&XHR=1
Den Befehl kannst Du auch einfach mal im Webbrowser ausprobieren, also oben im URL feld eingeben. Info link zum Beispiel Link: https://forum.fhem.de/index.php?topic=43159.0

Das geht ohne Zentrale, also einfach ueber den URL. Dafuer muesste dann VPN on demand eingerichtet sein, oder Du musst im heimischen LAN / WLAN sein.

Den Shortcut kann man dann einfach in der App anklicken, oder Du kannst Dir den Shortcut direkt auf den Homescreen legen, dann brauchst Du nur noch klicken. Habs gerade mal ausprobiert, das geht einwandfrei.
Bullseye auf iNUC, Homematic + HMIP(UART/HMUSB), Debmatic, HUEBridge, Zigbee/Conbee III, FB7690, Alexa (fhem-lazy), Livetracking, LaCrosse JeeLink, LoRaWan / TTN / Chirpstack, Sonos, ESPresence

TomLee

#6
Zitatoder Du kannst Dir den Shortcut direkt auf den Homescreen legen

Den Shortcut würd ich dann als Widget (Wisch im Home- oder Sperrbildschirm nach rechts) oder (mit IOS 16) zum Sperrbildschirm hinzufügen.

Damit kann man dann (im heimischen WLAN) mit zwei Gesten aus dem Sperrbildschirm die Tür öffnen.

edit:
Ok, drei Gesten wären nötig, Sperrbildschirm aktivieren, nach rechts oder oben wischen, Widget auslösen.

Torxgewinde

#7
@hugo: Kann man denn voraussetzen, dass FHEM bei dir ohne Authentifizierung läuft?
Kann man annehmen dass das VPN schnell genug aufgebaut ist, oder dass das Gerät bereits im heimischem WLAN eingebucht ist?

FHEM ohne Authentifizierung im LAN zu nutzen ist nicht so gut, in so einem Setup kann jedes Gerät im LAN FHEM nutzen. Da FHEM auch Systembefehle auslösen kann, kann man auch mit FHEM Rechten auf Betriebssystemebene Befehle ausführen. Insgesamt keine so gute Idee, außer man hat so richtig vertrauen in alle seine LAN Geräte und Nutzer.

Nutzt man FHEMWEB mit dem Modul "allowed" kann man Zugangsdaten nutzen. Die sind allerdings ohne HTTPS nicht verschlüsselt und damit für moderne Geräte im LAN praktisch nicht als geschützt anzunehmen. Ist schon besser als nix, ist aber auch wieder so Lala von der Sicherheit. Auch sollte man dann verschiedene Nutzer für den One-Button-User und den Admin von FHEM einrichten, da sonst der One-Button-User pfleglich auf die Logindaten aufpassen sollte und das ist bei One-Button-Usern eher nicht sichergestellt, sonst wären sie ja nicht mit nur einem Button zufrieden.

Nutzt man FHEMWEB mit HTTPS, dann sind die Zugangsdaten geschützt. Dann sollte auch im Mobilgerät eine akzeptierte CA genutzt werden, sonst mag iOS keine Verbindung aufbauen. Für HTTPS bietet sich Let's Encrypt an, oder man macht seine eigene CA und importiert diese in das iOS Gerät als vertrauenswürdig.

Falls also die Bedenken zum Grübeln anregen, ist NTFY weiterhin eine Option. Der öffentliche NTFY-Server läuft bereits mit einer anerkannten CA, wird von iOS also wie er ist akzeptiert. Der Komfort (Anzahl der Klicks) ist der gleiche wie bei der direkten Ansprache des FHEMWEB Servers, nur dass es auch ganz ohne VPN, Portweiterleitung oder WLAN über das Internet funktioniert.

Was denkt ihr?

Edit #1:
Um NTFY.sh einzurichten:
update add https://rm.byterazor.de/upd-fhem-ntfy/controls_byterazor-fhem-ntfy.txt
update
shutdown restart
Ein Device anlegen mit:
defmod NTFY0 NTFY_CLIENT https://ntfy.sh
attr NTFY0 defaultPriority default
attr NTFY0 defaultTopic FreundlichenGruesseAnAlleFHEMNutzer
attr NTFY0 room Experimente

Senden einer Nachricht mit einem curl-Befehl:
curl -d "Your message content here" \
     -H "Title: Bla" \
     https://ntfy.sh/FreundlichenGruesseAnAlleFHEMNutzer
Das Gleiche nur mit WGET:
wget --method=POST \
     --body-data="Your message content here" \
     --header="Title: Bla" \
     https://ntfy.sh/FreundlichenGruesseAnAlleFHEMNutzer -q -O -
Oder, wenn es ein reines HTTP-GET als Webhook sein soll:
https://ntfy.sh/FreundlichenGruesseAnAlleFHEMNutzer/publish?message=Your%20message%20content%20here&title=Bla

Im Event-Log taucht dann folgendes auf, darauf kann man mit notify oder DOIF reagieren:
2024-10-29 19:01:16.714 NTFY_TOPIC NTFY0_FreundlichenGruesseAnAlleFHEMNutzer nrReceivedMessages: 7
2024-10-29 19:01:16.715 NTFY_CLIENT NTFY0 subscriptions: FreundlichenGruesseAnAlleFHEMNutzer
2024-10-29 19:01:16.715 NTFY_CLIENT NTFY0 nrReceivedMessages: 7
2024-10-29 19:01:16.715 NTFY_CLIENT NTFY0 lastReceivedTitle: Bla
2024-10-29 19:01:16.715 NTFY_CLIENT NTFY0 lastReceivedData: Your message content here
2024-10-29 19:01:16.715 NTFY_CLIENT NTFY0 lastReceivedRawMessage: {"id":"oU5iqrdSFoeY","time":1730224876,"expires":1730268076,"event":"message","topic":"FreundlichenGruesseAnAlleFHEMNutzer","title":"Bla","message":"Your message content here"}

Mit einem notify-device kann man dann wie folgt reagieren:
defmod GarageNotify notify NTFY0:lastReceivedData:.* {\
Log(1, "$NAME: $EVTPART1, $EVTPART2, $EVENT");;\
\
if ("$EVTPART1 $EVTPART2" eq "Garage zu") {\
Log(1, "Garage soll zu gemacht werden");;\
fhem("set NTFY0 publish Ich werde die Garage nun schliessen");;\
}\
\
if ("$EVTPART1 $EVTPART2" eq "Garage auf") {\
Log(1, "Garage soll auf gemacht werden");;\
fhem("set NTFY0 publish Ich werde die Garage nun oeffnen");;\
}\
}
attr GarageNotify room Experimente
Die zugehörigen Webhooks wären dann:
https://ntfy.sh/FreundlichenGruesseAnAlleFHEMNutzer/publish?message=Garage%20auf
https://ntfy.sh/FreundlichenGruesseAnAlleFHEMNutzer/publish?message=Garage%20zu

Testen kannst du das hier:
https://ntfy.sh/FreundlichenGruesseAnAlleFHEMNutzer
https://demo-fhem.cooltux.net/fhem?detail=NTFY0 <-- Nur für begrenzte Zeit gültig
https://ntfy.sh/FreundlichenGruesseAnAlleFHEMNutzer/publish?message=Blubb&title=Bla

Wie man die App Kurzbefehle dazu bringt eine URL abzurufen, kann man bei Apple nachlesen:
https://support.apple.com/de-de/guide/shortcuts/apd58d46713f/ios

Torxgewinde

#8
Ich stelle gerade fest, dass nach einigen Stunden das NTFY nicht mehr auf die Nachrichten reagiert hatte. Ich habe einen Bugeintrag eröffnet, mal gucken: https://rm.byterazor.de/issues/53
Edit #1: Laut GIT ist das Thema in dem richtigem NTFY Modul gelöst, danke @Byterazor!

Falls jemand diese, bei weitem nicht so schöne, Alternative ausprobieren möchte um die Wartezeit zu überbrücken, hier eine zusammengehämmerte, eigene Lösung:
defmod NTFY_RECEIVE dummy
attr NTFY_RECEIVE userattr URL last_seen_max_age
attr NTFY_RECEIVE URL wss:ntfy.sh:443/FreundlichenGruesseAnAlleFHEMNutzer/ws
attr NTFY_RECEIVE alias NTFY_RECEIVE
attr NTFY_RECEIVE devStateIcon opened:general_ok@green:stop disconnected:rc_STOP@red:start
attr NTFY_RECEIVE eventMap /cmd connect:start/cmd disconnect:stop/
attr NTFY_RECEIVE icon hue_filled_plug
attr NTFY_RECEIVE last_seen_max_age 600
attr NTFY_RECEIVE readingList cmd
attr NTFY_RECEIVE room Experimente
attr NTFY_RECEIVE setList cmd
attr NTFY_RECEIVE userReadings connect:cmd:.connect {\
    my $hash = $defs{$name};;\
    my $devState = DevIo_IsOpen($hash);;\
    return "Device already open" if (defined($devState));;\
    \
    $hash->{DeviceName} = AttrVal($name, "URL", "wss:ntfy.sh:443/FreundlichenGruesseAnAlleFHEMNutzer/ws");;\
    $hash->{header}{'Host'} = 'ntfy.sh';;\
    $hash->{header}{'User-Agent'} = 'FHEM';;\
    \
    $hash->{directReadFn} = sub () {\
        my $hash = $defs{$name};;\
        readingsBeginUpdate($hash);;\
        my $buf = DevIo_SimpleRead($hash);;\
        \
        # track activity, emtpy buffer normally is from ping/pongs\
        readingsBulkUpdate($hash, "last_seen", int(time()*1000));;\
        RemoveInternalTimer($name.'Timeout');;\
        my $timeoutFunction = sub() {\
            my ($arg) = @_;;\
            my $hash = $defs{$name};;\
            my $myCmd = ReadingsVal($name, "cmd", "disconnect");;\
            return if ($myCmd =~ /disconnect|stop/);;\
\
            Log3($name, 3, "$name: Timeout occured, restarting websocket...");;\
            DevIo_CloseDev($hash);;\
            readingsBeginUpdate($hash);;\
            readingsBulkUpdate($hash, "state", "disconnected");;\
            readingsBulkUpdate($hash, "cmd", "connect", 1);;\
            readingsEndUpdate($hash, 1);;\
        };;\
        InternalTimer(gettimeofday() + 120, $timeoutFunction, $name.'Timeout');;\
        \
        if(!defined($buf)) {\
            DevIo_CloseDev($hash);;\
            #readingsBulkUpdate($hash, "last_seen", 0);;\
            $buf = "not_connected";;\
        }\
        \
        # only update our reading if buffer is not empty and looks like it contains a message\
        if ($buf ne "" && \
            $buf =~ /^{.*"event":"message".*}$/) { ## check if buffer looks like JSON with msg\
            \
            # delete all our readings that begin with "ntfy_"\
            foreach my $reading (grep { $_ =~ /^ntfy_.*/ } keys %{$hash->{READINGS}}) {\
                readingsDelete($hash, $reading);;\
            }\
            \
            # parse as JSON, do not trust the input fully, thus sanitize buffer\
            my %res = %{json2nameValue($buf)};; #(https://wiki.fhem.de/wiki/MQTT2_DEVICE_-_Schritt_f%C3%BCr_Schritt#json2nameValue.28.29)\
            foreach my $k (sort keys %res) {\
                # only keep ASCII and a German Characters like Umlaute, sharp-S...\
                my $sanitizedValue = $res{$k} =~ s/[^[:ascii:]äöüÖÄÜß]/_/rg;; # 'r' flag prevents modifying the input string\
                readingsBulkUpdate($hash, "ntfy_".makeReadingName($k), $sanitizedValue);;\
            }\
        }\
        #readingsBulkUpdate($hash, "websocketData", "$buf") if ($buf ne "");;\
        Log3($name, 3, "$name: Rx: >>>$buf<<<") if ($buf ne "");;\
        \
        readingsEndUpdate($hash, 1);;\
    };;\
    \
    DevIo_OpenDev($hash,\
        0,      ## reopen flag\
        undef,  ## initFn, on success\
        sub() { ## callbackFn, on verdict, req. to make it a non-blocking call\
            my ($hash, $error) = @_;;\
            if ($error) {\
                Log(3, "$name: DevIo_OpenDev Callback: connection failed: $error");;\
                \
                my $timerFunction = sub() {\
                    my ($arg) = @_;;\
                    my $hash = $defs{$name};;\
                    my $devState = DevIo_IsOpen($hash);;\
                    readingsSingleUpdate($hash, "cmd", "connect", 1) if (!defined($devState));;\
                };;\
                \
                RemoveInternalTimer($name.'Timer');;\
                my $rwait = int(rand(20)) + 10;;\
                InternalTimer(gettimeofday() + $rwait, $timerFunction, $name.'Timer');;\
                readingsSingleUpdate($hash, "cmd", "reconnect attempt in $rwait seconds", 1);;\
            }\
        }\
    );;\
    \
    readingsBulkUpdate($hash, "state", "connecting...");;\
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
disconnect:cmd:.disconnect {\
    my $hash = $defs{$name};;\
    RemoveInternalTimer($name.'Timer');;\
    RemoveInternalTimer($name.'Timeout');;\
    DevIo_CloseDev($hash);;\
    readingsBulkUpdate($hash, "state", "disconnected") if (!defined(DevIo_IsOpen($hash)));;\
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
onDisconnect { ## check on each update if the connection is unintentionally broken...\
    my $myState = ReadingsVal($name, "state", "???");;\
    my $myData = ReadingsVal($name, "websocketData", "???");;\
    my $myCmd = ReadingsVal($name, "cmd", "disconnect");;\
    return if ($myState ne "disconnected" and $myData ne "not_connected");;\
    return if ($myCmd =~ /disconnect|stop/);;\
\
    my $timerFunction = sub() {\
        my ($arg) = @_;;\
        my $hash = $defs{$name};;\
        my $devState = DevIo_IsOpen($hash);;\
        readingsSingleUpdate($hash, "cmd", "connect", 1) if (!defined($devState));;\
    };;\
\
    RemoveInternalTimer($name.'Timer');;\
    my $rwait = int(rand(20)) + 10;;\
    InternalTimer(gettimeofday() + $rwait, $timerFunction, $name.'Timer');;\
    readingsBulkUpdate($hash, "cmd", "reconnect attempt in $rwait seconds");;\
    \
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
}
attr NTFY_RECEIVE verbose 1
attr NTFY_RECEIVE webCmd start:stop

Torxgewinde

Wenn man ganz universell FHEM Befehle via NTFY senden möchte, sollte man diese unbedingt gegenprüfen, bevor man diese ausführt. Hier ein Vorschlag:

defmod GarageNotify notify NTFY0:lastReceivedData:.* {\
Log(1, "$NAME: >>>$EVENT<<<");;\
\
## remove the devicename from the $EVENT:\
my $cmd = $EVENT;;\
$cmd =~ s/^\Q$EVTPART0 \E//;;  # Remove $EVTPART0 from the beginning of $cmd\
Log(1, "$NAME: >>>$cmd<<<");;\
\
## Liste von erlaubten Befehlen als regulärer Ausdruck\
##   Zeilenende $ und Anfang ^ mit beachten,\
##   sonst sind unbeabsichtigte Befehlsketten/Escapes möglich\
my @commands = (\
'^set SteckdoseKuechenradio\.device o(?:ff|n)$',\
'^set G\.Ding1 on-for-timer [0-9]+$',\
'^set G\.Ding2 o(?:ff|n)$'\
);;\
\
##wandel von String in RegEx um\
@commands = map { qr{$_} } @commands;;\
\
##behalte was matcht, speichere die Arraylänge\
my $match = scalar grep { $cmd =~ $_ } @commands;;\
\
if ($match) {\
Log(1, "Führe FHEM command $cmd aus");;\
fhem("set NTFY0 publish FHEM sagt: Ich werde deinen FHEM Befehle nun ausfuehren");;\
fhem("$cmd");;\
}\
}
attr GarageNotify room Experimente

hugo

Vielen Dank für die Antworten.
Werde jetzt erstmal die Version mit dem VPN testen, ob die Zeit passt.

@Torxgewinde, du hast dir ja viel arbeit gemacht. Jetzt brauche ich doch einige Zeit um das alles zu verstehen und zum Nachdenken. Nochmal Danke.

Gruß Josef
Raspi 3 mit CUL HM-MOD-UART; nanoCUL
Homematic: HM-SEC-SCo 5x;HM-LC-SW1-BA-PCB 3x;HM-Dis-EP-WM55; HM-LC-SW4-PCB; ARLO;
Somfy RTS Rollo 14x; Alexa; GardenaSmartDevice; Stromzähler(GPIO); shelly1; shelly2.5;Wasserzähler(GPIO);Brennerstuhlsteckdosen;

andies

Ich habe VPN auf der FRITZ!Box (WireGuard) und dann auf dem iPhone meiner Frau ,,VPN on demand" installiert. In FHEM wiederum habe ich FTUI mit einer Webseite, und die Adresse dieser Seite habe ich auf den Home-Bildschirm hinterlegt. Das muss man einmalig anlegen.

Klickt sie dann auf das Icon auf dem iPhone, dauert es etwa 1-2 Sekunden und dann sieht sie das Bild unten: Kaffeemaschine, Rolladen und Gartentor.

Wenn Du mehr wissen willst, gerne fragen! Der WAF ist extrem wichtig.
FHEM 6.3 auf RaspPi4 (Raspbian:  6.6.28+; Perl: v5.36.0)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Arminus

Zitat von: andies am 17 November 2024, 21:31:51Wenn Du mehr wissen willst, gerne fragen! Der WAF ist extrem wichtig.

Hallo andies,

ich habe eine ähnliche Aufgabenstellung, kannst Du bitte Deine Lösung vorstellen?

Gruß
Arminus

Arminus

Zitat von: andies am 17 November 2024, 21:31:51Wenn Du mehr wissen willst, gerne fragen! Der WAF ist extrem wichtig.

Hallo andies,

ich habe eine ähnliche Aufgabenstellung, kannst Du bitte Deine Lösung vorstellen?

Gruß
Arminus

Arminus

Zitat von: andies am 17 November 2024, 21:31:51Wenn Du mehr wissen willst, gerne fragen! Der WAF ist extrem wichtig.

Hallo andies,

ich habe eine ähnliche Aufgabenstellung, kannst Du bitte Deine Lösung vorstellen?

Gruß
Arminus