From dd45a4e23159a2294e4123565cb82a5b340f3b1e Mon Sep 17 00:00:00 2001 From: klauswitt <> Date: Thu, 12 Nov 2015 21:28:44 +0000 Subject: [PATCH] 53_GHoma.pm: initial release git-svn-id: https://svn.fhem.de/fhem/trunk@9874 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 1 + fhem/FHEM/53_GHoma.pm | 584 ++++++++++++++++++++++++++++++++++++++++++ fhem/MAINTAINER.txt | 1 + 3 files changed, 586 insertions(+) create mode 100644 fhem/FHEM/53_GHoma.pm diff --git a/fhem/CHANGED b/fhem/CHANGED index d0deec7e4..dea6f12f2 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,6 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - feature: new module 53_GHoma.pm added (klausw) - feature: 14_CUL_REDIRECT: Rename 14_CUL_OTHER to 14_CUL_REDIRECT - bugfix: 00_SIGNALduino: Firmware Update 3.1.8-HF2 fixes a possible crash diff --git a/fhem/FHEM/53_GHoma.pm b/fhem/FHEM/53_GHoma.pm new file mode 100644 index 000000000..352a7376b --- /dev/null +++ b/fhem/FHEM/53_GHoma.pm @@ -0,0 +1,584 @@ +############################################## +# $Id: 53_GHoma.pm +# +# Protokoll: +# Prefix (5a a5), Anzahl Nutzbytes (2 Byte), Payload, Checksumme (FF - LowByte der Summe aller Payloadbytes), Postfix (5b b5) +# Antwort von Dose hat immer die letzen 3 Bloecke der MAC vom 11-13 Byte +# +# Payload immer in "|" +# Init1 (vom Server): +# 5a a5 00 07|02 05 0d 07 05 07 12|c6 5b b5 +# ** ** ** ** ** ** ** scheinen zufaellig zu sein +# 5a a5 00 01|02|fd 5b b5 +# Antwort auf Init1 von Dose: +# 5A A5 00 0B|03 01 0A C0 32 23 62 8A 7E 01 C2|AF 5B B5 +# MM MM MM ** MM: letzte 3 Stellen der MAC, ** scheinbar eine Checksumme basierend auf den 6 zufaelligen Bytes von Init1 +# Init2 (vom Server): +# 5a a5 00 02|05 01|f9 5b b5 +# Antwort auf Init2 von Dose: +# 5A A5 00 12|07 01 0A C0 32 23 62 8A 7E 00 01 06 AC CF 23 62 8A 7E|5F 5B B5 +# MM MM MM MM: letzte 3 Stellen der MAC +# MM MM MM MM MM MM MM: komplette MAC +# 5A A5 00 12|07 01 0A C0 32 23 62 8A 7E 00 02 05 00 01 01 08 11|4C 5B B5 Anzahl Bytes stimmt nicht! ist aber immer so +# 5A A5 00 15|90 01 0A E0 32 23 62 8A 7E 00 00 00 81 11 00 00 01 00 00 00 00|32 5B B5 Status der Dose (wird auch immer bei Zustandsaenderung geschickt) +# MM MM MM MM: letzte 3 Stellen der MAC +# qq qq: Schaltquelle 81=lokal geschaltet, 11=remote geschaltet +# oo oo: Schaltzustand ff=an, 00=aus +# Danach kommt alle x Sekunden ein Heartbeat von der Dose: +# 5A A5 00 09|04 01 0A C0 32 23 62 8A 7E|71 5B B5 +# MM MM MM +# Antwort vom Server (wenn die nicht kommt blinkt Dose wieder und muss neu initialisiert werden): +# 5a a5 00 01|06|f9 5b b5 +#--------------------------------------------------------------------------------------------------------- +# Einschalten der Dose: +# 5a a5 00 17|10 01 01 0a e0 32 23 62 8a 7e ff fe 00 00 10 11 00 00 01 00 00 00 ff|26 5b b5 +# MM MM MM +# Ausschalten der Dose +# 5a a5 00 17|10 01 01 0a e0 32 23 62 8a 7e ff fe 00 00 10 11 00 00 01 00 00 00 00|25 5b b5 +# MM MM MM +# beides wird quittiert (ebenso wird auch bei lokaler betaetigung quittiert) -> siehe 3. Antwort auf Init 2 +package main; +use strict; +use warnings; +use SetExtensions; +use TcpServerUtils; + +use constant { PREFIX => pack('C*', (0x5a,0xa5)), + POSTFIX => pack('C*', (0x5b,0xb5)), + INIT1A => pack('C*', (0x02,0x05,0x0d,0x07,0x05,0x07,0x12)), }; + +my $prefix = pack('C*', (0x5a,0xa5)); +my $postfix = pack('C*', (0x5b,0xb5)); + +my $init1a = pack('C*', (0x02,0x05,0x0d,0x07,0x05,0x07,0x12)); +my $init1b = pack('C*', (0x02)); +my $init2 = pack('C*', (0x05,0x01)); +my $hbeat = pack('C*', (0x06)); +my $switch1 = pack('C*', (0x10,0x01,0x01,0x0a,0xe0,0x32,0x23)); +my $switch2 = pack('C*', (0xff,0xfe,0x00,0x00,0x10,0x11,0x00,0x00,0x01,0x00,0x00,0x00)); + +my $dosehb = pack('C*', (0x00,0x09,0x04,0x01,0x0A,0xC0,0x32,0x23)); +my $cinit1 = pack('C*', (0x03,0x01,0x0a,0xc0,0x32,0x23)); +my $cmac = pack('C*', (0x07,0x01,0x0a,0xc0,0x32,0x23)); +my $cswitch = pack('C*', (0x90,0x01,0x0a,0xe0,0x32,0x23)); + +my $timeout = 60; + +##################################### +sub GHoma_Initialize($) { # + my ($hash) = @_; + + $hash->{SetFn} = "GHoma_Set"; # evtl. noch in define rein!!! + $hash->{DefFn} = "GHoma_Define"; + $hash->{ReadFn} = "GHoma_Read"; # wird von der globalen loop aufgerufen (ueber $hash->{FD} gefunden), wenn Daten verfuegbar sind + $hash->{UndefFn} = "GHoma_Undef"; + $hash->{AttrFn} = "GHoma_Attr"; + $hash->{StateFn} = "GHoma_State"; + $hash->{AttrList} = "restoreOnStartup:last,on,off restoreOnReinit:last,on,off blocklocal:yes,no ". + "allowfrom connectTimeout connectInterval"; + $hash->{noAutocreatedFilelog} = 1; # kein Filelog bei Autocreate anlegen + $hash->{ShutdownFn} = "GHoma_Shutdown"; +} +##################################### +sub GHoma_ClientConnect($) { # im Mom unnuetz + my ($hash) = @_; + my $name = $hash->{NAME}; + $hash->{DEF} =~ m/^(IPV6:)?(.*):(\d+)$/; + my ($isIPv6, $server, $port) = ($1, $2, $3); + + Log3 $name, 4, "$name: Connecting to $server:$port..."; + my @opts = ( + PeerAddr => "$server:$port", + Timeout => AttrVal($name, "connectTimeout", 60), + ); + + my $client; + if($hash->{SSL}) { + $client = IO::Socket::SSL->new(@opts); + } else { + $client = IO::Socket::INET->new(@opts); + } + if($client) { + $hash->{FD} = $client->fileno(); + $hash->{CD} = $client; # sysread / close won't work on fileno + $hash->{BUF} = ""; + $hash->{CONNECTS}++; + $selectlist{$name} = $hash; + $hash->{STATE} = "Connected"; + RemoveInternalTimer($hash); + Log3 $name, 3, "$name: connected to $server:$port"; + syswrite($hash->{CD}, ( GHoma_BuildString($init1a) . GHoma_BuildString($init1b) ) ); + InternalTimer(gettimeofday()+ $timeout + 30, "GHoma_Timer", $hash,0); + } else { + GHoma_ClientDisconnect($hash, 1); + } +} +##################################### +sub GHoma_ClientDisconnect($$) { # im Mom unnuetz + my ($hash, $connect) = @_; + my $name = $hash->{NAME}; + close($hash->{CD}) if($hash->{CD}); + delete($hash->{FD}); + delete($hash->{CD}); + delete($selectlist{$name}); + $hash->{STATE} = "Offline"; + InternalTimer(gettimeofday()+AttrVal($name, "connectInterval", 60), + "GHoma_ClientConnect", $hash, 0); + if($connect) { + Log3 $name, 4, "$name: Connect failed."; + } else { + Log3 $name, 3, "$name: Offline"; + } +} +##################################### +sub GHoma_Shutdown($) { # + my ($hash) = @_; + return unless defined $hash->{Id}; + # state auf letzten Schaltwert setzen oder auf fixen Startwert (wird bereitsbeim Shutdown ausgefuehrt) + if (AttrVal($hash->{NAME},"restoreOnStartup","last") eq "on") { + readingsSingleUpdate($hash, "state", "on", 1); + } elsif (AttrVal($hash->{NAME},"restoreOnStartup","last") eq "last" && defined $hash->{LASTSTATE} && $hash->{LASTSTATE} eq "on" ) { + readingsSingleUpdate($hash, "state", "on", 1); + } else { + readingsSingleUpdate($hash, "state", "off", 1); + } + return undef; +} +##################################### +sub GHoma_Define($$$) { # + my ($hash, $def) = @_; + + my @a = split("[ \t][ \t]*", $def); + my ($name, $type, $pport, $global) = split("[ \t]+", $def); + + my $port = $pport; + $port =~ s/^IPV6://; + + my $isServer = 1 if(defined($port) && $port =~ m/^\d+$/); + my $isClient = 1 if($port && $port =~ m/^(.+):\d+$/); + my $isSerCli = 1 if(defined($port) && $port =~ m/^([\da-f]{6})$/i); + + #return "Usage: define GHoma { [IPV6:]| }" if(!($isServer || $isClient || $isSerCli)); + return "Usage: define GHoma { [IPV6:] }" if(!($isServer || $isClient || $isSerCli)); + + $hash->{DeviceName} = $pport; + + if($isSerCli) { #ServerClient + my $name = $a[0]; + my $addr = $a[2]; + $hash->{Id} = pack('C*', ( hex(substr($addr,0,2)), hex(substr($addr,2,2)), hex(substr($addr,4,2)) ) ); + return; + } + + # Make sure that fhem only runs once + if($isServer) { + my $ret = TcpServer_Open($hash, $pport, "global"); + if($ret && !$init_done) { + Log3 $name, 1, "$ret. Exiting."; + exit(1); + } + return $ret; + } + + if($isClient) { + $hash->{isClient} = 1; + GHoma_ClientConnect($hash); + } + return; +} +##################################### +sub GHoma_BuildString($) { # Botschaft zum senden erzeugen + my ($data) = @_; + my $count = pack('n*', length($data)); + my $checksum = pack ('C*', 0xFF - (unpack("%8c*", $data)) ); + + #(my $smsg = ($prefix . $count . $data . $checksum . $postfix)) =~ s/(.|\n)/sprintf("%.2X ",ord($1))/eg; + #Log3 undef, 1, "GHoma TX: $smsg"; + + return $prefix . $count . $data . $checksum . $postfix; +} # +##################################### +sub GHoma_moveclient($$) { # Handles von temporaerem Client zu Statischem uebertragen und Temporaeren dann loeschen + my ($thash, $chash) = @_; + + if(defined($chash->{CD})) { # alte Verbindung entfernen, falls noch offen + close($chash->{CD}); + delete($chash->{CD}); + #delete($selectlist{$chash->{NAME}}); + delete($chash->{FD}); # Avoid Read->Close->Write + } + $chash->{FD} = $thash->{FD}; + $chash->{CD} = $thash->{CD}; + $chash->{SNAME} = $thash->{SNAME}; + my @client = split(":",$thash->{NAME}); + $chash->{IP} = $client[1]; + $chash->{PORT} = $client[2]; + $selectlist{$chash->{NAME}} = $chash; + readingsSingleUpdate($chash, "state", "Initialize...", 1); + delete($selectlist{$thash->{NAME}}); + delete $thash->{FD}; + CommandDelete(undef, $thash->{NAME}); + syswrite( $chash->{CD}, GHoma_BuildString($init2) ); + InternalTimer(gettimeofday()+ $timeout, "GHoma_Timer", $chash,0); +} +##################################### +sub GHoma_Read($) { # wird von der globalen loop aufgerufen (ueber $hash->{FD} gefunden), wenn Daten verfuegbar sind + my ($hash) = @_; + my $name = $hash->{NAME}; + if($hash->{SERVERSOCKET}) { # Accept and create a child + my $chash = TcpServer_Accept($hash, "GHoma"); + return if(!$chash); + Log3 $name, 4, "$name: angelegt: $chash->{NAME}"; + syswrite($chash->{CD}, ( GHoma_BuildString($init1a) . GHoma_BuildString($init1b) ) ); + InternalTimer(gettimeofday()+ $timeout, "GHoma_Timer", $chash,0); + $chash->{CD}->flush(); + return; + } + + my $buf; + my $ret = sysread($hash->{CD}, $buf, 256); + if(!defined($ret)) { + if($hash->{isClient}) { + Log3 $name, 1, "$name \$buf nicht definiert"; + GHoma_ClientDisconnect($hash, 0); + } else { + CommandDelete(undef, $name); + } + return; + } + + if ( substr($buf,0,10) eq ($prefix . $dosehb )) { # Heartbeat + #DevIo_SimpleWrite($hash, GHoma_BuildString($hbeat) , undef); + RemoveInternalTimer($hash); + $buf =~ s/(.|\n)/sprintf("%.2X ",ord($1))/eg; #empfangene Zeichen in Hexwerte wandeln + Log3 $name, 5, "$name empfangen: $buf"; + syswrite( $hash->{CD}, GHoma_BuildString($hbeat) ); + Log3 $hash, 5, "$hash->{NAME} Heartbeat gesendet"; + InternalTimer(gettimeofday()+ $timeout, "GHoma_Timer", $hash,0); + } else { # alles ausser Heartbeat + my @msg = split(/$prefix/,$buf); + foreach (@msg) { + next if ( $_ eq "" ); + if ( hex(unpack('H*', substr($_,length($_)-2,2))) != hex(unpack('H*', $postfix ))) { # Check Postfix + Log3 $hash, 1, "$hash->{NAME} Fehler: postfix = " . unpack('H*', substr($_,length($_)-2,2)); + next; + } + if ( hex(unpack('H*', substr($_,length($_)-3,1))) != ( 0xFF - unpack("%8c*", substr($_,2,length($_)-5) ) ) ) { # Check Checksum + Log3 $hash, 1, "$hash->{NAME} Fehler: Checksum soll = " . hex(unpack('H*', substr($_,length($_)-3,1))) . " ist = ". ( 0xFF - unpack("%8c*", substr($_,2,length($_)-5) ) ); + next; + } + if ( hex(unpack('H*', substr($_,0,2))) != ( length($_) - 5 ) ) { # Check Laenge + Log3 $hash, 4, "$hash->{NAME} laengesoll = " . hex(unpack('H*', substr($_,0,2))) . " laengeist = " . ( length($_) - 5 ) + } + + (my $smsg = $_) =~ s/(.|\n)/sprintf("%.2X ",ord($1))/eg; # empfangene Zeichen in Hexwerte wandeln + Log3 $hash, 5, "$hash->{NAME} RX: 5A A5 $smsg"; # ...und ins Log schreiben + + if ( substr($_,2,6) eq ($cinit1)) { # Antwort auf erstes Init + $hash->{Id} = substr($_,8,3); + unless ($hash->{isClient}) { + # fuer Server Loesung bei erster Antwort von Dose nach bestehendem Devicem it gleicher Id suchen und Verbindung auf dieses Modul uebertragen + my $clientdefined = undef; + foreach my $dev (devspec2array("TYPE=$hash->{TYPE}")) { # bereits bestehendes define mit dieser Id suchen + if ($hash->{Id} eq InternalVal($dev,"Id","") && $hash->{NAME} ne $dev && InternalVal($dev,"TEMPORARY","") ne "1") { + #Log3 $hash, 5, "$hash->{NAME}: $dev passt -> Handles uebertragen"; + GHoma_moveclient($hash, $defs{$dev}); + $clientdefined = 1; + last + } + } + unless ( defined $clientdefined) { # ...ein Neues anlegen, falls keins existiert + my $id = unpack('H*', $hash->{Id} ); + Log3 $name, 4, "GHoma Unknown device $id, please define it"; + DoTrigger("global", "UNDEFINED GHoma_$id GHoma $id"); + GHoma_moveclient($hash, $defs{"GHoma_$id"}) if ($defs{"GHoma_$id"}); + } + } else { + readingsSingleUpdate($hash, "state", "Initialize...", 1); + syswrite( $hash->{CD}, GHoma_BuildString($init2) ); + RemoveInternalTimer($hash); + InternalTimer(gettimeofday()+ $timeout, "GHoma_Timer", $hash,0); + } + } elsif ( substr($_,2,6) eq $cmac && substr($_,8,3) eq substr($_,17,3) ) { # Nachricht mit MAC (kommt unter Anderem als Antwort auf Init2) + my $mac; + for my $i (0...5) { # MAC formattieren + $mac .= sprintf("%.2X",ord( substr($_,14+$i,1) )); + last if $i == 5; + $mac .= ":"; + } + $hash->{MAC} = $mac; + } elsif ( substr($_,2,6) eq $cswitch && (( length($_) - 5 ) == 0x15 ) ) { # An oder Aus + my $id = unpack('H*', substr($_,8,3) ); + my $rstate = hex(unpack('H*', substr($_,22,1))) == 0xFF ? "on" : "off"; + my $src = hex(unpack('H*', substr($_,14,1))) == 0x81 ? "local" : "remote"; + if ( defined $hash->{LASTSTATE} && $hash->{STATE} eq "Initialize..." ) { # wenn dies erste Statusbotschaft nach Anmeldung + my $nstate = AttrVal($name, "restoreOnReinit", "last"); + if ( $nstate ne "last" && $nstate ne $rstate ) { + GHoma_Set( $hash, $hash->{NAME}, $nstate ); + } elsif ($nstate eq "last" && $hash->{LASTSTATE} ne $rstate) { + GHoma_Set( $hash, $hash->{NAME}, $hash->{LASTSTATE} ); + } + } elsif ($src eq "local") { # bei schalten direkt an Steckdose soll... + if (AttrVal($name, "blocklocal", "no") eq "yes") { # ...wieder zurueckgeschaltet werden, wenn Attribut blocklocal yes ist + GHoma_Set($hash, $hash->{NAME}, $hash->{LASTSTATE}); + } else { # ...laststate angepasst werden (um bei reinit richtigen wert zu haben) + $hash->{LASTSTATE} = $rstate; + } + } + + if (defined $hash->{SNAME} && defined $defs{$hash->{SNAME}} ) { # Readings auch im Server eintragen + readingsBeginUpdate($defs{$hash->{SNAME}}); + readingsBulkUpdate($defs{$hash->{SNAME}}, $id .'_state', $rstate); + readingsBulkUpdate($defs{$hash->{SNAME}}, $id .'_source', $src); + readingsEndUpdate($defs{$hash->{SNAME}}, 1); + } + + readingsBeginUpdate($hash); + readingsBulkUpdate($hash, 'state', $rstate); + readingsBulkUpdate($hash, 'source', $src); + readingsEndUpdate($hash, 1); + } + } + } + #Log3 $name, 5, "$name empfangen: $buf"; + return +} +##################################### +sub GHoma_Timer($) { # wird ausgeloest wenn heartbeat nicht mehr kommt + my ($hash) = @_; + Log3 $hash, 3, "$hash->{NAME}: Timer abgelaufen"; + readingsSingleUpdate($hash, "state", "offline", 1); + GHoma_ClientDisconnect($hash, 0) if $hash->{isClient}; + return TcpServer_Close($hash) if defined $hash->{FD}; + #DevIo_Disconnected($hash); +} +##################################### +sub GHoma_Attr(@) { # + my @a = @_; + my $hash = $defs{$a[1]}; + + # if($a[0] eq "set" && $a[2] eq "SSL") { + # TcpServer_SetSSL($hash); + # if($hash->{CD}) { + # my $ret = IO::Socket::SSL->start_SSL($hash->{CD}); + # Log3 $a[1], 1, "$hash->{NAME} start_SSL: $ret" if($ret); + # } + # } + + return undef; +} +##################################### +sub GHoma_Set($@) { # + my ($hash, @a) = @_; + return undef unless defined $hash->{Id}; # set fuer den Server ausblenden + my $name = $a[0]; + my $type = $a[1]; + my @sets = ('on:noArg', 'off:noArg'); + + my $status = ReadingsVal($hash->{NAME},"state",""); + + if($type eq "on") { + $type = pack('C*', (0xff)); + readingsSingleUpdate($hash, "state", "set_on", 1) if ( $status =~ m/([set_]?o[n|ff])$/i ); + $hash->{LASTSTATE} = "on"; + } elsif($type eq "off") { + $type = pack('C*', (0x00)); + readingsSingleUpdate($hash, "state", "set_off", 1) if ( $status =~ m/([set_]?o[n|ff])$/i ); + $hash->{LASTSTATE} = "off"; + } else { + my $slist = join(' ', @sets); + return SetExtensions($hash, $slist, @a); + } + if (defined $hash->{CD}) { + syswrite( $hash->{CD}, GHoma_BuildString($switch1 . $hash->{Id} . $switch2 . $type) ); + } + return undef; +} +##################################### +sub GHoma_State($$$$) { # reload readings at FHEM start + my ($hash, $tim, $sname, $sval) = @_; + Log3 $hash, 4, "$hash->{NAME}: $sname kann auf $sval wiederhergestellt werden $tim"; + if ( $sname eq "state" && defined $hash->{Id} ) { + $hash->{LASTSTATE} = $sval; + readingsSingleUpdate($hash, "state", "offline", 1) + } + return; +} +##################################### +sub GHoma_Undef($$) { # + my ($hash, $arg) = @_; + RemoveInternalTimer($hash); + return TcpServer_Close($hash) if defined $hash->{FD}; +} +##################################### + + +1; + +=pod +=begin html + + +

GHoma

+(en | de) +
    +
      + Connects fhem to an G-Homa adapter plug

      + preliminary:
      +
    • Configure WLAN settings:
      + bring device in AP mode (press button for more than 3s, repeat this step until the LED is permanently on)
      + Now connect with your computer to G-Home network.
      + Browse to 10.10.100.254 (username:password = admin:admin)
      + In STA Setting insert your WLAN settings
      +
    • +
    • Configure Network Parameters setting:
      + Other Setting -> Protocol to TCP-Client
      + Other Setting -> Port ID (remember value for FHEM settings)
      + Other Setting -> Server Address (IP of your FHEM Server)
      +
    • +
    • Optional:
      + Block all outgoing connections for G-Homa in your router.
      +
    • +
    +

    + + + Define
    +
      + define <name> GHoma <port>
      + Specifies the GHoma server device.
      + New adapters will be added automaticaly after first connection.
      + You can also manyally add an adapter:
      + define <name> GHoma <Id>
      + where Id is the last 6 numbers of the plug's MAC address
      + Example: MAC= AC:CF:23:A5:E2:3B -> Id= A5E23B
      +
      +
    + + Set +
      + set <name> <value> +

      + where value is one of:
      +
        + off
        + on
        +
        +
      + The set extensions are also supported.
      +
      +
    + + + Attributes
    +
      + For plug devices: +
      • restoreOnStartup
        + Restore switch state after reboot
        + Default: last, valid values: last, on, off

        +
      • +
      • restoreOnReinit
        + Restore switch state after reconnect
        + Default: last, valid values: last, on, off

        +
      • +
      • blocklocal
        + Restore switch state to reading state immideately after local switching
        + Default: no, valid values: no, yes

        +
      + For server devices: +
      • allowfrom
        + Regexp of allowed ip-addresses or hostnames. If set, + only connections from these addresses are allowed.

        +
      +
    • readingFnAttributes
    • +
    +
    +
+ +=end html + +=begin html_DE + + +

GHoma

+(en | de) +
    +
      + Verbindet fhem mit einem G-Homa Zwischenstecker

      + Vorbereitung:
      +
    • WLAN konfigurieren:
      + Gerät in den AP modus bringen (Knopf für mehr als 3s drücken, diesen Schritt wiederholen bis die LED permanent leuchtet)
      + Nun einen Computer mit der SSID G-Home verbinden.
      + Im Browser zu 10.10.100.254 (username:passwort = admin:admin)
      + In STA Setting WLAN Einstellungen eintragen
      +
    • +
    • Network Parameters settings:
      + Other Setting -> Protocol auf TCP-Server
      + Other Setting -> Port ID (wird später für FHEM benötigt)
      + Other Setting -> Server Address (IP Adresse des FHEM Servers)
      +
    • +
    • Optional:
      + Im Router alle ausgehenden Verbindungen für G-Homa blockieren.
      +
    • +
    +

    + + + Define
    +
      + define <name> GHoma <port>
      + Legt ein GHoma Server device an.
      + Neue Zwischenstecker werden beim ersten verbinden automatisch angelegt.
      + Diese können aber auch manuell angelegt werden:
      + define <name> GHoma <Id>
      + Die Id besteht aus den letzten 6 Stellen der MAC Adresse des Zwischensteckers.
      + Beispiel: MAC= AC:CF:23:A5:E2:3B -> Id= A5E23B
      +
      +
    + + Set +
      + set <name> <value> +

      + Gültige Werte für value:
      +
        + off
        + on
        +
        +
      + Die set extensions werden auch unterstützt.
      +
      +
    + + + + + Attributes
    +
      + Für Zwischenstecker devices: +
      • restoreOnStartup
        + Wiederherstellen der Portzustände nach Neustart
        + Standard: last, gültige Werte: last, on, off

        +
      • +
      • restoreOnReinit
        + Wiederherstellen der Portzustände nach Neustart
        + Standard: last, gültige Werte: last, on, off

        +
      • +
      • blocklocal
        + Wert im Reading State sofort nach Änderung über lokale Taste wiederherstellen
        + Standard: no, gültige Werte: no, yes

        +
      + Für Server devices: +
      • allowfrom
        + Regexp der erlaubten IP-Adressen oder Hostnamen. Wenn dieses Attribut + gesetzt wurde, werden ausschließlich Verbindungen von diesen + Adressen akzeptiert.

        +
      +
    • readingFnAttributes
    • +
    +
    +
+ +=end html_DE + +=cut \ No newline at end of file diff --git a/fhem/MAINTAINER.txt b/fhem/MAINTAINER.txt index e11550b38..bfe716bba 100644 --- a/fhem/MAINTAINER.txt +++ b/fhem/MAINTAINER.txt @@ -186,6 +186,7 @@ FHEM/52_I2C_PCA9532 klausw http://forum.fhem.de Sonstige FHEM/52_I2C_PCF8574 klausw http://forum.fhem.de Sonstige Systeme FHEM/52_I2C_SHT21 klausw http://forum.fhem.de Sonstige Systeme FHEM/52_I2C_TSL2561 kaihs http://forum.fhem.de Sonstige Systeme +FHEM/53_GHoma.pm klausw http://forum.fhem.de Sonstige Systeme FHEM/55_GDS.pm betateilchen http://forum.fhem.de Unterstuetzende Dienste FHEM/55_InfoPanel.pm betateilchen http://forum.fhem.de Unterstuetzende Dienste FHEM/55_PIFACE.pm klaus.schauer http://forum.fhem.de Einplatinencomputer