From 7b7c5b99ec7f2c4b6bd92c90ab18b77d76a5be5a Mon Sep 17 00:00:00 2001 From: Phill Date: Fri, 2 Mar 2018 18:55:02 +0000 Subject: [PATCH] 39_Talk2Fhem.pm: Update 0.4.5 bugfixes commandref update (#84992) git-svn-id: https://svn.fhem.de/fhem/trunk@16314 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/39_Talk2Fhem.pm | 291 ++++++++++++++++++++++++-------------- 1 file changed, 188 insertions(+), 103 deletions(-) diff --git a/fhem/FHEM/39_Talk2Fhem.pm b/fhem/FHEM/39_Talk2Fhem.pm index b712987bf..c90d26b72 100644 --- a/fhem/FHEM/39_Talk2Fhem.pm +++ b/fhem/FHEM/39_Talk2Fhem.pm @@ -89,14 +89,26 @@ # 21.02.2018 0.4.4 # bracket extraction bug fixed # def not load at bootup fixed +# 03.03.2018 0.4.5 +# timephrase modified +# recognize order in hash replacement +# Commandref fix unwanted characters +# possibility of nested brackets in modifiacator +# stabitility fixes in user regexp +# replace ; to ;; in timecommands +# Add 1 day if timecode is in past in hour phrases +# Added async warning if keywordlist is unkown ################################################################ # TODO: # # device verundung durch regexp klammern? eher durch try and error -# get compare lists # answerx +# # klammern in keywordlists sollen die $n nummerierung nicht beeinflussen -# +# in keywordlists sind vermutlich nur maximal eine klammerebene möglich direkte regex arrays sind endlos verschachtelbar +# zusätzlich unmodifizierte zeit greifbar machen +# timephrase kombies morgen früh um 9 uhr ist unzuverlässig. evtl order einführen, dann kann auch die splittung weg +# viertel zeitphrasen package main; @@ -111,7 +123,7 @@ use Encode qw(decode encode); my %Talk2Fhem_globals; -$Talk2Fhem_globals{version}="0.4.4"; +$Talk2Fhem_globals{version}="0.4.5"; $Talk2Fhem_globals{EN}{erase} = ['\bplease\b', '\balso\b', '^msgtext:']; $Talk2Fhem_globals{EN}{numbers} = { @@ -225,7 +237,7 @@ $Talk2Fhem_globals{DE}{pass} = { empty => '^\s*$' }; $Talk2Fhem_globals{DE}{datephrase} = { - '(? {days=>1} + 'morgen'=> {days=>1} , 'übermorgen'=> {days=>2} , 'gestern'=> {days=>-1} , 'vorgestern'=> {days=>-2} @@ -245,6 +257,7 @@ $Talk2Fhem_globals{DE}{datephrase} = { , 'in ('.$Talk2Fhem_globals{DE}{numberre}.') tag(\S\S)?'=> {days=>'"$1"'} , 'am (\d\S*(\s\d+)?)'=> {date=>'"$1"'} }; +# fc modify time. $_[0] = ermittelte zeit. Zugriff auf $1 $2 usw $Talk2Fhem_globals{DE}{timephrase} = { '(in|und|nach)? ('.$Talk2Fhem_globals{DE}{numberre}.') stunde.?' => {hour=>'"$2"'} , '(in|und|nach)? ('.$Talk2Fhem_globals{DE}{numberre}.') minute.?' => {min=>'"$2"'} @@ -254,10 +267,17 @@ $Talk2Fhem_globals{DE}{timephrase} = { , 'später' => {hour=>1} , 'jetzt' => {unix=>'time'} , 'sofort' => {unix=>'time'} -, 'um ('.$Talk2Fhem_globals{DE}{numberre}.') (uhr)?' => {time=>'"$1"'} -, 'um ('.$Talk2Fhem_globals{DE}{numberre}.') uhr ('.$Talk2Fhem_globals{DE}{numberre}.')' => {hour=>'"$1"', min=>'"$1"'} ############ ZU TESTEN +, 'um (\d+\s?\:\s?\d+|'.$Talk2Fhem_globals{DE}{numberre}.') (uhr)?' => { + time=>'"$1"', + fc=>sub () {(($_[0] + 3600) < time) ? ($_[0]+3600*24) : $_[0] } + } +, 'um ('.$Talk2Fhem_globals{DE}{numberre}.') uhr ('.$Talk2Fhem_globals{DE}{numberre}.')' => { + hour=>'"$1"', + min=>'"$1"', + fc=>sub () {(($_[0] + 3600) < time) ? ($_[0]+3600*24) : $_[0] } + } ############ ZU TESTEN , 'früh' => {time=>'"09:00"'} -, '(? {time=>'"18:00"'} +, 'abends?' => {time=>'"18:00"'} , 'nachmittags?' => {time=>'"16:00"'} , 'vormittags?' => {time=>'"10:30"'} , 'mittags?' => {time=>'"12:00"'} @@ -314,7 +334,7 @@ sub Talk2Fhem_Define($$) $hash->{STATE} = "Loading"; if ($def =~ /^\S+ Talk2Fhem$/) { - $hash->{DEF} = ""; + $hash->{DEF} = "# = \n# Examples:\n# timer (löschen|zurück)\t= set \$NAME cleartimers\n# ereignis\\S* (löschen|zurück)\t= set \$NAME cleartriggers"; return; } @@ -432,7 +452,9 @@ sub Talk2Fhem_Loadphrase($$$) { if ($1) { $keylistname = $2; unless ($keylist{$keylistname}) { - return(T2FL($hash, 1, "Unkown keywordlist $1. In phrase: $phr")); + asyncOutput($hash->{CL}, "Warning: Unkown keywordlist $1. In phrase: $phr"); + next; + #return(T2FL($hash, 1, "Unkown keywordlist $1. In phrase: $phr")); } my $re = join("|", @{$keylist{$keylistname}}); $phr =~ s/@(\w+)/$re/; @@ -568,7 +590,7 @@ sub Talk2Fhem_Set($@) #Ausführen if ($res{cmds}) { for my $h (@{$res{cmds}}) { - my $fhemcmd = ($$h{at}?Talk2Fhem_mkattime($name, $$h{at})." ":"").$$h{cmd}; + my $fhemcmd = ($$h{at}?Talk2Fhem_mkattime($name, $$h{at})." ":"").($$h{cmd} =~ s/;/;;/gr ); unless ($$h{ifs}) { # kein IF @@ -814,7 +836,7 @@ sub Talk2Fhem_normalize($) my $string = shift; #mach probleme bei "ue" # $string =~ s/\s{2,}|\b\w\b|\t|\n|['".,;:\!\?]/ /g; - $string =~ s/\s{2,}|\t|\n|['".,;:\!\?]/ /g; + $string =~ s/\s{2,}|\t|\n|['".,;\!\?]/ /g; return $string; } @@ -949,8 +971,20 @@ $txt =~ s/$origin//; $origin = $&; $txt = Talk2Fhem_normalize(Talk2Fhem_realtrim($txt)); readingsSingleUpdate($me, "origin", $origin, 1); + +#:START #Zeiten könnten auch ein und enthalten deswegen nicht wenn auf und eine Zahl folgt my @cmds = split(/ und (?!$Talk2Fhem_globals{DE}{numberre})/, $txt); +# CHECK if $cmd[0] hit Talk2Fhem_test. Unless dont split. And make a deeper analysis. +#if ($#cmd) +# before test remove time and if phrases simple +# unless (Talk2Fhem_test($me, $cmds[0])) { +# Nun schauen wir mal was vor und nach dem und ist. +# könnte phrasentreffer auf kompletten satz ausschluss geben +# +# } +#} + foreach (@cmds) { @@ -1030,7 +1064,7 @@ if (%lastcmd and } #wieder wird nicht mehr benötigt $cmd =~ s/\bwieder\b|^(dann|danach) / /g; -$cmd = Talk2Fhem_filter($myname, $cmd); +$cmd = Talk2Fhem_normalize(Talk2Fhem_realtrim(Talk2Fhem_filter($myname, $cmd))); T2FL($myname, 4, "Command left: '$cmd'") if $rawcmd ne $cmd; @@ -1092,6 +1126,7 @@ my $disu = AttrVal($myname, "T2F_disableumlautescaping", 0); my %tf = %{$tp{$key}}; T2FL($myname, 4, "Timephrase found: =~ s/\\b$key\\b/"); foreach my $datemod (keys(%tf)) { + next if $datemod eq "fc"; # Suche Ersetzungsvariablen my $dmstore = $tf{$datemod}; while ($tf{$datemod} =~ /\$(\d+)/) { @@ -1123,7 +1158,7 @@ my $disu = AttrVal($myname, "T2F_disableumlautescaping", 0); } elsif ($datemod eq "hour") { $evt = POSIX::mktime($now[0],$now[1],($now[2]+$tf{hour}),$lt[3],$lt[4],$lt[5]) || 0; } elsif ($datemod eq "time") { - my @t = split(":", $tf{time}); + my @t = map { s/\s//gr } split(":", $tf{time}); $evt = POSIX::mktime($t[2] || 0,$t[1] || 0,$t[0],$lt[3],$lt[4],$lt[5]) || 0; } elsif ($datemod eq "date") { my @t = split(/\.|\s/, $tf{date}); @@ -1137,6 +1172,14 @@ my $disu = AttrVal($myname, "T2F_disableumlautescaping", 0); } @lt = localtime($evt); } + + if ($tp{$key}{fc}) { + if (ref $tp{$key}{fc} eq "CODE") { + my $lock = $evt; + $evt = &{$tp{$key}{fc}}($evt); + T2FL($myname, 4, "Time modified by function. ".$evt) if $lock != $evt; + } + } } return($evt); } @@ -1174,7 +1217,7 @@ T2FL($myname, 5, "$myname Evaluate search:\n$cmd =~ /$$phr{key}/i") if ref $res; for my $fphr (@fphrs) { # if (my @d = ($cmd =~ qr/$fphr/i)){ if ($fphr =~ s/^\?//){ - my @d = ($cmd =~ /$fphr/i); + my @d = (eval { $cmd =~ /$fphr/i}); my $m = $&; #Log 1, "A: ".$fphr; #Log 1, "A: ".Dumper $m; @@ -1195,8 +1238,8 @@ for my $fphr (@fphrs) { $punmatch =~ s/$m//gi; #$cmd =~ s/$m//gi; } elsif ($fphr =~ /^\!/) { - return if ($cmd =~ /$'/i); - } elsif (my @d = ($cmd =~ /$fphr/i)){ + return if (eval { $cmd =~ /$'/i }); + } elsif (my @d = (eval { $cmd =~ /$fphr/i } )){ my $m = $&; $pmatch .= $m; $punmatch =~ s/$m//gi; @@ -1293,11 +1336,25 @@ my %react; T2FL($myname, 4, "Replaced bracket: $raw -> $do") if $raw ne $do; - while ($do =~ s/(.*)\$(\d+)(\[|\{|\()(.*?)(\]|\}|\))/$1###/) { - #Klammer aus Value in Hash überführen +# while ($do =~ s/(.*)\$(\d+)(\[|\{|\()(.*?)(?3)/$1###/) { +# while ($do =~ s/(.*)\$(\d+)(\[|\{|\()(.*?)(\]|\}|\))/$1###/) { + while ($do =~ /(.*)\$(\d+)(?=\[|\{|\()/) { + my $pre = $1; my $clipno = $2; - my $uhash = $4; - my $utype = $3; + my $post = $'; + + my ($found, $rest) = extract_bracketed( $post, '{}[]()' ); + unless ($found) { + Talk2Fhem_err($myname, T2FL($myname, 1, "'$raw': Fehler in Kommandoteilmodifikator Nr. '\$$clipno' nach: '$pre'"),$res,1); + return(0); + } + #Klammer aus Value in Hash überführen + $do = $pre."###".$rest; + $found =~ /(.)(.*)./; + my $utype = $1; + my $uhash = $2; + + T2FL($myname, 4, "Advanced bracket replacement. \$$clipno$uhash = $do"); if ($uhash =~ /@(\w+)/) { if ($modlist{$1}) { @@ -1319,10 +1376,11 @@ my %react; $hash = Talk2Fhem_parseArray($uhash) } elsif ($utype eq "{") { #$hash = eval($uhash) - my $harr = Talk2Fhem_parseArray($uhash); + my $harr = Talk2Fhem_parseArray($uhash); my $i=0; for (@$harr) { my $h = Talk2Fhem_parseArray($_, "=>"); - $$hash{$$h[0]} = $$h[1]; + $$hash{$$h[0]} = {val=>$$h[1],order=>$i++}; + } } elsif ($utype eq "(") { ##### klappt nicht weil in while regex nicht bis zur schließenden klammer getriggert wird wenn vorher ein } oder ] kommt @@ -1348,9 +1406,9 @@ my %react; if (ref($hash) eq "HASH") { T2FL($myname, 5, "HASH evaluation:\n".Dumper($hash)); #my $passed=0; - foreach my $h (keys(%$hash)) { + foreach my $h (sort {$$hash{$a}{order} <=> $$hash{$b}{order} } keys(%$hash)) { #sollte eigentlich in den syntaxcheck - unless (defined $$hash{$h}) { + unless (defined $$hash{$h}{val}) { T2FL($myname, 1, "Empty replacementstring! $h"); #return(0); next; @@ -1381,7 +1439,7 @@ my %react; $re = Talk2Fhem_escapeumlauts($re, $disu); if ($d =~ qr/$re/i) { - my $rp = $$hash{$h}; + my $rp = $$hash{$h}{val}; if (ref $fc eq "CODE") { T2FL($myname,5,"Functionmod '$fc' $rp"); my @res = $d =~ qr/$re/i; @@ -1397,11 +1455,11 @@ my %react; } } # empty != undef -# if (defined($d) and $d =~ qr/${$Talk2Fhem{pass}}{empty}/ and ($$hash{empty} or (! $$hash{empty} and $$hash{else}))) { +# if (defined($d) and $d =~ qr/${$Talk2Fhem{pass}}{empty}/ and ($$hash{empty}{val} or (! $$hash{empty}{val} and $$hash{else}{val}))) { # empty undef if (! defined($d) or $d =~ qr/${$Talk2Fhem{pass}}{empty}/) { #$d existiert nicht - my $e = ($$hash{empty} || $$hash{else}); + my $e = ($$hash{empty}{val} || $$hash{else}{val}); T2FL($myname, 5, "Empty word replace with '$e'"); $do =~ s/###/$e/; } @@ -1410,9 +1468,9 @@ my %react; ######### if ($do =~ /###/) { #Vergleich fehlgeschlagen - if ($$hash{else}) { - T2FL($myname, 5, "Unkown word '$d' replace with '$$hash{else}'"); - $do =~ s/###/$$hash{else}/; + if ($$hash{else}{val}) { + T2FL($myname, 5, "Unkown word '$d' replace with '$$hash{else}{val}'"); + $do =~ s/###/$$hash{else}{val}/; } else { T2FL($myname, 1, "HASH Replacement Failed! $do"); #%$res = undef; @@ -1458,15 +1516,33 @@ my %react; T2FL($myname, 5, "Clipnumber $clipno is no array! Try to extract by seperator '|'"); # my @cs = map { my @t = split('\|', $_ =~ s/^\(|\)$//gr); \@t } $$phr{key} =~ /(? 10; + } + + # @keywords = @{$cs[($clipno-1)]}; - #Log 1, Dumper @cs; - @cs = grep { /^\(/ } @cs; - #Log 1, Dumper @cs; -# Log 1, "-----> ".$$phr{key}; - @keywords = split('\|', $cs[($clipno-1)] =~ s/^\(|\)$//gr); -# Log 1, Dumper @keywords; +# Log 1, Dumper @cs; +# @cs = grep { /^\(/ } @cs; +# Log 1, Dumper @cs; +# Log 1, "-----> ".$cs[($clipno-1)]; + (my $clip = $cs[($clipno)]) =~ s/^\(|\)$//g; +# push(@keywords, split('\|', $clip) extract_bracketed($clip, '()')); + @keywords = map { /^\(/ ? $_ : split('\|', $_=~s/^\||\|$//gr) } extract_multiple($clip, [sub { extract_bracketed($_[0], '()') }]); +# @keywords = split('\|',); + + #Log 1, Dumper @keywords; #wenn keine Liste in Klammer ist if ($#keywords == -1) { Talk2Fhem_err($myname, T2FL($myname, 1, "Clipnumber $clipno includes no array or integer in '$$phr{key}!"),$res,1); @@ -1475,12 +1551,13 @@ my %react; } else { @keywords = @{$keylist{$hitnokeylist[$clipno]}}; } + T2FL($myname, 4, "Searching position of $d in @keywords"); @keywords = map { Talk2Fhem_escapeumlauts($_, $disu) } @keywords; T2FL($myname, 4, "Searching position of $d in @keywords"); my $i=0; foreach (@keywords) { # if ($d =~ /^\Q$_\E$/i) { - if ($d =~ /^$_$/i) { + if (eval{$d =~ /^$_$/i}) { unless (defined($$hash[$i])) { my $err = T2FL($myname, 1, "Not enough elements in modwordlist! Position $i in (@$hash) doesn't exist."); if ($else eq "") { @@ -1628,6 +1705,10 @@ return($_[2]); The command part begins after the equals sign with a space, tab, or newline.

<regexp> = <command>

+ Short refernce: +
+ <RegExpPart> [&& [?!]<RegExpPart_n>] = [ <FHEM command> | { <Perl code> } | (<option> => '<wert>' , ... ) ] +

Example: helo world = {Log 1, Helo World}

Everything after a hashtag '#' is ignored until the end of the line. @@ -1673,7 +1754,7 @@ return($_[2]);
  • $n[<list>]
    Comma separated list: [value1,value2,...,[else,value], [empty,value]] or [@modwordlist]
    If $n is a number, the word at that position in <list> is selected.

    - If $n is a text, it searches for a list in its parenthesis in the part. (a|b|c) or (@keywordlist) + If $n is a text, it searches for a list in its parenthesis in the <regexp> part. (a|b|c) or (@keywordlist) In this list, $n is searched for and successively positioned in <list> chosen for $n.
    Example: light .* (kitchen|corridor|bad) (\S*) on = set $1[dev_a,dev_b,dev_c] $2{true => on,false => off}
  • @@ -1683,8 +1764,8 @@ return($_[2]); Environment variables::
      There are a number of variables that can be accessed in the <command>-part. -
    • $& Contains all found words
    • -
    • !$& Contains the rest that was not included by RegExp
    • +
    • $& Contains all found words
    • +
    • !$& Contains the rest that was not included by RegExp
    • $DATE Contains the time and date text of the voice
    • $AGAIN Contains the word again if it is a command again
    • $TIME Contains the found time.
    • @@ -1793,7 +1874,7 @@ return($_[2]);
    • T2F_origin
      A RegExp which is generally removed and whose output can be accessed via $0.
      - Can be used for + Can be used for user mapping.
    • T2F_languageDE|EN
      The used language can be set via the global attribute "language". Or overwritten with this attribute.
    • @@ -1814,9 +1895,9 @@ return($_[2]);

      Talk2Fhem

        - Das Modul Talk2Fhem stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her. - Die Konfiguration erfolgt dabei komfortabel über das FHEM Webfrontend.
        - Für eine genauere Beschreibung und weiterführende Beispiele siehe Talk2Fhem Wiki. + Das Modul Talk2Fhem stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her. + Die Konfiguration erfolgt dabei komfortabel über das FHEM Webfrontend.
        + Für eine genauere Beschreibung und weiterführende Beispiele siehe Talk2Fhem Wiki.

        Define @@ -1827,22 +1908,26 @@ return($_[2]);

        Die eigentliche Konfigration sollte erst auf der FHEM Seite erfolgen.

        - Die einzelnen Sprachphrasen werden Zeile für Zeile konfiguriert. Hierbei fängt eine Konfiguration - immer mit dem Regulärem Ausdruck an, gefolgt von mindestens einem Leerzeichen oder Tabulator gefolgt + Die einzelnen Sprachphrasen werden Zeile für Zeile konfiguriert. Hierbei fängt eine Konfiguration + immer mit dem Regulärem Ausdruck an, gefolgt von mindestens einem Leerzeichen oder Tabulator gefolgt von einem Gleichheitszeichen.
        - Der Kommandoteil fängt nach dem Gleichheitszeichen mit einem Leerzeichen, Tabulator oder Zeilenumbruch an.

        + Der Kommandoteil fängt nach dem Gleichheitszeichen mit einem Leerzeichen, Tabulator oder Zeilenumbruch an.

        <regexp> = <command>

        + Kurzreferenz: +
        + <RegExpPart> [&& [?!]<RegExpPart_n>] = [ <FHEM command> | { <Perl code> } | (<option> => '<wert>' , ... ) ] +

        Beispiel: hallo welt = {Log 1, Hallo Welt}

        Alles nach einem Hashtag '#' wird bis zum Zeilenende ignoriert.

        <regexp> -
          Regulärer Ausdruck der den Text beschreibt, bei dem das Kommando ausgeführt werden soll
        +
          Regulärer Ausdruck der den Text beschreibt, bei dem das Kommando ausgeführt werden soll


        <command>
          - Der ausführende Teil. Folgende Formate sind Zulässig: + Der ausführende Teil. Folgende Formate sind Zulässig:
        • FHEM Kommando
        • {Perlcode}
        • (<option> => '<wert>' , ... )
        • @@ -1850,51 +1935,51 @@ return($_[2]);
          <option>
        • cmd
          FHEM Kommando wie oben
        • offset
          Ganzzahliger Wert in Sekunden der auf den Zeitpunkt addiert wird
        • -
        • answer
          Perl Code dessen Rückgabe in das Reading answer geschrieben wird
        • +
        • answer
          Perl Code dessen Rückgabe in das Reading answer geschrieben wird

      - Klammerüberführung: + Klammerüberführung:
        - Im Regulärem Ausdruck gesetzte Klammern können in den Kommandoteil mit $1, $2, [...], $n überführt und - modifiziert werden. Folgende Modifizierungsmöglichkeiten stehen hierbei zur Verfügung. -
      • $n
        Ohne Änderung direkt das Wort überführen.
      • + Im Regulärem Ausdruck gesetzte Klammern können in den Kommandoteil mit $1, $2, [...], $n überführt und + modifiziert werden. Folgende Modifizierungsmöglichkeiten stehen hierbei zur Verfügung. +
      • $n
        Ohne Änderung direkt das Wort überführen.
      • $n{<typ> => <wert>}
        Die Typen sind:
        true, false, integer, float, numeral, /<regexp>/, word, empty, else
        true entspricht: ja|1|true|wahr|ein|eins.*|auf.*|..?ffnen|an.*|rauf.*|hoch.*|laut.*|hell.*
        false entspricht: nein|0|false|falsch|aus.*|null|zu.*|schlie..?en|runter.*|ab.*|leise.*|dunk.*
        - integer Wort enthält eine Zahl - float Wort enthält eine Gleitkommazahl + integer Wort enthält eine Zahl + float Wort enthält eine Gleitkommazahl numeral Word ist ein Zahlenwort oder Zahl
        /<regexp>/ Wort entspricht der <regexp> - word Wort enthält gleich oder mehr als 4 Zeichen - empty Wort enthält eine Leere Zeichenkette - else Falls keines der Fälle zutrifft - Wird ein <typ> identifiziert wird für $n der <wert> eingesetzt
        + word Wort enthält gleich oder mehr als 4 Zeichen + empty Wort enthält eine Leere Zeichenkette + else Falls keines der Fälle zutrifft + Wird ein <typ> identifiziert wird für $n der <wert> eingesetzt
        Beispiel: licht (\S*) = set light $1{true => on,false => off}
      • $n[<list>]
        Kommaseparierte Liste: [wert1,wert2,...,[else,value], [empty,value]] oder [@modwordlist]
        - Ist $n eine Zahl, wird das Wort das an dieser Position in <list> steht gewählt.

        - Ist $n ein Text wird in der zugehörigen Klammer im <regexp>-Teil nach einer Liste gesucht. (a|b|c) oder (@keywordlist) - In dieser Liste, wird nach $n gesucht und bei erfolg dessen Position in <list> für $n gewählt. -
        Beispiel: licht .* (küche|flur|bad) (\S*) an = set $1[dev_a,dev_b,dev_c] $2{true => on,false => off} + Ist $n eine Zahl, wird das Wort das an dieser Position in <list> steht gewählt.

        + Ist $n ein Text wird in der zugehörigen Klammer im <regexp>-Teil nach einer Liste gesucht. (a|b|c) oder (@keywordlist) + In dieser Liste, wird nach $n gesucht und bei erfolg dessen Position in <list> für $n gewählt. +
        Beispiel: licht .* (küche|flur|bad) (\S*) an = set $1[dev_a,dev_b,dev_c] $2{true => on,false => off}
      • -
      • $n@
        Das Wort wird so übernommen wie es in der Liste im <regexp>-Teil steht.
      • +
      • $n@
        Das Wort wird so übernommen wie es in der Liste im <regexp>-Teil steht.

      Umgebungsvariablen:
        - Es stehen eine Reihe von Variablen zur Verfügung auf die im <command>-Teil zugegriffen werden können. -
      • $& Enthält alle gefundenen Wörter
      • -
      • !$& Enthält den Rest der nicht von der RegExp eingeschlossen wurde
      • -
      • $DATE Enthält den Zeit und Datumstext des Sprachbefehls
      • -
      • $AGAIN Enthält das Wort wieder wenn es sich um ein wieder Kommando handelt
      • -
      • $TIME Enthält die erkannte Zeit.
      • -
      • $NAME Enthält den Devicenamen.
      • -
      • $IF Enthält den Text der erkannten T2F_if Konfiguration.
      • -
      • $0 Enthält den Text der erkannten T2F_origin RegExp.
      • + Es stehen eine Reihe von Variablen zur Verfügung auf die im <command>-Teil zugegriffen werden können. +
      • $& Enthält alle gefundenen Wörter
      • +
      • !$& Enthält den Rest der nicht von der RegExp eingeschlossen wurde
      • +
      • $DATE Enthält den Zeit und Datumstext des Sprachbefehls
      • +
      • $AGAIN Enthält das Wort wieder wenn es sich um ein wieder Kommando handelt
      • +
      • $TIME Enthält die erkannte Zeit.
      • +
      • $NAME Enthält den Devicenamen.
      • +
      • $IF Enthält den Text der erkannten T2F_if Konfiguration.
      • +
      • $0 Enthält den Text der erkannten T2F_origin RegExp.
    @@ -1905,8 +1990,8 @@ return($_[2]);
      set <name> [!]<text>

      - Über das set Kommando wird der zu interpretierende Text an das Modul gesendet. - Schaue unter commandref#set für weiterführende Hilfe. + Über das set Kommando wird der zu interpretierende Text an das Modul gesendet. + Schaue unter commandref#set für weiterführende Hilfe.
    • cleartimers
    • Entfernt die wartenden zeitbezogenen Kommandos
    • cleartriggers
    • Entfernt die wartenden ereignisbezogenen Kommandos
    @@ -1916,21 +2001,21 @@ return($_[2]); Get
    get <name> <option>

    - Über get lassen sich Informationen aus dem Modul auslesen. - Siehe commandref#get für weitere Informationen zu "get". + Über get lassen sich Informationen aus dem Modul auslesen. + Siehe commandref#get für weitere Informationen zu "get".

    <option>
    • @keywordlist @modwordlist
      - Vergleich der zwei Listen Wort für Wort
    • + Vergleich der zwei Listen Wort für Wort
    • keylistno
      Eine Auflistung der Konfigurierten "Keyword"-Listen. Zur einfacheren Positionierung der "Modword"-Listen
    • log
      - Zeigt die Logeinträge des letzten Kommandos
    • + Zeigt die Logeinträge des letzten Kommandos
    • modificationtypes
      Zeigt die RegExp der Modifikationstypen.
    • standardfilter
      - Lädt den Standardfilter und schreibt ihn in das Attribut T2F_filter wenn er leer ist
    • + Lädt den Standardfilter und schreibt ihn in das Attribut T2F_filter wenn er leer ist
    • version
      Die Modulversion
    @@ -1941,34 +2026,34 @@ return($_[2]); Readings
    • set
      - Enthält den zuletzt über "set" gesendeten Text. + Enthält den zuletzt über "set" gesendeten Text.
    • cmds
      - Enthält das zuletzt ausgeführte Kommando. Wird auch bei disable=1 gesetzt. + Enthält das zuletzt ausgeführte Kommando. Wird auch bei disable=1 gesetzt.
    • answer
      - Enthält den Antworttext des letzten Befehls. + Enthält den Antworttext des letzten Befehls.
    • err
      - Enthält die letzte Fehlermeldung.
      - "No match" Übereinstimmung mit keiner RegExp.
      + Enthält die letzte Fehlermeldung.
      + "No match" Übereinstimmung mit keiner RegExp.
      "Error on Command" siehe FHEM log.
    • response
      - Enthällt die Rüclgabe des FHEM Befhels. + Enthällt die Rückgabe des FHEM Befhels.
    • origin
      - Enthält die gefundene Zeichenkette der in dem Attribut T2F_origin definierten RegExp. + Enthält die gefundene Zeichenkette der in dem Attribut T2F_origin definierten RegExp.
    • status
      - Enthält den Status der Ausgabe. + Enthält den Status der Ausgabe. response, disabled, err, answers, done
    • ifs
      - Enthält die Bedingungen bei denen das Kommando ausgeführt werden wird. + Enthält die Bedingungen bei denen das Kommando ausgeführt werden wird.
    • notifies
      - Enthält eine Auflistung der Devices die für die aktuell wartenden bedingten Kommandos relevant sind. Auf diesen Devices liegt ein internes notify. + Enthält eine Auflistung der Devices die für die aktuell wartenden bedingten Kommandos relevant sind. Auf diesen Devices liegt ein internes notify.
    @@ -1979,37 +2064,37 @@ return($_[2]);
      attr <name> <attribute> <value>

      - Siehe commandref#attr für weitere Informationen zu den Attributen. + Siehe commandref#attr für weitere Informationen zu den Attributen.

      Attribute:
      • T2F_keywordlist <name> = <list>
        - Eine Komma seperierte Liste von Schlüsselwörtern wie z.B.: Räumen, Namen, Farben usw...
        - Mit anderen Worten, mit natürlichem Namen benannte Sachen. + Eine Komma seperierte Liste von Schlüsselwörtern wie z.B.: Räumen, Namen, Farben usw...
        + Mit anderen Worten, mit natürlichem Namen benannte Sachen.
      • T2F_modwordlist <name> = <list>
        - Eine Komma seperierte Liste von Ersetzungswörten die für die Schlüsselwörter eingesetzt werden. - z.B.: Gerätenamen in FHEM
        + Eine Komma seperierte Liste von Ersetzungswörten die für die Schlüsselwörter eingesetzt werden. + z.B.: Gerätenamen in FHEM
      • T2F_if
        Eine Auflistung von ereignisgesteuerten Konfigurationen. Die Syntax ist die der Definition. Kommandoteil ist eine IF Bedingung.
        - z.B.: wenn .*?tür = [door] eq "open" + z.B.: wenn .*?tür = [door] eq "open"
      • T2F_filter
        Kommaseparierte Liste von RegExp die generell entfernt werden.
        Standard: \bbitte\b,\bauch\b,\bkann\b,\bsoll\b
      • T2F_origin
        - Eine RegExp die generell entfernt wird und deren Ausgabe über $0 angesprochen werden kann.
        - Kann für eine Benutzerzuordnung verwendet werden. + Eine RegExp die generell entfernt wird und deren Ausgabe über $0 angesprochen werden kann.
        + Kann für eine Benutzerzuordnung verwendet werden.
      • T2F_languageDE|EN
        - Die verwendete Sprache kann über das globale Attribut "language" gesetzt werden. Oder über dieses Attribut überschrieben werden. + Die verwendete Sprache kann über das globale Attribut "language" gesetzt werden. Oder über dieses Attribut überschrieben werden.
      • T2F_disableumlautescaping <0|1>
        Deaktiviert das Konvertieren der Umlaute in "\S\S?"
      • disable <0|1>
        - Kann zu Testzwecken verwendet werden. Steht das Attribut auf 1, wird das FHEM-Kommando nicht ausgeführt + Kann zu Testzwecken verwendet werden. Steht das Attribut auf 1, wird das FHEM-Kommando nicht ausgeführt aber in das Reading cmds geschrieben.