<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>http://wiki.fhem.de/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=RoBra81</id>
	<title>FHEMWiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.fhem.de/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=RoBra81"/>
	<link rel="alternate" type="text/html" href="http://wiki.fhem.de/wiki/Spezial:Beitr%C3%A4ge/RoBra81"/>
	<updated>2026-04-15T17:47:55Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Talk2Fhem&amp;diff=24874</id>
		<title>Talk2Fhem</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Talk2Fhem&amp;diff=24874"/>
		<updated>2018-01-30T15:02:58Z</updated>

		<summary type="html">&lt;p&gt;RoBra81: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Das Modul stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her&lt;br /&gt;
|ModType=h]&lt;br /&gt;
|ModCmdRef=Talk2Fhem&lt;br /&gt;
|ModForumArea=Unterst&amp;amp;uuml;tzende Dienste&lt;br /&gt;
|ModTechName=39_Talk2Fhem.pm&lt;br /&gt;
|ModOwner=Oliver Georgi&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Seite beschreibt die Funktionsweise und Konfiguration des Moduls 39_Talk2Fhem.pm&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen ==&lt;br /&gt;
[[Datei:ModulTalk2FhemScreenshot.png|360px|thumb|right]]&lt;br /&gt;
Es ist sehr zu empfehlen, für die Konfiguration des Moduls, im Webfrontend von FHEM die Syntaxhervorhebung zu aktivieren. Die Aktivierung des erweiterten Editors ist [[Konfiguration#Syntaxhervorhebung|hier]] beschrieben.&lt;br /&gt;
&lt;br /&gt;
Kenntnisse im Bereich Regulärer Ausdrücke (RegExp) in Perl sind hilfreich, aber nicht zwingend erforderlich. Ein kurzer Einstieg kann hier eingesehen werden. [[Modul_Talk2Fhem#Häufig_verwendete_RegExp|Häufig_verwendete_RegExp]]&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
Das Modul Talk2Fhem stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her. Es ist ein überaus flexibles und relativ einfach zu konfigurierendes Script mit dem man sehr natürlich kommunizieren kann. Die Konfiguration erfolgt dabei über das FHEM Webfrontend. &lt;br /&gt;
&lt;br /&gt;
Es werden diverse [[Modul_Talk2Fhem#Zeitenerkennung|Zeit- und Datumsangaben]] erkannt. Außerdem ist es möglich [[Modul_Talk2Fhem#Eventenerkennung|Events zu formulieren]], welche die Befehle zu einem bestimmten Ereignis ausführen lassen. Bei der weiteren Verarbeitung der Sprachbefehle wird die Sprache mit selbst definierte Schlüsselwörter verglichen. &lt;br /&gt;
&lt;br /&gt;
=== Funktionsweise ===&lt;br /&gt;
&lt;br /&gt;
Die Zerlegung des Sprachbefehls erfolgt in mehreren Schritten. &lt;br /&gt;
# Aufteilen des Sprachbefehls in einzelne Kommandos anhand des Wortes UND&lt;br /&gt;
# Erkennen von Zeit- und Datumsangaben und entfernen für die weitere Verarbeitung&lt;br /&gt;
# Entfernung unnötiger Wörter&lt;br /&gt;
# Vergleich mit den definierten Schlüsselwörtern&lt;br /&gt;
# Konvertieren in ein FHEM Kommando&lt;br /&gt;
# Zeit- und Eventgebundenes auslösen des FHEM Kommandos&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Solange das Modul noch nicht offiziell aufgenommen wurde, muss die Datei 39_Talk2Fhem.pm manuell in das Verzeichnis FHEM/ kopiert werden. Siehe Forumsbeitrag. [https://forum.fhem.de/index.php/topic,80960.0.html]&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
 define talk Talk2Fhem&lt;br /&gt;
Zum testen der Konfiguration ist es Ratsam vorerst das Attribut disable auf 1 zu setzen. Hierbei wird die Auslösung der FHEM Kommandos unterdrückt.&lt;br /&gt;
 attr talk disable 1&lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
Der Sprachbefehl wird über das Kommando &#039;&#039;&#039;set&#039;&#039;&#039; oder &#039;&#039;&#039;set !&#039;&#039;&#039; an das Modul geleitet.&lt;br /&gt;
 set talk Guten Morgen liebes Zuhause&lt;br /&gt;
&#039;&#039;Wird kein Text angehängt, wird der letzte Sprachbefehl erneut ausgeführt.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Readings ===&lt;br /&gt;
&lt;br /&gt;
Im Reading &#039;&#039;&#039;set&#039;&#039;&#039; steht der letzte gesendete Sprachbefehl.&lt;br /&gt;
&amp;lt;br&amp;gt;Im Reading &#039;&#039;&#039;cmds&#039;&#039;&#039; steht das letzte ausgeführte FHEM-Kommando dessen Rückgabe in in das Reading &#039;&#039;&#039;fhem&#039;&#039;&#039; geschrieben wird. &lt;br /&gt;
&lt;br /&gt;
Die Antworten und Modulinterne Fehler werden in den Readings &#039;&#039;&#039;answers&#039;&#039;&#039; und &#039;&#039;&#039;err&#039;&#039;&#039; ausgegben. &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;ifs&#039;&#039;&#039; stehen die Bedingungen bei dem das letzte Kommando ausgeführt werden wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;notifies&#039;&#039;&#039; enthält eine Auflistung der Devices die für die aktuell wartenden bedingten Kommandos relevant sind. Auf diesen Devices liegt ein internes notify.   &lt;br /&gt;
&lt;br /&gt;
Das Reading &#039;&#039;&#039;status&#039;&#039;&#039; wird jedes mal gesetzt und erhält Werte nach folgender Priorität.&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|1.||&#039;&#039;&#039;response&#039;&#039;&#039; ||wenn das FHEM Kommando eine Meldung ausgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|2.||&#039;&#039;&#039;disabled&#039;&#039;&#039; ||wenn das Attribute disable auf 1 steht&lt;br /&gt;
|-&lt;br /&gt;
|3.||&#039;&#039;&#039;err&#039;&#039;&#039; ||wenn der Sprachbefehl einen Fehler zurückgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|4.||&#039;&#039;&#039;answer&#039;&#039;&#039; ||wenn der Sprachbefehl eine Antwort ausgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|5.||&#039;&#039;&#039;done&#039;&#039;&#039; ||wenn keines der oberen Fälle eingetreten ist, also alles gut verlaufen ist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Beispiel ===&lt;br /&gt;
Die FHEM Befehle werden eigenständig ausgeführt, sie können aber zur Überprüfung auch weitergeleitet werden. Das Beispiel zeigt auch wie auf Fehler und Antworten von Talk2Fhem reragiert werden kann.&lt;br /&gt;
Erstellen eines Notify&lt;br /&gt;
 define n_talk notify talk:.* {}&lt;br /&gt;
Folgendes in der Definition von n_talk einfügen&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 talk:.* {&lt;br /&gt;
 # Sende die Antwort per Telegram und gebe es über das GoogleHome aus&lt;br /&gt;
 	if ($EVENT =~ s/^answers: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telegram _msg \@USER $EVENT&amp;quot;);&lt;br /&gt;
 		fhem(&amp;quot;set d_googlespeak $EVENT&amp;quot;);	&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 # Schicke den Fehler per Telegram und sag am GoogleHome das es nicht geklappt hat.&lt;br /&gt;
 	if ($EVENT =~ s/^err: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telbot _msg \@Oliver $EVENT&amp;quot;);&lt;br /&gt;
 		my @a = (&amp;quot;Das hat leider nicht geklappt&amp;quot;, &amp;quot;Es gab leider einen Fehler&amp;quot;, &amp;quot;Es tut mir leid. Das hat nicht funktioniert.&amp;quot;, &amp;quot;Es ist leider zu einem Fehler gekommen&amp;quot;,&amp;quot;Könntest du das vielleicht nochmal anders sagen&amp;quot;, &amp;quot;Mhhh, das kann ich so nicht verstehen&amp;quot;);&lt;br /&gt;
 		fhem(&amp;quot;set d_googlespeak $a[int(rand($#a))]&amp;quot;);&lt;br /&gt;
 	} &lt;br /&gt;
 &lt;br /&gt;
 # Schick mir alle ausgeführten Befehle als Telegram&lt;br /&gt;
 &lt;br /&gt;
 	if ($EVENT =~ s/^cmds: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telbot _msg \@USER $EVENT&amp;quot;);&lt;br /&gt;
 	} &lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Eine weitere Möglichkeit Talk2Fhem mit anderen Modulen zu verbinden, ist über das Reading &#039;&#039;&#039;status&#039;&#039;&#039; möglich.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Lösung hat den Vorteil das eine Standardantwort definiert werden kann. &lt;br /&gt;
&#039;&#039;&#039;!Achtung noch nicht getestet vom Author!&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
talk:status {&lt;br /&gt;
my $text = ReadingsVal(&amp;quot;talk&amp;quot;, $EVENT, &amp;quot;Komisch, hier sollte eigentlich etwas Text stehen.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;$EVENT&amp;quot; eq &amp;quot;response&amp;quot;) {&lt;br /&gt;
  #FHEM gibt bei Erfolg eig. keine Rückmeldung, also ist vermutlich was schief gelaufen&lt;br /&gt;
  $text = &amp;quot;Die Haussteuerung hat folgende Meldung gebracht. $text&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; eq &amp;quot;err&amp;quot;) {&lt;br /&gt;
  $text = [&amp;quot;Das habe ich nicht verstanden!&amp;quot;,&amp;quot;Phuu das kann ich noch nicht!&amp;quot;,&amp;quot;Nein! Heute nicht.&amp;quot;, &amp;quot;Wie bitte?&amp;quot;]-&amp;gt;[rand(4)];&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; =~ /^answer/) {&lt;br /&gt;
  $text = ReadingsVal(&amp;quot;talk&amp;quot;, &amp;quot;answers&amp;quot;, &amp;quot;Ich habe nichts zu sagen.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; eq &amp;quot;err&amp;quot;) {&lt;br /&gt;
  #in $text steht schon der fehler drin&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; eq &amp;quot;done&amp;quot;) {&lt;br /&gt;
  $text = [&amp;quot;Ok.&amp;quot;,&amp;quot;Ja.&amp;quot;,&amp;quot;Gerne.&amp;quot;, &amp;quot;Mach ich!&amp;quot;]-&amp;gt;[rand(4)];&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
  $text = &amp;quot;Oh, es gibt etwas neues, bitte schau mal im Forum bei Talk2Fhem vorbei.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fhem(&#039;set speaker speak &amp;quot;$text&amp;quot;&#039;) if $text;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zeitenerkennung ===&lt;br /&gt;
Die Zeit- und Datum Eingabe kann auf viele verschiedene Arten erfolgen.&amp;lt;br&amp;gt;&lt;br /&gt;
Die Datumerkennung umfasst folgende Phrasen:&lt;br /&gt;
*morgen, übermorgen&lt;br /&gt;
*in ... Wochen, Monat, Jahr&lt;br /&gt;
*nächste Woche, Monat, Jahr&lt;br /&gt;
*Wochentage&lt;br /&gt;
*in ... Tagen&lt;br /&gt;
*am DATUM&lt;br /&gt;
&lt;br /&gt;
Die Zeiterkennung umfasst folgende Phrasen:&lt;br /&gt;
*in,nach ... stunden,minuten,sekunden&lt;br /&gt;
*um ... (Uhr) (...)&lt;br /&gt;
*heute - entspricht 12:00&lt;br /&gt;
*früh - entspricht 9 Uhr&lt;br /&gt;
*abend - entspricht 18 Uhr&lt;br /&gt;
*nachmittag - entspricht 16 Uhr&lt;br /&gt;
*vormittag - entspricht 10:30 Uhr&lt;br /&gt;
*mittag - entspricht 12 Uhr&lt;br /&gt;
*gleich - entspricht 5 Minuten&lt;br /&gt;
*nachher - entspricht 30 Minuten&lt;br /&gt;
*später - entspricht 1 Stunde&lt;br /&gt;
*jetzt&lt;br /&gt;
*sofort&lt;br /&gt;
&lt;br /&gt;
Datum und Zeitangaben können natürlich kombiniert werden.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wird eine Zeit erfolgreich erkannt erfolgt die Ausführung des FHEM-Kommandos über das Modul &#039;&#039;&#039;at&#039;&#039;&#039;. Es wird ein at Eregnis angelegt welches den Namen &#039;&#039;at_&amp;lt;modulname&amp;gt;_&amp;lt;zeitindex&amp;gt;&#039;&#039; erhält.&lt;br /&gt;
&lt;br /&gt;
Bei mehreren Kommandos über das Schlüsselwort &#039;&#039;UND&#039;&#039; wirkt sich der Zeitpunkt des ersten Kommandos auch auf das zweite und dritte ... aus.&lt;br /&gt;
 Schalte die Heizung um 20 Uhr aus und mache die Rollläden runter&lt;br /&gt;
Beide Kommandos werden um 20 Uhr ausgelöst.&lt;br /&gt;
&lt;br /&gt;
Hat das zweite Kommando ebenfalls eine Zeitphrase wird diese Zeit genommen.&lt;br /&gt;
 schalte die Heizung heute Abend ab und mache die Rollläden jetzt runter&lt;br /&gt;
==== Zeitenmodifikation ====&lt;br /&gt;
Wie oben gesehen wird der Zeitpunkt des ersten Kommandos vor dem &amp;quot;und&amp;quot; auch für das zweite nach dem &amp;quot;und&amp;quot; gesetzt. Vorausgesetzt er wird beim 2. Kommando nicht durch eine eigenständige Zeit (hier &amp;quot;jetzt&amp;quot;) ersetzt.&lt;br /&gt;
Wenn man die Zeit des zweiten Kommandos, relativ zum ersten setzen möchte, kann dies mit den Schlüsselwörtern &#039;&#039;dann&#039;&#039;, &#039;&#039;danach&#039;&#039; oder &#039;&#039;wieder&#039;&#039;  formuliert werden.&lt;br /&gt;
 Fahre um 14 Uhr die Rollläden an der Terrasse runter und schalte dann in 2 Minuten die Bewässerung an&lt;br /&gt;
oder&lt;br /&gt;
 Mach am Freitag um 5 Uhr die Heizung aus und in einer Woche wieder an&lt;br /&gt;
&lt;br /&gt;
Manchmal ist es notwendig etwas vor der angegebenen Zeit auszuführen. Hier lässt sich ein Offset zu dem ermittelten Zeitpunkt hinzufügen, um ihn zu ändern.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;perl&#039;&amp;gt;dusche\S?$ = (offset=&amp;gt;-3600, cmd=&amp;gt;&#039;set d_log bad warm&#039;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Der Sprachbefehl&lt;br /&gt;
 ich will um 18:30 Uhr duschen&lt;br /&gt;
Legt folgendes at Ergnis an&lt;br /&gt;
 define at_assi_1513096200 at 2017-12-12T17:30:00 set d_log bad warm&lt;br /&gt;
&lt;br /&gt;
=== Eventkonfiguration ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ereigniswiederholung ===&lt;br /&gt;
Werden zwei Sätze über ein &#039;&#039;&#039;und&#039;&#039;&#039; miteinander verknüpft kann der zweite Satz mit dem Wort &#039;&#039;&#039;wieder&#039;&#039;&#039; das Ereignis wiederholen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
 mach bitte die Garage auf und in 5 Minuten wieder zu&lt;br /&gt;
Man benötigt hier nicht erneut den kompletten ersten Satz zu wiederholen.&lt;br /&gt;
&lt;br /&gt;
== Konfiguration ==&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration des Moduls wird hauptsächlich über die Definition (DEF) vorgenommen.&lt;br /&gt;
Eine Konfiguration beginnt immer mit der Definition der gesuchten Schlüsselwörtern gefolgt von einem Gleichheitszeichen &#039;&#039;(siehe Randnotiz)&#039;&#039;. Diese werden Anhand von Regulären Ausdrücken (RegExp) beschrieben. Also z.B.:&lt;br /&gt;
 garage auf =&lt;br /&gt;
Das bededutet, sobald die Wörter in der Reihenfolge &amp;quot;garage&amp;quot; und &amp;quot;auf&amp;quot; erkannt werden, wird der Kommandoteil der Konfiguration ausgeführt. Groß- und Kleinschreibung wird grundsätzlich ignoriert.&lt;br /&gt;
&lt;br /&gt;
{{Randnotiz|RNText=Wichtig&lt;br /&gt;
Vor und nach dem Gleichheitszeichen muss mindestens ein Trennzeichen vorhanden sein&lt;br /&gt;
*Vor dem &amp;quot;=&amp;quot; mindestens ein Leer- oder Tabulatorzeichen&lt;br /&gt;
*Nach dem &amp;quot;=&amp;quot; können zusätzlich auch Zeilenumbrüche eingefügt werden&lt;br /&gt;
}}&lt;br /&gt;
Der Kommandoteil folgt dem Gleichheitszeichen &#039;&#039;(siehe Randnotiz)&#039;&#039;. Und kann auf folgende Arten vorliegen.&lt;br /&gt;
* FHEM Kommando&lt;br /&gt;
* { Perl Befehl }&lt;br /&gt;
* ( [[Modul_Talk2Fhem#erweiterte_Befehlskonfiguration]] )&lt;br /&gt;
&lt;br /&gt;
=== Import von Konfigurationen ===&lt;br /&gt;
Umfangreiche Konfigurationen können in Dateien ausgelagert und über @inlcude importtiert werden:&lt;br /&gt;
&lt;br /&gt;
 $include = FHEM/t2f.cfg&lt;br /&gt;
&lt;br /&gt;
=== Übersicht ===&lt;br /&gt;
 &amp;lt;regexp&amp;gt; = &amp;lt;command&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im ganzen könnte die Konfiguration dann so aussehen:&lt;br /&gt;
 garage\S* auf = set dev_garage open&lt;br /&gt;
&#039;&#039;\S* Siehe hierzu [[Modul_Talk2Fhem#Häufig_verwendete_RegExp|Häufig verwendete RegExp]].&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bei dem vorherigen Beispiel, würde der FHEM Befehl &amp;quot;set garage open&amp;quot; bei allen folgenden Sprachbefehlen ausgeführt werden.&lt;br /&gt;
 Mach bitte die Garage auf&lt;br /&gt;
 Das haus soll das Garagentor aufmachen&lt;br /&gt;
 Garagentür in 5 Minuten auf&lt;br /&gt;
 Die Garagen soll in einer Stunde aufgemacht werden&lt;br /&gt;
&lt;br /&gt;
=== RegExp in unbekannter Reihenfolge ===&lt;br /&gt;
Wenn die Reihenfolge der Wörter nicht bekannt sind kann der &amp;lt;regexp&amp;gt;-Teil aufgeteilt (verUNDet) werden: &amp;lt;regexp&amp;gt; &amp;amp;&amp;amp; &amp;lt;regexp&amp;gt; &amp;amp;&amp;amp; ...&lt;br /&gt;
&lt;br /&gt;
 Licht &amp;amp;&amp;amp; Wohnzimmer &amp;amp;&amp;amp; schalte = ...&lt;br /&gt;
&lt;br /&gt;
akzeptiert&lt;br /&gt;
&lt;br /&gt;
 Schalte das Licht im Wohnzimmer&lt;br /&gt;
&lt;br /&gt;
 Im Wohnzimmer das Licht schalten&lt;br /&gt;
&lt;br /&gt;
 Schalte im Wohnzimmer das licht&lt;br /&gt;
&lt;br /&gt;
=== RegExp optional oder nicht vorhanden ===&lt;br /&gt;
Die einzelnen RegExp können zusätzlich mit ? und ! beeinflusst werden:&lt;br /&gt;
&lt;br /&gt;
 !&amp;lt;regexp&amp;gt; ist eine Verneinung. Sprich, nur wenn die &amp;lt;regexp&amp;gt; nicht vorkommt.&lt;br /&gt;
 ?&amp;lt;regexp&amp;gt; Optionale &amp;lt;regexp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beipiel:&lt;br /&gt;
&lt;br /&gt;
 Licht &amp;amp;&amp;amp; ?Wohnzimmer &amp;amp;&amp;amp; schalte &amp;amp;&amp;amp; !aus = ...&lt;br /&gt;
&lt;br /&gt;
akzeptiert&lt;br /&gt;
&lt;br /&gt;
 Schalte das Licht im Wohnzimmer ein&lt;br /&gt;
&lt;br /&gt;
 Schalte das Licht ein&lt;br /&gt;
&lt;br /&gt;
aber nicht&lt;br /&gt;
&lt;br /&gt;
 Schalte das Licht im Wohnzimmer aus&lt;br /&gt;
&lt;br /&gt;
 Schalte das Licht aus&lt;br /&gt;
&lt;br /&gt;
=== Klammerüberführung ===&lt;br /&gt;
&lt;br /&gt;
Es ist nicht notwendig für jeden Zustand oder jedes Gerät eine eigene Konfigurationzeile zu erzeugen. Hierfür gibt es die Möglichkeit, wie bei Regulären Ausdrücken üblich, Klammern &amp;quot;( )&amp;quot; im &amp;lt;regex&amp;gt;-Teil zu erfassen. Dies erfolgt über die Standartvariablen $1, $2, ..., $n. &amp;quot;n&amp;quot; steht hier für die nte Klammer.&lt;br /&gt;
Zusätzlich gibt es in Talk2Fhem die Möglichkeit die Klammern zu modifizieren.&lt;br /&gt;
&lt;br /&gt;
Soll die Garage auf und zugemacht werden, lässt sich folgendermaßen beschreiben.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
 garage\S* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(\S+)&amp;lt;/span&amp;gt; = set dev_garage &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Satz: &amp;quot;Mach die Garage auf&amp;quot; ergibt dann als FHEM Kommando&lt;br /&gt;
 set dev_garage auf&lt;br /&gt;
&lt;br /&gt;
=== Klammermodifikation ===&lt;br /&gt;
&lt;br /&gt;
Da es in den meißten Fällen nicht gewünscht ist, nur das gefunde Wort in das FHEM Kommando zu überführen, lässt sich zusätzlich das gefundene Wort modifizieren.&lt;br /&gt;
&lt;br /&gt;
==== Variante 1: nach Typ ====&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kann die Klammer auf ihren Typ hin modifiziert werden.&lt;br /&gt;
&lt;br /&gt;
===== Definition =====&lt;br /&gt;
&lt;br /&gt;
 $n{ &#039;&#039;&#039;typ&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;modification&#039;&#039;&#039;, typ2 =&amp;gt; mod2, ..., typn =&amp;gt; modn }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;typ&#039;&#039;&#039; kann eines der folgenden Wörtern enthalten:&lt;br /&gt;
*&#039;&#039;&#039;true&#039;&#039;&#039; sind alle Wörter die eine positive Richtung enthalten. Wie z.B. auf, ein, hoch, an, usw.&lt;br /&gt;
*&#039;&#039;&#039;false&#039;&#039;&#039; sind alle Wörter die eine negative Richtung enthalten. Wie z.B. ab, aus, runter, zu, usw.&lt;br /&gt;
*&#039;&#039;&#039;integer&#039;&#039;&#039; Wort enthält eine Zahl&lt;br /&gt;
*&#039;&#039;&#039;float&#039;&#039;&#039; Wort enthält eine Gleitkommazahl&lt;br /&gt;
*&#039;&#039;&#039;/&amp;lt;regexp&amp;gt;/&#039;&#039;&#039; Wort entspricht der &amp;lt;regexp&amp;gt;&lt;br /&gt;
*&#039;&#039;&#039;word&#039;&#039;&#039; Wort enthält gleich oder mehr als 4 Zeichen &lt;br /&gt;
*&#039;&#039;&#039;empty&#039;&#039;&#039; Wort enthält eine Leere Zeichenkette&lt;br /&gt;
*&#039;&#039;&#039;else&#039;&#039;&#039; Falls keines der Fälle zutrifft&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;modification&#039;&#039;&#039; enthält das einzufügende Wort.&lt;br /&gt;
&lt;br /&gt;
===== Beispiel =====&lt;br /&gt;
 garage\S* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(\S*)&amp;lt;/span&amp;gt; = set dev_garage &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;{ true =&amp;gt; open , false =&amp;gt; close }&lt;br /&gt;
Die Sätze:&lt;br /&gt;
 mach die Garage auf&lt;br /&gt;
 bitte Garagentor schließen &lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set dev_garage open&lt;br /&gt;
 set dev_garage close&lt;br /&gt;
&lt;br /&gt;
==== Variante 2: nach Liste ====&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kann die Klammer anhand einer oder zweier Listen selektiert werden.&lt;br /&gt;
&lt;br /&gt;
===== Definition =====&lt;br /&gt;
&lt;br /&gt;
 $n[ wert1, wert2,,,,, wertn ]&lt;br /&gt;
oder&lt;br /&gt;
 $n[ @liste ]&lt;br /&gt;
&lt;br /&gt;
Innerhalb der Klammern [ ] wird eine Komma separierte Liste mit Namen erwartet die als Modifikatorliste dient. Die sogenannte Modwordlist. Die Werte sind immer optional und können leer gelassen werden. Über das Attribut &#039;&#039;T2F_modwordlist&#039;&#039; können diese Listen zur Übersicht und Wiederverwendbarkeit angelegt werden. Siehe Attribute. Auf diese Listen, lässt sich über den Namen der Liste, mit einem vorangestelltes &#039;@&#039; zugreifen.&lt;br /&gt;
&lt;br /&gt;
===== Beispiel nach Position =====&lt;br /&gt;
&lt;br /&gt;
Beim ersten Beispiel wird eine Zahl im regex-Teil erwartet (\d+). Diese Zahl entscheidet welche Position aus der Modwordlist ausgewählt werden soll.&lt;br /&gt;
 ventilator auf (stufe )?&amp;lt;span style=&#039;color:red&#039;&amp;gt;(\d+)&amp;lt;/span&amp;gt; = set aircon &amp;lt;span style=&#039;color:red&#039;&amp;gt;$2&amp;lt;/span&amp;gt;[ off, level1, level2, level3 ]                                                                                              &lt;br /&gt;
                &amp;lt;span style=&#039;color:gray&#039;&amp;gt;           |------------------&amp;gt;  0      1       2       3&amp;lt;/span&amp;gt;            &lt;br /&gt;
&#039;&#039;(Stufe )?&#039;&#039; bedeutet: Das Wort Stufe kann, muss aber nicht.&lt;br /&gt;
&lt;br /&gt;
Die Sätze:&lt;br /&gt;
 Ventilator in 10 Minuten auf Stufe 0&lt;br /&gt;
 Ventilator auf 3&lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set aircon off&lt;br /&gt;
 set aircon level3&lt;br /&gt;
&lt;br /&gt;
===== Beispiel nach Vergleichsliste =====&lt;br /&gt;
&lt;br /&gt;
Hier kommt eine weitere Liste ins Spiel. Die sogenannte Keywordlist ist im Eigentlichen eine RegExp &amp;quot;Ver-oder-ung&amp;quot;.&lt;br /&gt;
 ( key1 | key2 | ... | keyn )&lt;br /&gt;
oder&lt;br /&gt;
 ( @keywordlist )&lt;br /&gt;
Diese Liste mit Schlüsselwörtern wird im &amp;lt;regex&amp;gt;-Teil angegeben. Hier entscheidet nicht eine Zahl über die Position, sondern die Position die in der Keywordlist einen Treffer hat wird an selber Position in der Modwordlist ausgewählt. Im Attribut T2F_keywordlist können vordefinierte Listen angelegt werden und mit @keylist ausgewählt werden&lt;br /&gt;
&lt;br /&gt;
 blendet.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(Wohnzimmer|Esszimmer|Küche)&amp;lt;/span&amp;gt; = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;[act_lvgroom, act_dinroom, act_kitchen] 70&lt;br /&gt;
               &amp;lt;span style=&#039;color:gray&#039;&amp;gt;|__________|_______|___________________|_____________|____________|&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;.*&#039;&#039; beliebig viele Zeichen&lt;br /&gt;
&lt;br /&gt;
Die Sätze: &lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 ich sitze geblendet im Wohnzimmer&lt;br /&gt;
 die sonne blendet in der Küche&lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set act_dinroom 70&lt;br /&gt;
 set act_lvgroom 70&lt;br /&gt;
 set act_kitchen 70&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Auswahl des Listenelements &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Soll bei der Nutzung der Variable nicht der Wert aus dem Sprachbefehl, sondern der Wert der Liste genutzt werden, so wird an die Variable ein @ angehängt. So wird bei&lt;br /&gt;
 blendet.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(Wohnzimmer|Esszimmer|Küche)&amp;lt;/span&amp;gt; = set act_&amp;lt;span style=&#039;color:red&#039;&amp;gt;$1@&amp;lt;/span&amp;gt; 70&lt;br /&gt;
&lt;br /&gt;
Die Sätze &lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 es blendet im esszimmer&lt;br /&gt;
immer zu&lt;br /&gt;
 set act_Esszimmer 70&lt;br /&gt;
&lt;br /&gt;
führen, da die Liste das Esszimmer großgeschrieben enthält.&lt;br /&gt;
&lt;br /&gt;
===== Ergänzung =====&lt;br /&gt;
Ähnlich wie in Variante 1, könne  auch hier auf die Schlüsselwörte &lt;br /&gt;
 empty für leere Zeichenkette &lt;br /&gt;
und &lt;br /&gt;
 else für alle anderen Fälle&lt;br /&gt;
zugegriffen werden. Hierbei wird der Modwordlist einfach empty oder else gefolgt von dem gewünschten Wert als nächstes Element angehängt.&lt;br /&gt;
 $n[ wert1, wert2,,,, empty, wert3, else, wert4 ]&lt;br /&gt;
&lt;br /&gt;
==== zusätzliche Variablen ====&lt;br /&gt;
Ergänzend zu den Listenvariablen stehen folgende Variablen zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
 $&amp;amp; Enthält alle gefundenen Wörter&lt;br /&gt;
 !$&amp;amp; Enthält den Rest der nicht von der RegExp eingeschlossen wurde&lt;br /&gt;
 $DATE Enthält den Zeit und Datumstext des Sprachbefehls&lt;br /&gt;
 $AGAIN Enthält das Wort wieder wenn es sich um ein wieder Kommando handelt (siehe Beispiele)&lt;br /&gt;
&lt;br /&gt;
=== erweiterte Befehlskonfiguration ===&lt;br /&gt;
Um Talk2Fhem in den Konfigurationszeilen weitere Parameter zu übergeben, ist eine gesonderte Syntax zu verwenden.&lt;br /&gt;
 &amp;lt;regexp&amp;gt; = ( option =&amp;gt; &#039;value&#039;  ,&lt;br /&gt;
              opt2   =&amp;gt; &#039;value2&#039; ,&lt;br /&gt;
              ... &lt;br /&gt;
              optn   =&amp;gt; &#039;valuen&#039; ) &lt;br /&gt;
Es stehen folgende Optionen zur Verfügung:&lt;br /&gt;
*cmd    =&amp;gt; enthält das FHEM Kommando.  Wie oben beschrieben.&lt;br /&gt;
*answer  =&amp;gt;  Ein in Anführungszeichen (&amp;quot; oder &#039;) gesetzter Perl-Befehl, dessen Rückgabe in das Reading &#039;&#039;answer&#039;&#039; geschrieben wird.&lt;br /&gt;
* offset =&amp;gt;  Ganzzahliger Wert in Sekunden der dem Zeitpunkt addiert wird. Siehe [[Modul_Talk2Fhem#Zeitenmodifikation]]&lt;br /&gt;
&lt;br /&gt;
=== Antworten ===&lt;br /&gt;
In Talk2Fhem können Antworten, die das Modul ausgeben soll, definiert werden. Hier können Fragen verarbeitet werden oder auch den Erfolg eines Kommandos bestätigt werden.&lt;br /&gt;
&lt;br /&gt;
Über die [[Modul_Talk2Fhem#erweiterte_Befehlskonfiguration]], erhält der Parameter &amp;quot;answer&amp;quot; einen Perl Befehl, dessen Rückgabe die Antwort darstellt.&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Erfolgsmeldung ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;tu was = ( cmd =&amp;gt; &amp;quot;set tue es&amp;quot; , answer =&amp;gt; &#039;&amp;quot;Erledigt&amp;quot;&#039; )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Man beachte hier, dass die Parameter immer in Anführungszeichen gesetzt werden müssen. In diesem Fall der Perl Befehl. Ein Text in Perl wird ebenfalls in Anführungszeichen gesetzt, deswegen die doppelten Anführungszeichen!&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Zustandsabfrage ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;wurde es getan = ( answer =&amp;gt; &#039;Value(&amp;quot;tue&amp;quot;) eq &amp;quot;es&amp;quot; ? &amp;quot;Ja&amp;quot; : &amp;quot;Nein&amp;quot;&#039;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Temperaturabfragen ====&lt;br /&gt;
Eine einfache Temperaturabfrage könnte so aussehen.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;wie.*(kalt|warm|grad|temperatur) = ( answer =&amp;gt; &#039;&amp;quot;Die Temperatur beträgt &amp;quot;.ReadingsVal(&amp;quot;tempdev&amp;quot;, &amp;quot;temperature&amp;quot;, &amp;quot;Fehler&amp;quot;)&#039; )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Für eine Raumbezogene Temperaturabfrage, siehe [[Modul_Talk2Fhem#Anwendungsbeispiele_und_Vorlagen]]&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Folgende Attribute werden zur Zeit unterstützt&lt;br /&gt;
=== T2F_keywordlist ===&lt;br /&gt;
 &amp;lt;Name&amp;gt; = &amp;lt;kommaseparierte Liste mit RegExp&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Beispiele&#039;&#039;&#039;&lt;br /&gt;
 rooms = haus|überall|wohnung , wohnzimmer , bad\S* , toilette|wc , büro , ...&lt;br /&gt;
 names = Mama , Papa , Kevin , Jacqueline&lt;br /&gt;
 channels = ard|das erste , zdf , rtl , sat 1 , vox , rtl2 , prosieben , kabel eins , arte&lt;br /&gt;
Man beachte hier die möglichkeit der RegExp&amp;lt;br&amp;gt;&lt;br /&gt;
Das Schlüsselwort &#039;&#039;&#039;haus&#039;&#039;&#039; löst das selbe aus wie &#039;&#039;&#039;überall&#039;&#039;&#039; und &#039;&#039;&#039;wohnung&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;Genauso &#039;&#039;&#039;bad&#039;&#039;&#039; oder &#039;&#039;&#039;badezimmer&#039;&#039;&#039; oder &#039;&#039;&#039;badeirgendewas&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== T2F_modwordlist ===&lt;br /&gt;
 &amp;lt;Name&amp;gt; = &amp;lt;kommaseparierte Liste mir RegExp&amp;gt;&lt;br /&gt;
Die Positionen der gewählten Geräte, ist eine Zuordnung zu den Listen in&#039;&#039;T2F_keywordlist&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;Wenn Wohnzimmer in der keywordliste &amp;lt;rooms&amp;gt; an Position 2 steht muss der Rolladenaktor in der modworliste &amp;lt;roll&amp;gt; auch an Position 2 stehen.&lt;br /&gt;
 roll = rollos_alle , d_rollo_wz , hm_roll_bad.* , hm_roll_wc , hm_roll_buero.* , ...&lt;br /&gt;
 lights = alle_lichte , &#039;&#039;&#039;&amp;quot;sw_wz1,sw_wz2&amp;quot;&#039;&#039;&#039; , sw_bad.* , sw_wc&lt;br /&gt;
Sollen einem Schlüsselwort mehrere Aktoren zugeordnet werden, geht das über sogenannte &amp;quot;Quotes&amp;quot;. (Anführungszeichen) Siehe &amp;lt;lights&amp;gt;.&lt;br /&gt;
 &amp;quot;a,b&amp;quot;  oder  &#039;a,b&#039;  oder  a\,b&lt;br /&gt;
&lt;br /&gt;
=== T2F_disableumlautescaping ===&lt;br /&gt;
&lt;br /&gt;
Deaktiviert das Konvertieren der Umlaute innnerhalb von regulären Ausdrücken in &#039;&#039;&#039;\S\S?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== T2F_language ===&lt;br /&gt;
&lt;br /&gt;
Legt die verwendete Sprache fest. Alternativ wird das Globale Attribut &#039;&#039;language&#039;&#039; verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== disable ===&lt;br /&gt;
Deaktiviert das Ausführen des FHEM Kommandos&lt;br /&gt;
=== verbose ===&lt;br /&gt;
&lt;br /&gt;
== Anwendungsbeispiele und Vorlagen ==&lt;br /&gt;
Hier folgen diverse Vorlagen und Beispiele die jeweils an die eigenen Bedürfnisse angepassst werden sollten/müssen. Hierzu sind die entsprechenden Stellen &amp;lt;span style=&#039;color:red&#039;&amp;gt;rot&amp;lt;/span&amp;gt; markiert.&lt;br /&gt;
=== Keywordlist ===&lt;br /&gt;
Eine typische Keywordlist wäre eine Auflistung der benötigten Räume&lt;br /&gt;
 rooms = haus|überall|wohnung,wohnzimmer,esszimmer,bad\S*,toilette|wc,&lt;br /&gt;
 büro,schlafzimmer,ankleide|garderobe,kinderzimmer,spielzimmer,&lt;br /&gt;
 flur|gang|diele,garage,garten,terrasse,balkon,&lt;br /&gt;
 eg|erdgescho\S*,og|obergescho\S*,\S*auße\S*( haus)?|vor der tür&lt;br /&gt;
&lt;br /&gt;
=== Einfaches schalten ===&lt;br /&gt;
 licht (\S+) = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;dev_light&amp;lt;/span&amp;gt; $1{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
=== Einfaches schalten mit eigenen Wörtern ===&lt;br /&gt;
Will man neben an/aus einen weiteren Zustand selbst definieren, kann das so geschehen.&lt;br /&gt;
 garage (\S+) = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;dev_gate&amp;lt;/span&amp;gt; $1{ /&amp;lt;span style=&#039;color:red&#039;&amp;gt;kurz&amp;lt;/span&amp;gt;/ =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;open-for-time 5&amp;lt;/span&amp;gt;, true =&amp;gt; open, false =&amp;gt; close }&lt;br /&gt;
&lt;br /&gt;
=== Einfaches schalten mit Räumen ===&lt;br /&gt;
 licht (\S+ ){0,2} (&amp;lt;span style=&#039;color:red&#039;&amp;gt;wohnzimmer|esszimmer|küche|terrasse&amp;lt;/span&amp;gt;) (\S+) = set $2[&amp;lt;span style=&#039;color:red&#039;&amp;gt;light_wz,light_ez,light_kitchen,light_outside&amp;lt;/span&amp;gt;] $3{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
Bei größeren Mengen an Räumen und Geräten bietet sich das anlegen von Keyword- und Modwordlisten an. &lt;br /&gt;
 licht (\S+ ){0,2} (&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;) (\S+) = set $2[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@lights&amp;lt;/span&amp;gt;] $3{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
&lt;br /&gt;
=== Rolladen fahren ===&lt;br /&gt;
Sind die Rollläden innerhalb von FHEM über das Attribut &amp;quot;room&amp;quot; den Räumen mit Klarnamen zugeordnet, lässt sich das ganze am einfachsten konfigurieren.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;1.  nach Devicetyp&#039;&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(\S+) (auf )?(\S+) = {fhem(&#039;set room=&#039;.ucfirst(&#039;$3&#039;).&#039;:FILTER=a:subType=blindActuator &amp;lt;span style=&#039;color:red&#039;&amp;gt;$5&amp;lt;/span&amp;gt;{true=&amp;gt;on, false=&amp;gt;off, integer=&amp;gt;&#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;set_$5&amp;lt;/span&amp;gt;&#039;)}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erklärung&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn das Device vom subTyp &amp;quot;blindActuator&amp;quot; ist (HomeMatic Rolladenactor) und es im Raum $3 ist, wird dieses Device gefahren. Die Funktion ucfirst ist notwendig damit der erste Buchstabe groß geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;2.  nach Devicenamen&#039;&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(\S+) (auf )?(\S+) = {fhem(&#039;set room=&#039;.ucfirst(&#039;$3&#039;).&#039;:FILTER=rollo.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;$5&amp;lt;/span&amp;gt;{true=&amp;gt;on, false=&amp;gt;off, integer=&amp;gt;&#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;set_$5&amp;lt;/span&amp;gt;&#039;)}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erklärung&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Gleiche wie oben, nur das alle Devices die mit rollo beginnen im Raum $3 gefahren werden. (rollo.*)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;3.  nach Benutzerdefinierten Räumen&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Ansonsten müssen wir dem Modul sagen in welchem Raum welches Device sitzt. Das hat dafür den Vorteil das die Räume als RegExp angegeben werden können.&amp;lt;br&amp;gt;Wir erzeugen eine Modwordlist &#039;&#039;rollos&#039;&#039; in der wir alle Rollladen &amp;quot;Devices&amp;quot; auflisten. Die Reihenfolge ist an der Keywordlist &amp;quot;rooms&amp;quot; ([[Modul_Talk2Fhem#Keywordlist]]) anzupassen.&lt;br /&gt;
 rollos = &amp;lt;span style=&#039;color:red&#039;&amp;gt;r_alle&amp;lt;/span&amp;gt;,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_wz&amp;lt;/span&amp;gt;,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_ez&amp;lt;/span&amp;gt;,,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_buero&amp;lt;/span&amp;gt;,...&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;)? (auf )?(\S+) = set $3[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rollos&amp;lt;/span&amp;gt;, empty, &amp;lt;span style=&#039;color:red&#039;&amp;gt;rollos_alle&amp;lt;/span&amp;gt;] $5{true=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt;, integer=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;&amp;quot;set_$5&amp;quot;&amp;lt;/span&amp;gt;}&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 Rollos auf&lt;br /&gt;
 Rolllos Überall schließen &lt;br /&gt;
 Rollo im Wohnzimmer hoch&lt;br /&gt;
 Rolladen im Esszimmer runter&lt;br /&gt;
 Rollläden in der Küche auf 50&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Damit wäre eigentlich schon alles abgedeckt. Folgendes Beispiel ist aber auch noch nützlich.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
  (blendet|schatte\S?) ?(\S+ ){0,2}(&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;) = set $3[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rollos&amp;lt;/span&amp;gt;] &amp;lt;span style=&#039;color:red&#039;&amp;gt;set_70&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 ich werde geblendet in der Küche&lt;br /&gt;
 die Sonne blendet mich im Badezimmer&lt;br /&gt;
 beschatte das Haus&lt;br /&gt;
 mach schatten im Erdgeschoss&lt;br /&gt;
&lt;br /&gt;
=== GoogleCast Befehle ===&lt;br /&gt;
Etwas bessere Lautstärkebefehle als die von Google.&lt;br /&gt;
Die Lautstärken müssten noch dem eigenen Geschmack angepasst werden&lt;br /&gt;
 #GoogleCast Commandos&lt;br /&gt;
 leise$            =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 14&lt;br /&gt;
 normale lautstärke =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 20&lt;br /&gt;
 laut$             =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 30&lt;br /&gt;
 (ein wenig|etwas|viel)? ?(lauter|leiser)  =  { fhem(&amp;quot;set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume &amp;quot;.(ReadingsVal(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;volume&amp;quot;, 0)$2[+,-]$1[3,5,10,empty,7])) }&lt;br /&gt;
&#039;&#039;&#039; Beispielsätze &#039;&#039;&#039;&lt;br /&gt;
 Mach leise&lt;br /&gt;
 Mach lauter&lt;br /&gt;
 Mach etwas leiser&lt;br /&gt;
 Mach viel lauter&lt;br /&gt;
&lt;br /&gt;
=== Talk Timer zurücksetzen ===&lt;br /&gt;
Sollen alle von Talk2Fhem angelegten Timer gelöscht werden.&lt;br /&gt;
 (timer|kommandos) (löschen|zurücksetzen) = delete at_&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;.*&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 bitte alle timer zurücksetzen&lt;br /&gt;
 zukünftige kommandos löschen&lt;br /&gt;
&lt;br /&gt;
=== Frage Antwort ===&lt;br /&gt;
==== Raumbezogene Temperaturansage ====&lt;br /&gt;
Wir erzeugen wieder unsere Modwordlist sagen wir @sens gefüllt mit den Temperaturfühler &amp;quot;Devices&amp;quot;. Reihenfolge wie immer die der Keywordlist @rooms.&lt;br /&gt;
 wie.*(kalt|warm|grad|temperatur).*(&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;@rooms&amp;lt;/span&amp;gt;) = ( answer =&amp;gt; &#039;&amp;quot;Die Temperatur beträgt &amp;quot;.ReadingsVal(&amp;quot;$2[&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;@sens&amp;lt;/span&amp;gt;]&amp;quot;, &amp;quot;&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;temperature&amp;lt;/span&amp;gt;&amp;quot;, &amp;quot;unbekannt&amp;quot;).&amp;quot; grad&amp;quot;&#039; )&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 wie warm ist es im Wohnzimmer&lt;br /&gt;
 wie ist die Temperatur in der Küche&lt;br /&gt;
 wie kalt ist es draußen&lt;br /&gt;
&lt;br /&gt;
==== Multiple Antworten ====&lt;br /&gt;
 Hallo Haus = ( answer =&amp;gt; &#039;[&amp;quot;Hallo auch!&amp;quot;,&amp;quot;Guten Tag!&amp;quot;,&amp;quot;Ahoi!&amp;quot;]-&amp;gt;[rand(&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt;)]&#039; ) &lt;br /&gt;
Wählt zufällig eine der drei Aussagen.&lt;br /&gt;
&lt;br /&gt;
==== Ausgabe eines oder mehrerer Zustände ====&lt;br /&gt;
Angenommen man möchte wissen ob das Haus abgeschlossen ist. Und in FHEM existiert ein Dummy der diesen Zustand wiederspiegelt und im Reading text die offenen Fenster und Türen aufgelistet sind. Kann man folgendermaßen den Status erfragen&lt;br /&gt;
 (alles|das haus) (zu|abgeschlossen) = (&lt;br /&gt;
   answer =&amp;gt; &#039;(Value(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;d_schliessung&amp;lt;/span&amp;gt;&amp;quot;) eq &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;zu&amp;lt;/span&amp;gt;&amp;quot;) &lt;br /&gt;
   ? &amp;quot;Es ist alles zu&amp;quot; &lt;br /&gt;
   : &amp;quot;Nein, offen sind: &amp;quot;.ReadingsVal(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;d_schliessung&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;text&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;&amp;quot;)&#039;&lt;br /&gt;
&lt;br /&gt;
==== Zustandsabfrage anhand des Aliasnamen ====&lt;br /&gt;
Möchte man alle Geräte anhand seines Attribut &amp;quot;alias&amp;quot; ansprechen, um dessen Status zu erfragen, könnte das so erfolgen.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039; &lt;br /&gt;
 (zustand|status) (\S+)* (\S+) = (answer=&amp;gt;&#039;my $s=Value((grep { &amp;quot;$3&amp;quot; =~ /$attr{$_}{&amp;lt;span style=&#039;color:red&#039;&amp;gt;alias&amp;lt;/span&amp;gt;}/i } (keys %attr))[0]);; &amp;quot;Der Status ist &amp;quot;.$s if $s&#039;)&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 Wie ist der Zustand der Lüftung&lt;br /&gt;
 sag mir den Status der Haustür&lt;br /&gt;
Es ist auch möglich ein eigenes Attribut zu kreieren, und dieses als Klarnamenattribut zu verwenden. Hierzu einfach im Device global ein userattr hinzufügen. z.B.&lt;br /&gt;
 attr global userattr T2F_alias&lt;br /&gt;
Jetzt stehen in allen Devices das Attribut T2F_alias zur Verfügung. Vorteil ist das dann auch wieder RegExp verwendet werden können. Im oberen Beispiel müsste dann dass rot markierte &amp;quot;alias&amp;quot; durch &amp;quot;T2F_alias&amp;quot; ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration innerhalb der Geräte ===&lt;br /&gt;
Neben der Identifikation der Geräte über die vorhandenen FHEM-Attribute (z.B. room, alias, ...) kann eine alternative Konfiguration auch über eigens für Talk2Fhem angelegte Attribute erfolgen. Die hierfür notwendigen Grundlagen und einige Beispiele sollen im Folgenden beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Grundlagen / Voraussetzungen ====&lt;br /&gt;
1. Anlegen der notwendigen userattr am global-Device:&lt;br /&gt;
&lt;br /&gt;
Erweiterung des Attributes userattr des Gerätes global um folgende Einträge:&lt;br /&gt;
  T2F_places:textField-long T2F_properties:textField-long T2F_rooms:textField-long T2F_types_color:textField-long T2F_types_heating:textField-long T2F_types_info:textField-long T2F_types_switch:textField-long&lt;br /&gt;
&lt;br /&gt;
2. Optional: Hilfsfunktionen für das automatische Füllen der T2F_keywordlist im talk-Device bei Änderung eines T2F-Attributes eines Gerätes&lt;br /&gt;
&lt;br /&gt;
2a. erstellen einer sub in der 99_myUtils.pm:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;  sub fill_T2F_keywordlist&lt;br /&gt;
  {&lt;br /&gt;
    my ($name, $t2f_device) = @_;&lt;br /&gt;
    $name =~ s/T2F_//g;&lt;br /&gt;
    if ($name eq &#039;userattr&#039;)&lt;br /&gt;
    {&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    Log 0, &amp;quot;List: &amp;quot;.$name;&lt;br /&gt;
    my $currentAttr = AttrVal($t2f_device,&amp;quot;T2F_keywordlist&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    my @currentAttrParts = split(/$name = /, $currentAttr);&lt;br /&gt;
    my $currentAttrBeg = @currentAttrParts[0];&lt;br /&gt;
    $currentAttrBeg = substr($currentAttrBeg, 0, -1);&lt;br /&gt;
    my @currentAttrEnd = split(/\n/, @currentAttrParts[1], 2);&lt;br /&gt;
    my @array = devspec2array(&#039;a:T2F_&#039;.$name.&#039;=.+&#039;);&lt;br /&gt;
    my @attributes = ();&lt;br /&gt;
    if (@array &amp;gt; 0 and defined($defs{$array[0]}))&lt;br /&gt;
    {&lt;br /&gt;
      foreach (@array){&lt;br /&gt;
      my @attrVals = split(/\n/,AttrVal($_, &#039;T2F_&#039;.$name, &#039;&#039;));&lt;br /&gt;
      foreach (@attrVals){&lt;br /&gt;
          my $attrVal = $_;&lt;br /&gt;
          $attrVal =~ s/  / /g;&lt;br /&gt;
          $attrVal =~ s/ =&amp;gt; /=&amp;gt;/g;&lt;br /&gt;
          my @attrValParts = split(/=&amp;gt;/,$attrVal);&lt;br /&gt;
          $attrVal = @attrValParts[0];&lt;br /&gt;
          $attrVal =~ s/!//g;&lt;br /&gt;
          $attrVal =~ s/, /,/g;&lt;br /&gt;
          my @attr = split(/,/, $attrVal);&lt;br /&gt;
          push(@attributes, @attr);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    my %hash   = map { $_ =&amp;gt; 1 } @attributes;&lt;br /&gt;
    my @unique = keys %hash;&lt;br /&gt;
    my $result = $currentAttrBeg.&amp;quot;\n&amp;quot;.$name.&amp;quot; = &amp;quot;.join(&amp;quot;, &amp;quot;, @unique).&amp;quot;\n&amp;quot;.@currentAttrEnd[1];&lt;br /&gt;
    $result =~ s/\n\n/\n/g;&lt;br /&gt;
    $result =~ s/  / /g;&lt;br /&gt;
    fhem(&#039;attr &#039;.$t2f_device.&#039; T2F_keywordlist &#039;.$result);&lt;br /&gt;
  }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2b. Erstellen eines DOIFs zum Aufruf der sub:&lt;br /&gt;
&lt;br /&gt;
  defmod talk.DI.fillAttr DOIF ([global:&amp;quot;^ATTR.*T2F_.*&amp;quot;]) ({my $val = ReadingsVal(&amp;quot;$SELF&amp;quot;, &amp;quot;e_global_events&amp;quot;, &amp;quot;&amp;quot;); $val =~ m/(\S*) (\S*) (\S*) (.*)/; if ($2 ne &#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;&#039; &amp;amp;&amp;amp; $2 ne &#039;global&#039;) { fill_T2F_keywordlist(&amp;quot;$3&amp;quot;, &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;&amp;quot;);}})&lt;br /&gt;
  attr talk.DI.fillAttr do always&lt;br /&gt;
&lt;br /&gt;
3. Optional: Erlauben von Umlauten in den T2F-Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_disableumlautescaping 1  &lt;br /&gt;
  &lt;br /&gt;
Nun können die T2F-Attribute pro FHEM-Device definiert und dann in den Talk2Fhem-Befehlen benutzt werden. Wurde der Punkt 2 abgearbeitet, so werden mit dem Füllen der Attribute am Geräte auch die Keywordlisten am talk-Device gefüllt. Wie diese dann verwendet werden können, sollen die folgenden Beispiele zeigen.&lt;br /&gt;
&lt;br /&gt;
==== Schalten von Geräten ====&lt;br /&gt;
&lt;br /&gt;
Ausgangssituation: Es gibt drei Lampen Lampe1, Lampe2, Lampe3 und ein Nachtlicht mit einer Eule mit folgenden Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr Lampe1 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe1 T2F_rooms Haus, Obergeschoss, !Esszimmer&lt;br /&gt;
  attr Lampe1 T2F_places Decke, Tür&lt;br /&gt;
  attr Lampe1 T2F_properties hell,!&lt;br /&gt;
&lt;br /&gt;
  attr Lampe2 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe2 T2F_rooms Haus, Obergeschoss, !Esszimmer&lt;br /&gt;
  attr Lampe2 T2F_places Tisch, Esstisch&lt;br /&gt;
  attr Lampe2 T2F_properties dunkel,schwach,!&lt;br /&gt;
&lt;br /&gt;
  attr Lampe3 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe3 T2F_rooms Haus, Obergeschoss, !Küche&lt;br /&gt;
  attr Lampe3 T2F_places Besenschrank&lt;br /&gt;
  &lt;br /&gt;
  attr Nachtlicht T2F_types_switch Lampe, !Licht, Eule, Nachtlicht&lt;br /&gt;
  attr Nachtlicht T2F_rooms Haus, Obergeschoss, !Kinderschlafzimmer&lt;br /&gt;
  attr Nachtlicht T2F_places Steckdose&lt;br /&gt;
&lt;br /&gt;
Durch die in Punkt 2 der Voraussetzungen genannten Funktionen wurden folgende T2F-keywordlisten automatisch angelegt:&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_keywordlist rooms = Kinderschlafzimmer, Haus, Küche, Obergeschoss, Esszimmer &lt;br /&gt;
                            places = Tür, Steckdose, Tisch, Decke, Esstisch&lt;br /&gt;
                            properties = hell, dunkel, schwach&lt;br /&gt;
                            types_switch = Lampe, Licht, Eule&lt;br /&gt;
&lt;br /&gt;
Die Definition für das T2F-Device lautet dann wie folgt:&lt;br /&gt;
&lt;br /&gt;
  #   1              2                 3                4            5          6          7      &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; ?(@properties) &amp;amp;&amp;amp; (@types_switch) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) &amp;amp;&amp;amp; (\S+)(schalten|machen)?$ =&lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_switch=.*$3@.*:FILTER=T2F_rooms=.*$4@.*:FILTER=T2F_properties=.*$2@.*:FILTER=T2F_places=.*$5@.* $6{true=&amp;gt;on, false=&amp;gt;off}&#039;,&lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;$AGAIN&amp;quot; ? &amp;quot;dann $DATE wieder $6{true=&amp;gt;ein, false=&amp;gt;aus}&amp;quot; : &amp;quot;$1{/bitte/=&amp;gt;Gern, else=&amp;gt;Das heißt Bitte}, ich schalte $1{/bitte/=&amp;gt;, else=&amp;gt;trotzdem} folgende Geräte $6{true=&amp;gt;ein, false=&amp;gt;aus}: &amp;quot;.T2F_answer(&amp;quot;T2F_types_switch=.*$3@.*:FILTER=T2F_rooms=.*$4@.*:FILTER=T2F_properties=.*$2@.*:FILTER=T2F_places=.*$5@.*&amp;quot;,&amp;quot;T2F_types_switch&amp;quot;)&#039;)&lt;br /&gt;
                            &lt;br /&gt;
Damit sind dann die folgenden Sprachbefehle möglich:&lt;br /&gt;
&lt;br /&gt;
  Schalte das Licht in der Küche ein                      =&amp;gt; schaltet Lampe3 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte die helle Lampe im Esszimmer an                 =&amp;gt; schaltet Lampe1 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht im Esszimmer über dem Esstisch ein    =&amp;gt; schaltet Lampe2 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte die Eule ein                                    =&amp;gt; schaltet Nachtlicht ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht im Esszimmer aus}                     =&amp;gt; schaltet Lampe1 und Lampe2 aus&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht aus                                   =&amp;gt; schaltet alle vier Lichter aus&lt;br /&gt;
&lt;br /&gt;
Um in der Antwort die Liste der geschalteten Geräte genannt zu bekommen, wird die sub T2F_answer aus der 99_myUtils aufgerufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub T2F_answer&lt;br /&gt;
{&lt;br /&gt;
  my ($filter, $type) = @_;&lt;br /&gt;
  my $answer = &#039;&#039;;&lt;br /&gt;
  my @devices = devspec2array($filter);&lt;br /&gt;
  if (@devices &amp;gt; 0 and defined($defs{$devices[0]}))&lt;br /&gt;
  {&lt;br /&gt;
    foreach (@devices){&lt;br /&gt;
      my $devAttr = AttrVal($_, $type, &#039;&#039;);&lt;br /&gt;
      if ($answer ne &#039;&#039;)&lt;br /&gt;
      {&lt;br /&gt;
        $answer = $answer.&amp;quot;, &amp;quot;;&lt;br /&gt;
      }&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      $devAttr = AttrVal($_, &#039;T2F_properties&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      $devAttr = AttrVal($_, &#039;T2F_rooms&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      $devAttr = AttrVal($_, &#039;T2F_places&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return $answer.&amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Benennung der Geräte erfolgt auf Basis derer T2F-Attribute: Typ, Eigenschaft, Raum, Ort. Ist das jeweilige Attribut leer, ist es auch in der Antwort leer. Enthält die jeweilige Attributliste ein Ausrufezeichen (!), so wird der Eintrag nach dem Ausrufezeichen für die Antwort verwendet (z.B. Esszimmer als Raum). Steht das Ausrufezeichen am Ende, so wird der Eintrag in der Antwort leer gelassen (z.B. die Eigenschaft bei Lampe1). Ist kein Ausrufezeichen vorhanden, so wird der erste Eintrag verwendet.&lt;br /&gt;
&lt;br /&gt;
==== Einstellen der Heizung ====&lt;br /&gt;
&lt;br /&gt;
Das gleiche Prinzp wie bei den Lampen kann auch für die Einstellung der Heizung verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Ausgangssituation: In der Küche, im Kinderschlafzimmer und im Esszimmer gibt es jeweils eine Heizung (Homematic HM-CC-RT-DN) mit folgenden Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr HeizungEsszimmer T2F_places Heizung,!&lt;br /&gt;
  attr HeizungEsszimmer T2F_rooms Haus,Obergeschoss,Essbereich,!Esszimmer&lt;br /&gt;
  attr HeizungEsszimmer T2F_types_heating Heizung,Temperatur,Esszimmer,Essbereich,!&lt;br /&gt;
&lt;br /&gt;
  attr HeizungKüche T2F_places Heizung,!&lt;br /&gt;
  attr HeizungKüche T2F_rooms Haus,Obergeschoss,Essbereich,!Küche&lt;br /&gt;
  attr HeizungKüche T2F_types_heating Heizung,Temperatur,Küche,Essbereich,!&lt;br /&gt;
&lt;br /&gt;
  attr HeizungKiSchla T2F_places Heizung,!&lt;br /&gt;
  attr HeizungKiSchla T2F_rooms Haus,Obergeschoss,!Kinderschlafzimmer&lt;br /&gt;
  attr HeizungKiSchla T2F_types_heating Heizung,Temperatur,Kinderschlafzimmer,!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mit der T2F-Definition&lt;br /&gt;
&lt;br /&gt;
  #   1             2                  3        4      5                  &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; (@types_heating) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; (auf (\d+) grad|auto\S*)( stellen| setzen| einstellen| ein)?$ = &lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.* $5{integer=&amp;gt;desired-temp $5, else=&amp;gt;controlMode auto}&#039;,&lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;$AGAIN&amp;quot; ? &amp;quot;dann $DATE wieder auf Automatik&amp;quot; : &amp;quot;Die Durchschnittstemperatur beträgt dort zur Zeit &amp;quot;.averageTemp(&amp;quot;T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.*&amp;quot;).&amp;quot; Grad\n$1{/bitte/=&amp;gt;Gern, else=&amp;gt;Das heißt Bitte}, ich stelle die Heizung in folgenden Räumen auf $5{integer=&amp;gt;$5 Grad, else=&amp;gt;Automatik}: &amp;quot;.T2F_answer(&amp;quot;T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.*&amp;quot;,&amp;quot;T2F_types_heating&amp;quot;)&#039;)&lt;br /&gt;
  &lt;br /&gt;
funktionieren folgende Sprachbefehle:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Esszimmer auf 21 Grad        =&amp;gt; Stellt die Heizung im Esszimmer auf 21 Grad&lt;br /&gt;
  &lt;br /&gt;
  Bitte stell die Heizung im Essbereich auf 21 Grad       =&amp;gt; Stellt die Heizungen im Esszimmer und in der Küche auf 21 Grad&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Obergeschoss auf Automatik   =&amp;gt; Stellt die drei Heizungen auf Automatik&lt;br /&gt;
  &lt;br /&gt;
Dadurch, dass im Attribut T2F_types_heating auch die Räume aufgeführt sind, sind auch Befehle in folgender Form möglich:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Küche auf 21 Grad                       =&amp;gt; Stellt die Heizung in der Küche auf 21 Grad&lt;br /&gt;
&lt;br /&gt;
Auch kann in diesem (wie auch in den oben aufgeführten Schaltbefehlen) mit &amp;quot;wieder&amp;quot; gearbeitet werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Essbereich auf 21 Grad und in 2 Stunden wieder auf Automatik&lt;br /&gt;
  &lt;br /&gt;
Für die Generierung der Antwort wird neben der bei den Schaltbefehlen bereits gezeigten sub T2F_answer eine weiter Funktion verwende, welche die Durchschnittstemperatur im zu schaltenden Bereich ermittelt und ausgibt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
  sub averageTemp($)&lt;br /&gt;
  {&lt;br /&gt;
    my ($filter) = @_;&lt;br /&gt;
    my @tempDevices = devspec2array($filter);&lt;br /&gt;
    my $count = 0;&lt;br /&gt;
    my $measuredTemp = 0;&lt;br /&gt;
    if (@tempDevices &amp;gt; 0 and defined($defs{$tempDevices[0]})){&lt;br /&gt;
      foreach (@tempDevices){&lt;br /&gt;
        $measuredTemp = $measuredTemp + ReadingsVal($_, &amp;quot;measured-temp&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        $count = $count + 1;&lt;br /&gt;
      }&lt;br /&gt;
      return $measuredTemp / $count;&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
==== Einstellen der Farbe von Farbwechsellampen (Philips Hue, Wifilight, ...) ====&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel zum Einstellen der Lichtfarbe nehmen wir eine Farbwechsellampe LampeBunt an, welche den Befehl RGB unterstützt. Diese erhält folgende Attribute:&lt;br /&gt;
&lt;br /&gt;
  attr LampeBunt T2F_places Decke,Couch,Sofa&lt;br /&gt;
  attr LampeBunt T2F_rooms Haus,Dachgeschoss,!Wohnzimmer&lt;br /&gt;
  attr LampeBunt T2F_types_color Lampe,Licht&lt;br /&gt;
  attr LampeBunt T2F_types_switch Lampe,Licht&lt;br /&gt;
  &lt;br /&gt;
Durch das Attribut T2F_types_switch lässt sich diese über die bereits beschriebene Schaltlogik ein und ausschalten. Durch die zusätzlich T2F-Definition&lt;br /&gt;
&lt;br /&gt;
  #   1              2               3             4              5               6 &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; (@types_color) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) &amp;amp;&amp;amp; auf (@colors)( schalten| stellen)?$ = &lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_color=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_places=.*$4@.* RGB $5[@rgb]&#039;, &lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;Ich schalte folgende Geräte auf $5@: &amp;quot;.T2F_answer(&amp;quot;T2F_types_color=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_places=.*$4@.*&amp;quot;,&amp;quot;T2F_types_color&amp;quot;)&#039;)&lt;br /&gt;
&lt;br /&gt;
und die entsprechenden Attribute am T2F-Device talk (HINWEIS: eigene Listen können Problemlos ergänzt werden, diese werden durch die Hilfsfunktionen NICHT überschrieben)&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_keywordlist colors = Aus, Schwarz, Dunkles Schiefergrau, Schiefergrau, Helles Schiefergrau, Helles Stahlblau, Mattes Grau, Grau, Dunkelgrau, Silber, Hellgrau, Gainsboro, Rauchiges Weiß, Geisterweiß, Weiß, Schneeweiß, Elfenbein, Blütenweiß, Muschel, Altgold, Leinenfarbe, Antikes Weiß, Mandelweiß, Cremiges Papaya, Beige, Mais, Helles Goldrutengelb, Hellgelb, Chiffongelb, Blasse Goldrutenfarbe, Khaki, Gelb, Gold, Orange, Dunkles Orange, Goldrute, dunkle Goldrutenfarbe, Peru, Schokolade, Sattelbraun, Ocker, Braun, Dunkelrot, Kastanienbraun, Ziegelfarbe, Indischrot, Karmesinrot, Rot, Orangenrot, Tomatenrot, Koralle, Lachs, Helles Korallenrot, Dunkle Lachsfarbe, Helle Lachsfarbe, Sandbraun, Rosiges Braun, Gelbbraun, Grobes Braun, Weizen, Pfirsich, Navajoweiß, Tomatencreme, Rosige Lavenderfarbe, Altrosa, Rosa, Hellrosa, Leuchtendes Rosa, Fuchsie, Magentarot, Tiefrosa, Mittleres Violettrot, Blasses Violettrot, Pflaume, Distel, Lavendelfarbe, Violett, Orchidee, Dunkles Magentarot, Violett, Indigo, Blauviolett, Dunkles Violett, Dunkle Orchideenfarbe, Mittleres Violett, Mittlere Orchideenfarbe, Mittleres Schieferblau, Schieferblau, Dunkles Schieferblau, Mitternachtsblau, Marineblau, Dunkelblau, Mittelblau, Blau, Königsblau, Stahlblau, Kornblumenblau, Dodger-Blau, Tiefes Himmelblau, Helles Himmelblau, Himmelblau, Hellblau, Zyanblau, Blaugrün, Taubenblau, Helles Cyanblau, Aliceblau, Himmelblau, Cremig Pfefferminz, Honigmelone, Aquamarinblau, Türkis, Blasses Türkis, Mittleres Türkis, Dunkles Türkis, Mittleres Aquamarinblau, Helles Seegrün, Dunkles Zyanblau, Entenbraun, Kadettblau, Mittleres Seegrün, Dunkles Seegrün, Hellgrün, Blassgrün, Mittleres Frühlingsgrün, Frühlingsgrün, Zitronengrün, Gelbgrün, Seegrün, Waldgrün, Grün, Dunkelgrün, Olivfarbiges Graubraun, Dunkles Olivgrün, Olivgrün, Dunkles Khaki, Gelbgrün, Hellgrün, Grüngelb&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_modwordlist rgb = 000000, 000000, 8FBC8F, 708090, 778899, B0C4DE, 696969, 808080, A9A9A9, C0C0C0, D3D3D3, DCDCDC, F5F5F5, F8F8FF, FFFFFF, FFFAFA, FFFFF0, FFFAF0, FFF5EE, FDF5E6, FAF0E6, FAEBD7, FFEBCD, FFEFD5, F5F5DC, FFF8DC, FAFAD2, FFFFE0, FFFACD, EEE8AA, F0E68C, FFFF00, FFD700, FFA500, FF8C00, DAA520, B8860B, CD853F, D2691E, 8B4513, A0522D, A52A2A, 8B0000, 800000, B22222, CD5C5C, DC143C, FF0000, FF4500, FF6347, FF7F50, FA8072, F08080, E9967A, FFA07A, F4A460, BC8F8F, D2B48C, DEB887, F5DEB3, FFDAB9, FFDEAD, FFE4C4, FFF0F5, FFE4E1, FFC0CB, FFB6C1, FF69B4, FF00FF, FF00FF, FF1493, C71585, DB7093, DDA0DD, D8BFD8, E6E6FA, EE82EE, DA70D6, 8B008B, 800080, 4B0082, 8A2BE2, 9400D3, 9932CC, 9370DB, BA55D3, 7B68EE, 6A5ACD, 483D8B, 191970, 000080, 00008B, 0000CD, 0000FF, 4169E1, 4682B4, 6495ED, 1E90FF, 00BFFF, 87CEFA, 87CEEB, ADD8E6, 00FFFF, 00FFFF, B0E0E6, E0FFFF, A0CE00, F0FFFF, F5FFFA, F0FFF0, 7FFFD4, 40E0D0, AFEEEE, 48D1CC, 00CED1, 66CDAA, 20B2AA, 008B8B, 008080, 5F9EA0, 3CB371, 8FBC8F, 90EE90, 98FB98, 00FA9A, 00FF7F, 00FF00, 32CD32, 2E8B57, 228B22, 008000, 006400, 6B8E23, 556B2F, 808000, BDB76B, 9ACD32, 7FFF00, ADFF2F&lt;br /&gt;
&lt;br /&gt;
kann die Farbe nun auch über folgenden Sprachbefehle eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte schalte die Lampe im Wohnzimmer an der Couch auf Olivfarbiges Graubraun&lt;br /&gt;
&lt;br /&gt;
Dadurch, das die Liste colors den Wert &amp;quot;Aus&amp;quot; mit dem entsprechenden Wert &amp;quot;000000&amp;quot; in der Liste rgb enthält, kann die Lampe über die gleiche Logik auch ausgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte schalte das Licht im Wohnzimmer auf Pflaume und in einer Stunde wieder aus&lt;br /&gt;
  &lt;br /&gt;
==== Abfragen beliebiger Geräteinformationen ====&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Möglichkeit auf, die Antworten für Statusabfragen direkt am abgefragten Gerät zu definieren. Hierfür werden zunächst eine Definition am T2F-Device&lt;br /&gt;
&lt;br /&gt;
  #              1             2                3            4&lt;br /&gt;
  Wie &amp;amp;&amp;amp; ?(@properties)&amp;amp;&amp;amp; (@types_info) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) = &lt;br /&gt;
  (answer=&amp;gt;&#039;T2F_getInfo(&amp;quot;T2F_types_info=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_properties=.*$1@.*:FILTER=T2F_places=.*$4@.*&amp;quot;,&amp;quot;$2@&amp;quot;)&#039;)&lt;br /&gt;
  &lt;br /&gt;
und eine Funktion in der 99_myUtils&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub T2F_getInfo&lt;br /&gt;
{&lt;br /&gt;
  my ($filter,$info) = @_;&lt;br /&gt;
  my @devices = devspec2array($filter);&lt;br /&gt;
  if (@devices &amp;gt; 0 and defined($defs{$devices[0]}))&lt;br /&gt;
  {&lt;br /&gt;
    my $answer = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
    foreach (@devices){&lt;br /&gt;
      if ($answer ne &#039;&#039;)&lt;br /&gt;
      {&lt;br /&gt;
        $answer = $answer.&amp;quot;, &amp;quot;;&lt;br /&gt;
      }&lt;br /&gt;
      my $device = $_;&lt;br /&gt;
      my @attrVals = split(/\n/,AttrVal($device, &#039;T2F_types_info&#039;, &#039;&#039;));&lt;br /&gt;
      foreach (@attrVals){&lt;br /&gt;
        my $attrVal = $_;&lt;br /&gt;
        $attrVal =~ s/  / /g;&lt;br /&gt;
        $attrVal =~ s/ =&amp;gt; /=&amp;gt;/g;&lt;br /&gt;
        my @attrValParts = split(/=&amp;gt;/,$attrVal);&lt;br /&gt;
        if (@attrValParts[0] =~ /$info/)&lt;br /&gt;
        {&lt;br /&gt;
          my $cmd = &amp;quot;&#039; &amp;quot;.@attrValParts[1].&amp;quot;&#039;&amp;quot;;&lt;br /&gt;
          $cmd =~ s/=/\//g;&lt;br /&gt;
          $cmd =~ s/\)\(/\/r=~s\//g;&lt;br /&gt;
          $cmd =~ s/\)/\/r.&#039;/g;&lt;br /&gt;
          $cmd =~ s/#\(/&#039;, &#039;&#039;)=~s\//g;&lt;br /&gt;
          $cmd =~ s/ #/ &#039;.ReadingsVal(&#039;$device&#039;, &#039;/g;&lt;br /&gt;
          $cmd =~ s/#/&#039;, &#039;&#039;).&#039;/g;&lt;br /&gt;
          $cmd =~ s/T2F_answer/&#039;.T2F_answer(&#039;$device&#039;, &#039;T2F_types_switch&#039;).&#039;/g;&lt;br /&gt;
          $answer = $answer.&#039; &#039;.eval($cmd);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    return $answer;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration und Funktionsweise sind nun wie folgt: Das Gerät, dessen Status abgefragt werden sollen erhält neben den Oben bereits beschriebenen Attributen für Eigenschaft, Raum und Ort noch das Attribut T2F_types_info, welches Zeilenweise die abzufragenen Status in der folgenden Form enthält:&lt;br /&gt;
&lt;br /&gt;
  abfragewert =&amp;gt; Das ist die Antwort von Gerät T2F_answer mit den Wert #reading#(suchen1=ersetzen1)...(suchenn=ersetzenn)&lt;br /&gt;
  &lt;br /&gt;
Mit der Form #reading#(suchen1=ersetzen1)...(suchenn=ersetzenn) können die Werte von Readings des abgefragten Device zum Zeitpunkt der Abfrage ermittelt werden und im Ergebnis Ersetzungen vorgenommen werden (z.B. (on=an)(off=aus)). T2F_answer wird mit der T2F-Konfiguration (siehe oben) ersetzt. Für das Beispiel einer Heizung im Esszimmer wäre das zum Beispiel wie folgt möglich:&lt;br /&gt;
&lt;br /&gt;
  attr HeizungEsszimmer T2F_places Heizung,!&lt;br /&gt;
  attr HeizungEsszimmer T2F_rooms Haus,Obergeschoss,Essbereich,!Esszimmer&lt;br /&gt;
  attr HeizungEsszimmer T2F_types_info warm,Temperatur =&amp;gt; Die Temperatur T2F_answer beträgt #measured-temp# Grad und soll #desired-temp# Grad erreichen\&lt;br /&gt;
                                       modus,Betriebsart =&amp;gt; Die Betriebsart T2F_answer ist #controlMode#(auto=Automatik)(manu=Hand)\&lt;br /&gt;
                                       Ventilstellung =&amp;gt; Das Ventil T2F_answer ist #ValvePosition# Prozent geöffnet&lt;br /&gt;
&lt;br /&gt;
Damit sind dann folgende Abfragen möglich:&lt;br /&gt;
&lt;br /&gt;
  Wie warm ist die Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
  Wie ist die Temperatur der Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
  Wie ist die Ventilstellung der Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
  Wie warm sind die Heizungen?&lt;br /&gt;
&lt;br /&gt;
== Häufig verwendete RegExp ==&lt;br /&gt;
Perl Regular Expression, also ein regulärer Ausdruck der Programmiersprache Perl, ist eine Werkzeug um Zeichenketten zu beschreiben. Hier wird ein kurzer Einblick auf die im Artikel häufig genutzten RegExp zu geben.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung der Syntax kann hier eingesehen werden. [http://jkorpela.fi/perl/regexp.html]&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! RegExp !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| \S* || Beliebig viele (*) nicht Leerzeichen (\S). Für unbekannten und unwichtigen Wortendungen&amp;lt;br&amp;gt;z.b. garage\S* ist bei Garage, Garagentor oder Garagentür erfolgreich&lt;br /&gt;
|-&lt;br /&gt;
| \S+ || Mehr als ein Zeichen (+) welches kein Leerzeichen ist (\S)&lt;br /&gt;
|-&lt;br /&gt;
| \S\S? || Ein oder zwei Zeichen die keine Leerzeichen sind. Das &amp;quot;?&amp;quot; wirkt hier nur auf das angrenzende &amp;quot;\S&amp;quot;.&amp;lt;br&amp;gt;Sollte für Umlaute verwendet werden, da bei manchen Eingabemethoden Probleme mit Umlauten auftreten können.&lt;br /&gt;
|-&lt;br /&gt;
| (wort )?  || Ein bestimmtes Wort oder nicht.&lt;br /&gt;
|-&lt;br /&gt;
| (wort1&amp;amp;#124;wort2) || Entweder wort1 oder Wort2&lt;br /&gt;
|-&lt;br /&gt;
| wort$ || Nur wenn das Wort am ende der Zeichenkette steht.&lt;br /&gt;
|-&lt;br /&gt;
| (\S+){0,2} || Keins, eins oder zwei Wörter. Kann für Artikel wie z.B. &amp;quot;(in der&amp;amp;#124;in dem&amp;amp;#124;im&amp;amp;#124;auf der&amp;amp;#124;...)?&amp;quot; eingesetzt werden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Eingabemethoden ==&lt;br /&gt;
Die Herkunft der Sprachbefehle für das Modul sind vielfältig. Hier werden einige Methoden beschrieben wie der Sprachbefehl in das Modul gelangen kann.&lt;br /&gt;
=== Messenger Telegram ===&lt;br /&gt;
Ist ein [[TelegramBot]] telbot definiert, reicht ein einfaches &amp;quot;notify&amp;quot; um die Nachrichten an FHEM an Talk2Fhem weiterzuleiten.&lt;br /&gt;
 define &amp;lt;span style=&#039;color:red&#039;&amp;gt;n_telbot&amp;lt;/span&amp;gt; notify &amp;lt;span style=&#039;color:red&#039;&amp;gt;telbot&amp;lt;/span&amp;gt;:msgText.* set talk $EVENT&lt;br /&gt;
Schon kann mit FHEM gechattet werden... ;)&lt;br /&gt;
&lt;br /&gt;
=== Google Home Geräte ===&lt;br /&gt;
Momentan ist es leider noch notwendig über einen Umweg die Sprache von einem GoogleHome in FHEM zu bringen. Hierzu ist es notwendig einen funktionierenden DNS Service am laufen zu haben. Damit FHEM per Webadresse im Internet erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
*Ein FHEMWEB Device anlegen&lt;br /&gt;
 define api FHEMWEB 8087 global&lt;br /&gt;
 attr api HTTPS 1&lt;br /&gt;
 attr api allowfrom  1&lt;br /&gt;
 attr api csrfToken  None&lt;br /&gt;
*Ein allowed Device anlegen&lt;br /&gt;
 define allowed_api allowed api&lt;br /&gt;
 attr allowed_api allowedCommands set&lt;br /&gt;
 attr allowed_api allowedDevices talk&lt;br /&gt;
 attr allowed_api basicAuth  {&amp;quot;$user:$password&amp;quot; eq &#039;user:passwort&#039;}&lt;br /&gt;
 attr allowed_api validFor   api&lt;br /&gt;
*Mit Googlekono bei IFTTT.com anmelden&lt;br /&gt;
*New Applet&lt;br /&gt;
*+this GoogleAssistant -&amp;gt; Say a phrase with a text ingredient&lt;br /&gt;
* Die drei Triggertexte wählen z.b.&lt;br /&gt;
**das Haus $&lt;br /&gt;
**sag dem Haus $&lt;br /&gt;
**frag das Haus $&lt;br /&gt;
***Problem bei zu kurzen Texten hat GoogleHome keine anderen Anfragen mehr angenommen.&lt;br /&gt;
*Einen Antworttext überlegen z.B. OK und in &amp;quot;What do you want the Assistant to say in response?&amp;quot; eintragen&lt;br /&gt;
*Language Deutsch&lt;br /&gt;
*+that Webhooks&lt;br /&gt;
*URL wählen&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;https://user:password@dnsservice:54387/fhem?cmd.talk=set talk {{TextField}}&amp;amp;XHR=1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
*Fertig&lt;br /&gt;
&lt;br /&gt;
Jetzt wird der gesamte Text bei dem genannten Triggerworten an FHEM weitergeleitet.&lt;br /&gt;
&lt;br /&gt;
== Ausgabemethoden ==&lt;br /&gt;
&lt;br /&gt;
Siehe hierzu [[Modul_Talk2Fhem#Beispiel|Anwendungsbeispiel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Sprachsteuerung|Talk2FHEM]]&lt;/div&gt;</summary>
		<author><name>RoBra81</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Talk2Fhem&amp;diff=24867</id>
		<title>Talk2Fhem</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Talk2Fhem&amp;diff=24867"/>
		<updated>2018-01-30T14:14:48Z</updated>

		<summary type="html">&lt;p&gt;RoBra81: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Das Modul stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her&lt;br /&gt;
|ModType=h]&lt;br /&gt;
|ModCmdRef=Talk2Fhem&lt;br /&gt;
|ModForumArea=Unterst&amp;amp;uuml;tzende Dienste&lt;br /&gt;
|ModTechName=39_Talk2Fhem.pm&lt;br /&gt;
|ModOwner=Oliver Georgi&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Seite beschreibt die Funktionsweise und Konfiguration des Moduls 39_Talk2Fhem.pm&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen ==&lt;br /&gt;
[[Datei:ModulTalk2FhemScreenshot.png|360px|thumb|right]]&lt;br /&gt;
Es ist sehr zu empfehlen, für die Konfiguration des Moduls, im Webfrontend von FHEM die Syntaxhervorhebung zu aktivieren. Die Aktivierung des erweiterten Editors ist [[Konfiguration#Syntaxhervorhebung|hier]] beschrieben.&lt;br /&gt;
&lt;br /&gt;
Kenntnisse im Bereich Regulärer Ausdrücke (RegExp) in Perl sind hilfreich, aber nicht zwingend erforderlich. Ein kurzer Einstieg kann hier eingesehen werden. [[Modul_Talk2Fhem#Häufig_verwendete_RegExp|Häufig_verwendete_RegExp]]&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
Das Modul Talk2Fhem stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her. Es ist ein überaus flexibles und relativ einfach zu konfigurierendes Script mit dem man sehr natürlich kommunizieren kann. Die Konfiguration erfolgt dabei über das FHEM Webfrontend. &lt;br /&gt;
&lt;br /&gt;
Es werden diverse [[Modul_Talk2Fhem#Zeitenerkennung|Zeit- und Datumsangaben]] erkannt. Außerdem ist es möglich [[Modul_Talk2Fhem#Eventenerkennung|Events zu formulieren]], welche die Befehle zu einem bestimmten Ereignis ausführen lassen. Bei der weiteren Verarbeitung der Sprachbefehle wird die Sprache mit selbst definierte Schlüsselwörter verglichen. &lt;br /&gt;
&lt;br /&gt;
=== Funktionsweise ===&lt;br /&gt;
&lt;br /&gt;
Die Zerlegung des Sprachbefehls erfolgt in mehreren Schritten. &lt;br /&gt;
# Aufteilen des Sprachbefehls in einzelne Kommandos anhand des Wortes UND&lt;br /&gt;
# Erkennen von Zeit- und Datumsangaben und entfernen für die weitere Verarbeitung&lt;br /&gt;
# Entfernung unnötiger Wörter&lt;br /&gt;
# Vergleich mit den definierten Schlüsselwörtern&lt;br /&gt;
# Konvertieren in ein FHEM Kommando&lt;br /&gt;
# Zeit- und Eventgebundenes auslösen des FHEM Kommandos&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Solange das Modul noch nicht offiziell aufgenommen wurde, muss die Datei 39_Talk2Fhem.pm manuell in das Verzeichnis FHEM/ kopiert werden. Siehe Forumsbeitrag. [https://forum.fhem.de/index.php/topic,80960.0.html]&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
 define talk Talk2Fhem&lt;br /&gt;
Zum testen der Konfiguration ist es Ratsam vorerst das Attribut disable auf 1 zu setzen. Hierbei wird die Auslösung der FHEM Kommandos unterdrückt.&lt;br /&gt;
 attr talk disable 1&lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
Der Sprachbefehl wird über das Kommando &#039;&#039;&#039;set&#039;&#039;&#039; oder &#039;&#039;&#039;set !&#039;&#039;&#039; an das Modul geleitet.&lt;br /&gt;
 set talk Guten Morgen liebes Zuhause&lt;br /&gt;
&#039;&#039;Wird kein Text angehängt, wird der letzte Sprachbefehl erneut ausgeführt.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Readings ===&lt;br /&gt;
&lt;br /&gt;
Im Reading &#039;&#039;&#039;set&#039;&#039;&#039; steht der letzte gesendete Sprachbefehl.&lt;br /&gt;
&amp;lt;br&amp;gt;Im Reading &#039;&#039;&#039;cmds&#039;&#039;&#039; steht das letzte ausgeführte FHEM-Kommando dessen Rückgabe in in das Reading &#039;&#039;&#039;fhem&#039;&#039;&#039; geschrieben wird. &lt;br /&gt;
&lt;br /&gt;
Die Antworten und Modulinterne Fehler werden in den Readings &#039;&#039;&#039;answers&#039;&#039;&#039; und &#039;&#039;&#039;err&#039;&#039;&#039; ausgegben. &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;ifs&#039;&#039;&#039; stehen die Bedingungen bei dem das letzte Kommando ausgeführt werden wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;notifies&#039;&#039;&#039; enthält eine Auflistung der Devices die für die aktuell wartenden bedingten Kommandos relevant sind. Auf diesen Devices liegt ein internes notify.   &lt;br /&gt;
&lt;br /&gt;
Das Reading &#039;&#039;&#039;status&#039;&#039;&#039; wird jedes mal gesetzt und erhält Werte nach folgender Priorität.&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|1.||&#039;&#039;&#039;response&#039;&#039;&#039; ||wenn das FHEM Kommando eine Meldung ausgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|2.||&#039;&#039;&#039;disabled&#039;&#039;&#039; ||wenn das Attribute disable auf 1 steht&lt;br /&gt;
|-&lt;br /&gt;
|3.||&#039;&#039;&#039;err&#039;&#039;&#039; ||wenn der Sprachbefehl einen Fehler zurückgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|4.||&#039;&#039;&#039;answer&#039;&#039;&#039; ||wenn der Sprachbefehl eine Antwort ausgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|5.||&#039;&#039;&#039;done&#039;&#039;&#039; ||wenn keines der oberen Fälle eingetreten ist, also alles gut verlaufen ist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Beispiel ===&lt;br /&gt;
Die FHEM Befehle werden eigenständig ausgeführt, sie können aber zur Überprüfung auch weitergeleitet werden. Das Beispiel zeigt auch wie auf Fehler und Antworten von Talk2Fhem reragiert werden kann.&lt;br /&gt;
Erstellen eines Notify&lt;br /&gt;
 define n_talk notify talk:.* {}&lt;br /&gt;
Folgendes in der Definition von n_talk einfügen&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 talk:.* {&lt;br /&gt;
 # Sende die Antwort per Telegram und gebe es über das GoogleHome aus&lt;br /&gt;
 	if ($EVENT =~ s/^answers: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telegram _msg \@USER $EVENT&amp;quot;);&lt;br /&gt;
 		fhem(&amp;quot;set d_googlespeak $EVENT&amp;quot;);	&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 # Schicke den Fehler per Telegram und sag am GoogleHome das es nicht geklappt hat.&lt;br /&gt;
 	if ($EVENT =~ s/^err: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telbot _msg \@Oliver $EVENT&amp;quot;);&lt;br /&gt;
 		my @a = (&amp;quot;Das hat leider nicht geklappt&amp;quot;, &amp;quot;Es gab leider einen Fehler&amp;quot;, &amp;quot;Es tut mir leid. Das hat nicht funktioniert.&amp;quot;, &amp;quot;Es ist leider zu einem Fehler gekommen&amp;quot;,&amp;quot;Könntest du das vielleicht nochmal anders sagen&amp;quot;, &amp;quot;Mhhh, das kann ich so nicht verstehen&amp;quot;);&lt;br /&gt;
 		fhem(&amp;quot;set d_googlespeak $a[int(rand($#a))]&amp;quot;);&lt;br /&gt;
 	} &lt;br /&gt;
 &lt;br /&gt;
 # Schick mir alle ausgeführten Befehle als Telegram&lt;br /&gt;
 &lt;br /&gt;
 	if ($EVENT =~ s/^cmds: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telbot _msg \@USER $EVENT&amp;quot;);&lt;br /&gt;
 	} &lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Eine weitere Möglichkeit Talk2Fhem mit anderen Modulen zu verbinden, ist über das Reading &#039;&#039;&#039;status&#039;&#039;&#039; möglich.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Lösung hat den Vorteil das eine Standardantwort definiert werden kann. &lt;br /&gt;
&#039;&#039;&#039;!Achtung noch nicht getestet vom Author!&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
talk:status {&lt;br /&gt;
my $text = ReadingsVal(&amp;quot;talk&amp;quot;, $EVENT, &amp;quot;Komisch, hier sollte eigentlich etwas Text stehen.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;$EVENT&amp;quot; eq &amp;quot;response&amp;quot;) {&lt;br /&gt;
  #FHEM gibt bei Erfolg eig. keine Rückmeldung, also ist vermutlich was schief gelaufen&lt;br /&gt;
  $text = &amp;quot;Die Haussteuerung hat folgende Meldung gebracht. $text&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; eq &amp;quot;err&amp;quot;) {&lt;br /&gt;
  $text = [&amp;quot;Das habe ich nicht verstanden!&amp;quot;,&amp;quot;Phuu das kann ich noch nicht!&amp;quot;,&amp;quot;Nein! Heute nicht.&amp;quot;, &amp;quot;Wie bitte?&amp;quot;]-&amp;gt;[rand(4)];&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; =~ /^answer/) {&lt;br /&gt;
  $text = ReadingsVal(&amp;quot;talk&amp;quot;, &amp;quot;answers&amp;quot;, &amp;quot;Ich habe nichts zu sagen.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; eq &amp;quot;err&amp;quot;) {&lt;br /&gt;
  #in $text steht schon der fehler drin&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; eq &amp;quot;done&amp;quot;) {&lt;br /&gt;
  $text = [&amp;quot;Ok.&amp;quot;,&amp;quot;Ja.&amp;quot;,&amp;quot;Gerne.&amp;quot;, &amp;quot;Mach ich!&amp;quot;]-&amp;gt;[rand(4)];&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
  $text = &amp;quot;Oh, es gibt etwas neues, bitte schau mal im Forum bei Talk2Fhem vorbei.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fhem(&#039;set speaker speak &amp;quot;$text&amp;quot;&#039;) if $text;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zeitenerkennung ===&lt;br /&gt;
Die Zeit- und Datum Eingabe kann auf viele verschiedene Arten erfolgen.&amp;lt;br&amp;gt;&lt;br /&gt;
Die Datumerkennung umfasst folgende Phrasen:&lt;br /&gt;
*morgen, übermorgen&lt;br /&gt;
*in ... Wochen, Monat, Jahr&lt;br /&gt;
*nächste Woche, Monat, Jahr&lt;br /&gt;
*Wochentage&lt;br /&gt;
*in ... Tagen&lt;br /&gt;
*am DATUM&lt;br /&gt;
&lt;br /&gt;
Die Zeiterkennung umfasst folgende Phrasen:&lt;br /&gt;
*in,nach ... stunden,minuten,sekunden&lt;br /&gt;
*um ... (Uhr) (...)&lt;br /&gt;
*heute - entspricht 12:00&lt;br /&gt;
*früh - entspricht 9 Uhr&lt;br /&gt;
*abend - entspricht 18 Uhr&lt;br /&gt;
*nachmittag - entspricht 16 Uhr&lt;br /&gt;
*vormittag - entspricht 10:30 Uhr&lt;br /&gt;
*mittag - entspricht 12 Uhr&lt;br /&gt;
*gleich - entspricht 5 Minuten&lt;br /&gt;
*nachher - entspricht 30 Minuten&lt;br /&gt;
*später - entspricht 1 Stunde&lt;br /&gt;
*jetzt&lt;br /&gt;
*sofort&lt;br /&gt;
&lt;br /&gt;
Datum und Zeitangaben können natürlich kombiniert werden.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wird eine Zeit erfolgreich erkannt erfolgt die Ausführung des FHEM-Kommandos über das Modul &#039;&#039;&#039;at&#039;&#039;&#039;. Es wird ein at Eregnis angelegt welches den Namen &#039;&#039;at_&amp;lt;modulname&amp;gt;_&amp;lt;zeitindex&amp;gt;&#039;&#039; erhält.&lt;br /&gt;
&lt;br /&gt;
Bei mehreren Kommandos über das Schlüsselwort &#039;&#039;UND&#039;&#039; wirkt sich der Zeitpunkt des ersten Kommandos auch auf das zweite und dritte ... aus.&lt;br /&gt;
 Schalte die Heizung um 20 Uhr aus und mache die Rollläden runter&lt;br /&gt;
Beide Kommandos werden um 20 Uhr ausgelöst.&lt;br /&gt;
&lt;br /&gt;
Hat das zweite Kommando ebenfalls eine Zeitphrase wird diese Zeit genommen.&lt;br /&gt;
 schalte die Heizung heute Abend ab und mache die Rollläden jetzt runter&lt;br /&gt;
==== Zeitenmodifikation ====&lt;br /&gt;
Wie oben gesehen wird der Zeitpunkt des ersten Kommandos vor dem &amp;quot;und&amp;quot; auch für das zweite nach dem &amp;quot;und&amp;quot; gesetzt. Vorausgesetzt er wird beim 2. Kommando nicht durch eine eigenständige Zeit (hier &amp;quot;jetzt&amp;quot;) ersetzt.&lt;br /&gt;
Wenn man die Zeit des zweiten Kommandos, relativ zum ersten setzen möchte, kann dies mit den Schlüsselwörtern &#039;&#039;dann&#039;&#039;, &#039;&#039;danach&#039;&#039; oder &#039;&#039;wieder&#039;&#039;  formuliert werden.&lt;br /&gt;
 Fahre um 14 Uhr die Rollläden an der Terrasse runter und schalte dann in 2 Minuten die Bewässerung an&lt;br /&gt;
oder&lt;br /&gt;
 Mach am Freitag um 5 Uhr die Heizung aus und in einer Woche wieder an&lt;br /&gt;
&lt;br /&gt;
Manchmal ist es notwendig etwas vor der angegebenen Zeit auszuführen. Hier lässt sich ein Offset zu dem ermittelten Zeitpunkt hinzufügen, um ihn zu ändern.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;perl&#039;&amp;gt;dusche\S?$ = (offset=&amp;gt;-3600, cmd=&amp;gt;&#039;set d_log bad warm&#039;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Der Sprachbefehl&lt;br /&gt;
 ich will um 18:30 Uhr duschen&lt;br /&gt;
Legt folgendes at Ergnis an&lt;br /&gt;
 define at_assi_1513096200 at 2017-12-12T17:30:00 set d_log bad warm&lt;br /&gt;
&lt;br /&gt;
=== Eventkonfiguration ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ereigniswiederholung ===&lt;br /&gt;
Werden zwei Sätze über ein &#039;&#039;&#039;und&#039;&#039;&#039; miteinander verknüpft kann der zweite Satz mit dem Wort &#039;&#039;&#039;wieder&#039;&#039;&#039; das Ereignis wiederholen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
 mach bitte die Garage auf und in 5 Minuten wieder zu&lt;br /&gt;
Man benötigt hier nicht erneut den kompletten ersten Satz zu wiederholen.&lt;br /&gt;
&lt;br /&gt;
== Konfiguration ==&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration des Moduls wird hauptsächlich über die Definition (DEF) vorgenommen.&lt;br /&gt;
Eine Konfiguration beginnt immer mit der Definition der gesuchten Schlüsselwörtern gefolgt von einem Gleichheitszeichen &#039;&#039;(siehe Randnotiz)&#039;&#039;. Diese werden Anhand von Regulären Ausdrücken (RegExp) beschrieben. Also z.B.:&lt;br /&gt;
 garage auf =&lt;br /&gt;
Das bededutet, sobald die Wörter in der Reihenfolge &amp;quot;garage&amp;quot; und &amp;quot;auf&amp;quot; erkannt werden, wird der Kommandoteil der Konfiguration ausgeführt. Groß- und Kleinschreibung wird grundsätzlich ignoriert.&lt;br /&gt;
&lt;br /&gt;
{{Randnotiz|RNText=Wichtig&lt;br /&gt;
Vor und nach dem Gleichheitszeichen muss mindestens ein Trennzeichen vorhanden sein&lt;br /&gt;
*Vor dem &amp;quot;=&amp;quot; mindestens ein Leer- oder Tabulatorzeichen&lt;br /&gt;
*Nach dem &amp;quot;=&amp;quot; können zusätzlich auch Zeilenumbrüche eingefügt werden&lt;br /&gt;
}}&lt;br /&gt;
Der Kommandoteil folgt dem Gleichheitszeichen &#039;&#039;(siehe Randnotiz)&#039;&#039;. Und kann auf folgende Arten vorliegen.&lt;br /&gt;
* FHEM Kommando&lt;br /&gt;
* { Perl Befehl }&lt;br /&gt;
* ( [[Modul_Talk2Fhem#erweiterte_Befehlskonfiguration]] )&lt;br /&gt;
&lt;br /&gt;
=== Übersicht ===&lt;br /&gt;
 &amp;lt;regexp&amp;gt; = &amp;lt;command&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im ganzen könnte die Konfiguration dann so aussehen:&lt;br /&gt;
 garage\S* auf = set dev_garage open&lt;br /&gt;
&#039;&#039;\S* Siehe hierzu [[Modul_Talk2Fhem#Häufig_verwendete_RegExp|Häufig verwendete RegExp]].&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bei dem vorherigen Beispiel, würde der FHEM Befehl &amp;quot;set garage open&amp;quot; bei allen folgenden Sprachbefehlen ausgeführt werden.&lt;br /&gt;
 Mach bitte die Garage auf&lt;br /&gt;
 Das haus soll das Garagentor aufmachen&lt;br /&gt;
 Garagentür in 5 Minuten auf&lt;br /&gt;
 Die Garagen soll in einer Stunde aufgemacht werden&lt;br /&gt;
&lt;br /&gt;
=== Klammerüberführung ===&lt;br /&gt;
&lt;br /&gt;
Es ist nicht notwendig für jeden Zustand oder jedes Gerät eine eigene Konfigurationzeile zu erzeugen. Hierfür gibt es die Möglichkeit, wie bei Regulären Ausdrücken üblich, Klammern &amp;quot;( )&amp;quot; im &amp;lt;regex&amp;gt;-Teil zu erfassen. Dies erfolgt über die Standartvariablen $1, $2, ..., $n. &amp;quot;n&amp;quot; steht hier für die nte Klammer.&lt;br /&gt;
Zusätzlich gibt es in Talk2Fhem die Möglichkeit die Klammern zu modifizieren.&lt;br /&gt;
&lt;br /&gt;
Soll die Garage auf und zugemacht werden, lässt sich folgendermaßen beschreiben.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
 garage\S* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(\S+)&amp;lt;/span&amp;gt; = set dev_garage &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Satz: &amp;quot;Mach die Garage auf&amp;quot; ergibt dann als FHEM Kommando&lt;br /&gt;
 set dev_garage auf&lt;br /&gt;
&lt;br /&gt;
=== Klammermodifikation ===&lt;br /&gt;
&lt;br /&gt;
Da es in den meißten Fällen nicht gewünscht ist, nur das gefunde Wort in das FHEM Kommando zu überführen, lässt sich zusätzlich das gefundene Wort modifizieren.&lt;br /&gt;
&lt;br /&gt;
==== Variante 1: nach Typ ====&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kann die Klammer auf ihren Typ hin modifiziert werden.&lt;br /&gt;
&lt;br /&gt;
===== Definition =====&lt;br /&gt;
&lt;br /&gt;
 $n{ &#039;&#039;&#039;typ&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;modification&#039;&#039;&#039;, typ2 =&amp;gt; mod2, ..., typn =&amp;gt; modn }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;typ&#039;&#039;&#039; kann eines der folgenden Wörtern enthalten:&lt;br /&gt;
*&#039;&#039;&#039;true&#039;&#039;&#039; sind alle Wörter die eine positive Richtung enthalten. Wie z.B. auf, ein, hoch, an, usw.&lt;br /&gt;
*&#039;&#039;&#039;false&#039;&#039;&#039; sind alle Wörter die eine negative Richtung enthalten. Wie z.B. ab, aus, runter, zu, usw.&lt;br /&gt;
*&#039;&#039;&#039;integer&#039;&#039;&#039; Wort enthält eine Zahl&lt;br /&gt;
*&#039;&#039;&#039;float&#039;&#039;&#039; Wort enthält eine Gleitkommazahl&lt;br /&gt;
*&#039;&#039;&#039;/&amp;lt;regexp&amp;gt;/&#039;&#039;&#039; Wort entspricht der &amp;lt;regexp&amp;gt;&lt;br /&gt;
*&#039;&#039;&#039;word&#039;&#039;&#039; Wort enthält gleich oder mehr als 4 Zeichen &lt;br /&gt;
*&#039;&#039;&#039;empty&#039;&#039;&#039; Wort enthält eine Leere Zeichenkette&lt;br /&gt;
*&#039;&#039;&#039;else&#039;&#039;&#039; Falls keines der Fälle zutrifft&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;modification&#039;&#039;&#039; enthält das einzufügende Wort.&lt;br /&gt;
&lt;br /&gt;
===== Beispiel =====&lt;br /&gt;
 garage\S* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(\S*)&amp;lt;/span&amp;gt; = set dev_garage &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;{ true =&amp;gt; open , false =&amp;gt; close }&lt;br /&gt;
Die Sätze:&lt;br /&gt;
 mach die Garage auf&lt;br /&gt;
 bitte Garagentor schließen &lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set dev_garage open&lt;br /&gt;
 set dev_garage close&lt;br /&gt;
&lt;br /&gt;
==== Variante 2: nach Liste ====&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kann die Klammer anhand einer oder zweier Listen selektiert werden.&lt;br /&gt;
&lt;br /&gt;
===== Definition =====&lt;br /&gt;
&lt;br /&gt;
 $n[ wert1, wert2,,,,, wertn ]&lt;br /&gt;
oder&lt;br /&gt;
 $n[ @liste ]&lt;br /&gt;
&lt;br /&gt;
Innerhalb der Klammern [ ] wird eine Komma separierte Liste mit Namen erwartet die als Modifikatorliste dient. Die sogenannte Modwordlist. Die Werte sind immer optional und können leer gelassen werden. Über das Attribut &#039;&#039;T2F_modwordlist&#039;&#039; können diese Listen zur Übersicht und Wiederverwendbarkeit angelegt werden. Siehe Attribute. Auf diese Listen, lässt sich über den Namen der Liste, mit einem vorangestelltes &#039;@&#039; zugreifen.&lt;br /&gt;
&lt;br /&gt;
===== Beispiel nach Position =====&lt;br /&gt;
&lt;br /&gt;
Beim ersten Beispiel wird eine Zahl im regex-Teil erwartet (\d+). Diese Zahl entscheidet welche Position aus der Modwordlist ausgewählt werden soll.&lt;br /&gt;
 ventilator auf (stufe )?&amp;lt;span style=&#039;color:red&#039;&amp;gt;(\d+)&amp;lt;/span&amp;gt; = set aircon &amp;lt;span style=&#039;color:red&#039;&amp;gt;$2&amp;lt;/span&amp;gt;[ off, level1, level2, level3 ]                                                                                              &lt;br /&gt;
                &amp;lt;span style=&#039;color:gray&#039;&amp;gt;           |------------------&amp;gt;  0      1       2       3&amp;lt;/span&amp;gt;            &lt;br /&gt;
&#039;&#039;(Stufe )?&#039;&#039; bedeutet: Das Wort Stufe kann, muss aber nicht.&lt;br /&gt;
&lt;br /&gt;
Die Sätze:&lt;br /&gt;
 Ventilator in 10 Minuten auf Stufe 0&lt;br /&gt;
 Ventilator auf 3&lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set aircon off&lt;br /&gt;
 set aircon level3&lt;br /&gt;
&lt;br /&gt;
===== Beispiel nach Vergleichsliste =====&lt;br /&gt;
&lt;br /&gt;
Hier kommt eine weitere Liste ins Spiel. Die sogenannte Keywordlist ist im Eigentlichen eine RegExp &amp;quot;Ver-oder-ung&amp;quot;.&lt;br /&gt;
 ( key1 | key2 | ... | keyn )&lt;br /&gt;
oder&lt;br /&gt;
 ( @keywordlist )&lt;br /&gt;
Diese Liste mit Schlüsselwörtern wird im &amp;lt;regex&amp;gt;-Teil angegeben. Hier entscheidet nicht eine Zahl über die Position, sondern die Position die in der Keywordlist einen Treffer hat wird an selber Position in der Modwordlist ausgewählt. Im Attribut T2F_keywordlist können vordefinierte Listen angelegt werden und mit @keylist ausgewählt werden&lt;br /&gt;
&lt;br /&gt;
 blendet.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(Wohnzimmer|Esszimmer|Küche)&amp;lt;/span&amp;gt; = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;[act_lvgroom, act_dinroom, act_kitchen] 70&lt;br /&gt;
               &amp;lt;span style=&#039;color:gray&#039;&amp;gt;|__________|_______|___________________|_____________|____________|&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;.*&#039;&#039; beliebig viele Zeichen&lt;br /&gt;
&lt;br /&gt;
Die Sätze: &lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 ich sitze geblendet im Wohnzimmer&lt;br /&gt;
 die sonne blendet in der Küche&lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set act_dinroom 70&lt;br /&gt;
 set act_lvgroom 70&lt;br /&gt;
 set act_kitchen 70&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Auswahl des Listenelements &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Soll bei der Nutzung der Variable nicht der Wert aus dem Sprachbefehl, sondern der Wert der Liste genutzt werden, so wird an die Variable ein @ angehängt. So wird bei&lt;br /&gt;
 blendet.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(Wohnzimmer|Esszimmer|Küche)&amp;lt;/span&amp;gt; = set act_&amp;lt;span style=&#039;color:red&#039;&amp;gt;$1@&amp;lt;/span&amp;gt; 70&lt;br /&gt;
&lt;br /&gt;
Die Sätze &lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 es blendet im esszimmer&lt;br /&gt;
immer zu&lt;br /&gt;
 set act_Esszimmer 70&lt;br /&gt;
&lt;br /&gt;
führen, da die Liste das Esszimmer großgeschrieben enthält.&lt;br /&gt;
&lt;br /&gt;
===== Ergänzung =====&lt;br /&gt;
Ähnlich wie in Variante 1, könne  auch hier auf die Schlüsselwörte &lt;br /&gt;
 empty für leere Zeichenkette &lt;br /&gt;
und &lt;br /&gt;
 else für alle anderen Fälle&lt;br /&gt;
zugegriffen werden. Hierbei wird der Modwordlist einfach empty oder else gefolgt von dem gewünschten Wert als nächstes Element angehängt.&lt;br /&gt;
 $n[ wert1, wert2,,,, empty, wert3, else, wert4 ]&lt;br /&gt;
&lt;br /&gt;
=== erweiterte Befehlskonfiguration ===&lt;br /&gt;
Um Talk2Fhem in den Konfigurationszeilen weitere Parameter zu übergeben, ist eine gesonderte Syntax zu verwenden.&lt;br /&gt;
 &amp;lt;regexp&amp;gt; = ( option =&amp;gt; &#039;value&#039;  ,&lt;br /&gt;
              opt2   =&amp;gt; &#039;value2&#039; ,&lt;br /&gt;
              ... &lt;br /&gt;
              optn   =&amp;gt; &#039;valuen&#039; ) &lt;br /&gt;
Es stehen folgende Optionen zur Verfügung:&lt;br /&gt;
*cmd    =&amp;gt; enthält das FHEM Kommando.  Wie oben beschrieben.&lt;br /&gt;
*answer  =&amp;gt;  Ein in Anführungszeichen (&amp;quot; oder &#039;) gesetzter Perl-Befehl, dessen Rückgabe in das Reading &#039;&#039;answer&#039;&#039; geschrieben wird.&lt;br /&gt;
* offset =&amp;gt;  Ganzzahliger Wert in Sekunden der dem Zeitpunkt addiert wird. Siehe [[Modul_Talk2Fhem#Zeitenmodifikation]]&lt;br /&gt;
&lt;br /&gt;
=== Antworten ===&lt;br /&gt;
In Talk2Fhem können Antworten, die das Modul ausgeben soll, definiert werden. Hier können Fragen verarbeitet werden oder auch den Erfolg eines Kommandos bestätigt werden.&lt;br /&gt;
&lt;br /&gt;
Über die [[Modul_Talk2Fhem#erweiterte_Befehlskonfiguration]], erhält der Parameter &amp;quot;answer&amp;quot; einen Perl Befehl, dessen Rückgabe die Antwort darstellt.&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Erfolgsmeldung ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;tu was = ( cmd =&amp;gt; &amp;quot;set tue es&amp;quot; , answer =&amp;gt; &#039;&amp;quot;Erledigt&amp;quot;&#039; )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Man beachte hier, dass die Parameter immer in Anführungszeichen gesetzt werden müssen. In diesem Fall der Perl Befehl. Ein Text in Perl wird ebenfalls in Anführungszeichen gesetzt, deswegen die doppelten Anführungszeichen!&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Zustandsabfrage ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;wurde es getan = ( answer =&amp;gt; &#039;Value(&amp;quot;tue&amp;quot;) eq &amp;quot;es&amp;quot; ? &amp;quot;Ja&amp;quot; : &amp;quot;Nein&amp;quot;&#039;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Temperaturabfragen ====&lt;br /&gt;
Eine einfache Temperaturabfrage könnte so aussehen.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;wie.*(kalt|warm|grad|temperatur) = ( answer =&amp;gt; &#039;&amp;quot;Die Temperatur beträgt &amp;quot;.ReadingsVal(&amp;quot;tempdev&amp;quot;, &amp;quot;temperature&amp;quot;, &amp;quot;Fehler&amp;quot;)&#039; )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Für eine Raumbezogene Temperaturabfrage, siehe [[Modul_Talk2Fhem#Anwendungsbeispiele_und_Vorlagen]]&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Folgende Attribute werden zur Zeit unterstützt&lt;br /&gt;
=== T2F_keywordlist ===&lt;br /&gt;
 &amp;lt;Name&amp;gt; = &amp;lt;kommaseparierte Liste mit RegExp&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Beispiele&#039;&#039;&#039;&lt;br /&gt;
 rooms = haus|überall|wohnung , wohnzimmer , bad\S* , toilette|wc , büro , ...&lt;br /&gt;
 names = Mama , Papa , Kevin , Jacqueline&lt;br /&gt;
 channels = ard|das erste , zdf , rtl , sat 1 , vox , rtl2 , prosieben , kabel eins , arte&lt;br /&gt;
Man beachte hier die möglichkeit der RegExp&amp;lt;br&amp;gt;&lt;br /&gt;
Das Schlüsselwort &#039;&#039;&#039;haus&#039;&#039;&#039; löst das selbe aus wie &#039;&#039;&#039;überall&#039;&#039;&#039; und &#039;&#039;&#039;wohnung&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;Genauso &#039;&#039;&#039;bad&#039;&#039;&#039; oder &#039;&#039;&#039;badezimmer&#039;&#039;&#039; oder &#039;&#039;&#039;badeirgendewas&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== T2F_modwordlist ===&lt;br /&gt;
 &amp;lt;Name&amp;gt; = &amp;lt;kommaseparierte Liste mir RegExp&amp;gt;&lt;br /&gt;
Die Positionen der gewählten Geräte, ist eine Zuordnung zu den Listen in&#039;&#039;T2F_keywordlist&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;Wenn Wohnzimmer in der keywordliste &amp;lt;rooms&amp;gt; an Position 2 steht muss der Rolladenaktor in der modworliste &amp;lt;roll&amp;gt; auch an Position 2 stehen.&lt;br /&gt;
 roll = rollos_alle , d_rollo_wz , hm_roll_bad.* , hm_roll_wc , hm_roll_buero.* , ...&lt;br /&gt;
 lights = alle_lichte , &#039;&#039;&#039;&amp;quot;sw_wz1,sw_wz2&amp;quot;&#039;&#039;&#039; , sw_bad.* , sw_wc&lt;br /&gt;
Sollen einem Schlüsselwort mehrere Aktoren zugeordnet werden, geht das über sogenannte &amp;quot;Quotes&amp;quot;. (Anführungszeichen) Siehe &amp;lt;lights&amp;gt;.&lt;br /&gt;
 &amp;quot;a,b&amp;quot;  oder  &#039;a,b&#039;  oder  a\,b&lt;br /&gt;
&lt;br /&gt;
=== T2F_disableumlautescaping ===&lt;br /&gt;
&lt;br /&gt;
Deaktiviert das Konvertieren der Umlaute innnerhalb von regulären Ausdrücken in &#039;&#039;&#039;\S\S?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== T2F_language ===&lt;br /&gt;
&lt;br /&gt;
Legt die verwendete Sprache fest. Alternativ wird das Globale Attribut &#039;&#039;language&#039;&#039; verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== disable ===&lt;br /&gt;
Deaktiviert das Ausführen des FHEM Kommandos&lt;br /&gt;
=== verbose ===&lt;br /&gt;
&lt;br /&gt;
== Anwendungsbeispiele und Vorlagen ==&lt;br /&gt;
Hier folgen diverse Vorlagen und Beispiele die jeweils an die eigenen Bedürfnisse angepassst werden sollten/müssen. Hierzu sind die entsprechenden Stellen &amp;lt;span style=&#039;color:red&#039;&amp;gt;rot&amp;lt;/span&amp;gt; markiert.&lt;br /&gt;
=== Keywordlist ===&lt;br /&gt;
Eine typische Keywordlist wäre eine Auflistung der benötigten Räume&lt;br /&gt;
 rooms = haus|überall|wohnung,wohnzimmer,esszimmer,bad\S*,toilette|wc,&lt;br /&gt;
 büro,schlafzimmer,ankleide|garderobe,kinderzimmer,spielzimmer,&lt;br /&gt;
 flur|gang|diele,garage,garten,terrasse,balkon,&lt;br /&gt;
 eg|erdgescho\S*,og|obergescho\S*,\S*auße\S*( haus)?|vor der tür&lt;br /&gt;
&lt;br /&gt;
=== Einfaches schalten ===&lt;br /&gt;
 licht (\S+) = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;dev_light&amp;lt;/span&amp;gt; $1{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
=== Einfaches schalten mit eigenen Wörtern ===&lt;br /&gt;
Will man neben an/aus einen weiteren Zustand selbst definieren, kann das so geschehen.&lt;br /&gt;
 garage (\S+) = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;dev_gate&amp;lt;/span&amp;gt; $1{ /&amp;lt;span style=&#039;color:red&#039;&amp;gt;kurz&amp;lt;/span&amp;gt;/ =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;open-for-time 5&amp;lt;/span&amp;gt;, true =&amp;gt; open, false =&amp;gt; close }&lt;br /&gt;
&lt;br /&gt;
=== Einfaches schalten mit Räumen ===&lt;br /&gt;
 licht (\S+ ){0,2} (&amp;lt;span style=&#039;color:red&#039;&amp;gt;wohnzimmer|esszimmer|küche|terrasse&amp;lt;/span&amp;gt;) (\S+) = set $2[&amp;lt;span style=&#039;color:red&#039;&amp;gt;light_wz,light_ez,light_kitchen,light_outside&amp;lt;/span&amp;gt;] $3{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
Bei größeren Mengen an Räumen und Geräten bietet sich das anlegen von Keyword- und Modwordlisten an. &lt;br /&gt;
 licht (\S+ ){0,2} (&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;) (\S+) = set $2[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@lights&amp;lt;/span&amp;gt;] $3{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
&lt;br /&gt;
=== Rolladen fahren ===&lt;br /&gt;
Sind die Rollläden innerhalb von FHEM über das Attribut &amp;quot;room&amp;quot; den Räumen mit Klarnamen zugeordnet, lässt sich das ganze am einfachsten konfigurieren.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;1.  nach Devicetyp&#039;&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(\S+) (auf )?(\S+) = {fhem(&#039;set room=&#039;.ucfirst(&#039;$3&#039;).&#039;:FILTER=a:subType=blindActuator &amp;lt;span style=&#039;color:red&#039;&amp;gt;$5&amp;lt;/span&amp;gt;{true=&amp;gt;on, false=&amp;gt;off, integer=&amp;gt;&#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;set_$5&amp;lt;/span&amp;gt;&#039;)}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erklärung&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn das Device vom subTyp &amp;quot;blindActuator&amp;quot; ist (HomeMatic Rolladenactor) und es im Raum $3 ist, wird dieses Device gefahren. Die Funktion ucfirst ist notwendig damit der erste Buchstabe groß geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;2.  nach Devicenamen&#039;&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(\S+) (auf )?(\S+) = {fhem(&#039;set room=&#039;.ucfirst(&#039;$3&#039;).&#039;:FILTER=rollo.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;$5&amp;lt;/span&amp;gt;{true=&amp;gt;on, false=&amp;gt;off, integer=&amp;gt;&#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;set_$5&amp;lt;/span&amp;gt;&#039;)}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erklärung&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Gleiche wie oben, nur das alle Devices die mit rollo beginnen im Raum $3 gefahren werden. (rollo.*)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;3.  nach Benutzerdefinierten Räumen&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Ansonsten müssen wir dem Modul sagen in welchem Raum welches Device sitzt. Das hat dafür den Vorteil das die Räume als RegExp angegeben werden können.&amp;lt;br&amp;gt;Wir erzeugen eine Modwordlist &#039;&#039;rollos&#039;&#039; in der wir alle Rollladen &amp;quot;Devices&amp;quot; auflisten. Die Reihenfolge ist an der Keywordlist &amp;quot;rooms&amp;quot; ([[Modul_Talk2Fhem#Keywordlist]]) anzupassen.&lt;br /&gt;
 rollos = &amp;lt;span style=&#039;color:red&#039;&amp;gt;r_alle&amp;lt;/span&amp;gt;,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_wz&amp;lt;/span&amp;gt;,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_ez&amp;lt;/span&amp;gt;,,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_buero&amp;lt;/span&amp;gt;,...&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;)? (auf )?(\S+) = set $3[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rollos&amp;lt;/span&amp;gt;, empty, &amp;lt;span style=&#039;color:red&#039;&amp;gt;rollos_alle&amp;lt;/span&amp;gt;] $5{true=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt;, integer=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;&amp;quot;set_$5&amp;quot;&amp;lt;/span&amp;gt;}&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 Rollos auf&lt;br /&gt;
 Rolllos Überall schließen &lt;br /&gt;
 Rollo im Wohnzimmer hoch&lt;br /&gt;
 Rolladen im Esszimmer runter&lt;br /&gt;
 Rollläden in der Küche auf 50&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Damit wäre eigentlich schon alles abgedeckt. Folgendes Beispiel ist aber auch noch nützlich.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
  (blendet|schatte\S?) ?(\S+ ){0,2}(&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;) = set $3[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rollos&amp;lt;/span&amp;gt;] &amp;lt;span style=&#039;color:red&#039;&amp;gt;set_70&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 ich werde geblendet in der Küche&lt;br /&gt;
 die Sonne blendet mich im Badezimmer&lt;br /&gt;
 beschatte das Haus&lt;br /&gt;
 mach schatten im Erdgeschoss&lt;br /&gt;
&lt;br /&gt;
=== GoogleCast Befehle ===&lt;br /&gt;
Etwas bessere Lautstärkebefehle als die von Google.&lt;br /&gt;
Die Lautstärken müssten noch dem eigenen Geschmack angepasst werden&lt;br /&gt;
 #GoogleCast Commandos&lt;br /&gt;
 leise$            =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 14&lt;br /&gt;
 normale lautstärke =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 20&lt;br /&gt;
 laut$             =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 30&lt;br /&gt;
 (ein wenig|etwas|viel)? ?(lauter|leiser)  =  { fhem(&amp;quot;set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume &amp;quot;.(ReadingsVal(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;volume&amp;quot;, 0)$2[+,-]$1[3,5,10,empty,7])) }&lt;br /&gt;
&#039;&#039;&#039; Beispielsätze &#039;&#039;&#039;&lt;br /&gt;
 Mach leise&lt;br /&gt;
 Mach lauter&lt;br /&gt;
 Mach etwas leiser&lt;br /&gt;
 Mach viel lauter&lt;br /&gt;
&lt;br /&gt;
=== Talk Timer zurücksetzen ===&lt;br /&gt;
Sollen alle von Talk2Fhem angelegten Timer gelöscht werden.&lt;br /&gt;
 (timer|kommandos) (löschen|zurücksetzen) = delete at_&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;.*&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 bitte alle timer zurücksetzen&lt;br /&gt;
 zukünftige kommandos löschen&lt;br /&gt;
&lt;br /&gt;
=== Frage Antwort ===&lt;br /&gt;
==== Raumbezogene Temperaturansage ====&lt;br /&gt;
Wir erzeugen wieder unsere Modwordlist sagen wir @sens gefüllt mit den Temperaturfühler &amp;quot;Devices&amp;quot;. Reihenfolge wie immer die der Keywordlist @rooms.&lt;br /&gt;
 wie.*(kalt|warm|grad|temperatur).*(&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;@rooms&amp;lt;/span&amp;gt;) = ( answer =&amp;gt; &#039;&amp;quot;Die Temperatur beträgt &amp;quot;.ReadingsVal(&amp;quot;$2[&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;@sens&amp;lt;/span&amp;gt;]&amp;quot;, &amp;quot;&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;temperature&amp;lt;/span&amp;gt;&amp;quot;, &amp;quot;unbekannt&amp;quot;).&amp;quot; grad&amp;quot;&#039; )&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 wie warm ist es im Wohnzimmer&lt;br /&gt;
 wie ist die Temperatur in der Küche&lt;br /&gt;
 wie kalt ist es draußen&lt;br /&gt;
&lt;br /&gt;
==== Multiple Antworten ====&lt;br /&gt;
 Hallo Haus = ( answer =&amp;gt; &#039;[&amp;quot;Hallo auch!&amp;quot;,&amp;quot;Guten Tag!&amp;quot;,&amp;quot;Ahoi!&amp;quot;]-&amp;gt;[rand(&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt;)]&#039; ) &lt;br /&gt;
Wählt zufällig eine der drei Aussagen.&lt;br /&gt;
&lt;br /&gt;
==== Ausgabe eines oder mehrerer Zustände ====&lt;br /&gt;
Angenommen man möchte wissen ob das Haus abgeschlossen ist. Und in FHEM existiert ein Dummy der diesen Zustand wiederspiegelt und im Reading text die offenen Fenster und Türen aufgelistet sind. Kann man folgendermaßen den Status erfragen&lt;br /&gt;
 (alles|das haus) (zu|abgeschlossen) = (&lt;br /&gt;
   answer =&amp;gt; &#039;(Value(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;d_schliessung&amp;lt;/span&amp;gt;&amp;quot;) eq &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;zu&amp;lt;/span&amp;gt;&amp;quot;) &lt;br /&gt;
   ? &amp;quot;Es ist alles zu&amp;quot; &lt;br /&gt;
   : &amp;quot;Nein, offen sind: &amp;quot;.ReadingsVal(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;d_schliessung&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;text&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;&amp;quot;)&#039;&lt;br /&gt;
&lt;br /&gt;
==== Zustandsabfrage anhand des Aliasnamen ====&lt;br /&gt;
Möchte man alle Geräte anhand seines Attribut &amp;quot;alias&amp;quot; ansprechen, um dessen Status zu erfragen, könnte das so erfolgen.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039; &lt;br /&gt;
 (zustand|status) (\S+)* (\S+) = (answer=&amp;gt;&#039;my $s=Value((grep { &amp;quot;$3&amp;quot; =~ /$attr{$_}{&amp;lt;span style=&#039;color:red&#039;&amp;gt;alias&amp;lt;/span&amp;gt;}/i } (keys %attr))[0]);; &amp;quot;Der Status ist &amp;quot;.$s if $s&#039;)&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 Wie ist der Zustand der Lüftung&lt;br /&gt;
 sag mir den Status der Haustür&lt;br /&gt;
Es ist auch möglich ein eigenes Attribut zu kreieren, und dieses als Klarnamenattribut zu verwenden. Hierzu einfach im Device global ein userattr hinzufügen. z.B.&lt;br /&gt;
 attr global userattr T2F_alias&lt;br /&gt;
Jetzt stehen in allen Devices das Attribut T2F_alias zur Verfügung. Vorteil ist das dann auch wieder RegExp verwendet werden können. Im oberen Beispiel müsste dann dass rot markierte &amp;quot;alias&amp;quot; durch &amp;quot;T2F_alias&amp;quot; ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration innerhalb der Geräte ===&lt;br /&gt;
Neben der Identifikation der Geräte über die vorhandenen FHEM-Attribute (z.B. room, alias, ...) kann eine alternative Konfiguration auch über eigens für Talk2Fhem angelegte Attribute erfolgen. Die hierfür notwendigen Grundlagen und einige Beispiele sollen im Folgenden beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Grundlagen / Voraussetzungen ====&lt;br /&gt;
1. Anlegen der notwendigen userattr am global-Device:&lt;br /&gt;
&lt;br /&gt;
Erweiterung des Attributes userattr des Gerätes global um folgende Einträge:&lt;br /&gt;
  T2F_places:textField-long T2F_properties:textField-long T2F_rooms:textField-long T2F_types_color:textField-long T2F_types_heating:textField-long T2F_types_info:textField-long T2F_types_switch:textField-long&lt;br /&gt;
&lt;br /&gt;
2. Optional: Hilfsfunktionen für das automatische Füllen der T2F_keywordlist im talk-Device bei Änderung eines T2F-Attributes eines Gerätes&lt;br /&gt;
&lt;br /&gt;
2a. erstellen einer sub in der 99_myUtils.pm:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;  sub fill_T2F_keywordlist&lt;br /&gt;
  {&lt;br /&gt;
    my ($name, $t2f_device) = @_;&lt;br /&gt;
    $name =~ s/T2F_//g;&lt;br /&gt;
    if ($name eq &#039;userattr&#039;)&lt;br /&gt;
    {&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    Log 0, &amp;quot;List: &amp;quot;.$name;&lt;br /&gt;
    my $currentAttr = AttrVal($t2f_device,&amp;quot;T2F_keywordlist&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    my @currentAttrParts = split(/$name = /, $currentAttr);&lt;br /&gt;
    my $currentAttrBeg = @currentAttrParts[0];&lt;br /&gt;
    $currentAttrBeg = substr($currentAttrBeg, 0, -1);&lt;br /&gt;
    my @currentAttrEnd = split(/\n/, @currentAttrParts[1], 2);&lt;br /&gt;
    my @array = devspec2array(&#039;a:T2F_&#039;.$name.&#039;=.+&#039;);&lt;br /&gt;
    my @attributes = ();&lt;br /&gt;
    if (@array &amp;gt; 0 and defined($defs{$array[0]}))&lt;br /&gt;
    {&lt;br /&gt;
      foreach (@array){&lt;br /&gt;
      my @attrVals = split(/\n/,AttrVal($_, &#039;T2F_&#039;.$name, &#039;&#039;));&lt;br /&gt;
      foreach (@attrVals){&lt;br /&gt;
          my $attrVal = $_;&lt;br /&gt;
          $attrVal =~ s/  / /g;&lt;br /&gt;
          $attrVal =~ s/ =&amp;gt; /=&amp;gt;/g;&lt;br /&gt;
          my @attrValParts = split(/=&amp;gt;/,$attrVal);&lt;br /&gt;
          $attrVal = @attrValParts[0];&lt;br /&gt;
          $attrVal =~ s/!//g;&lt;br /&gt;
          $attrVal =~ s/, /,/g;&lt;br /&gt;
          my @attr = split(/,/, $attrVal);&lt;br /&gt;
          push(@attributes, @attr);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    my %hash   = map { $_ =&amp;gt; 1 } @attributes;&lt;br /&gt;
    my @unique = keys %hash;&lt;br /&gt;
    my $result = $currentAttrBeg.&amp;quot;\n&amp;quot;.$name.&amp;quot; = &amp;quot;.join(&amp;quot;, &amp;quot;, @unique).&amp;quot;\n&amp;quot;.@currentAttrEnd[1];&lt;br /&gt;
    $result =~ s/\n\n/\n/g;&lt;br /&gt;
    $result =~ s/  / /g;&lt;br /&gt;
    fhem(&#039;attr &#039;.$t2f_device.&#039; T2F_keywordlist &#039;.$result);&lt;br /&gt;
  }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2b. Erstellen eines DOIFs zum Aufruf der sub:&lt;br /&gt;
&lt;br /&gt;
  defmod talk.DI.fillAttr DOIF ([global:&amp;quot;^ATTR.*T2F_.*&amp;quot;]) ({my $val = ReadingsVal(&amp;quot;$SELF&amp;quot;, &amp;quot;e_global_events&amp;quot;, &amp;quot;&amp;quot;); $val =~ m/(\S*) (\S*) (\S*) (.*)/; if ($2 ne &#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;&#039; &amp;amp;&amp;amp; $2 ne &#039;global&#039;) { fill_T2F_keywordlist(&amp;quot;$3&amp;quot;, &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;&amp;quot;);}})&lt;br /&gt;
  attr talk.DI.fillAttr do always&lt;br /&gt;
&lt;br /&gt;
3. Optional: Erlauben von Umlauten in den T2F-Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_disableumlautescaping 1  &lt;br /&gt;
  &lt;br /&gt;
Nun können die T2F-Attribute pro FHEM-Device definiert und dann in den Talk2Fhem-Befehlen benutzt werden. Wurde der Punkt 2 abgearbeitet, so werden mit dem Füllen der Attribute am Geräte auch die Keywordlisten am talk-Device gefüllt. Wie diese dann verwendet werden können, sollen die folgenden Beispiele zeigen.&lt;br /&gt;
&lt;br /&gt;
==== Schalten von Geräten ====&lt;br /&gt;
&lt;br /&gt;
Ausgangssituation: Es gibt drei Lampen Lampe1, Lampe2, Lampe3 und ein Nachtlicht mit einer Eule mit folgenden Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr Lampe1 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe1 T2F_rooms Haus, Obergeschoss, !Esszimmer&lt;br /&gt;
  attr Lampe1 T2F_places Decke, Tür&lt;br /&gt;
  attr Lampe1 T2F_properties hell,!&lt;br /&gt;
&lt;br /&gt;
  attr Lampe2 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe2 T2F_rooms Haus, Obergeschoss, !Esszimmer&lt;br /&gt;
  attr Lampe2 T2F_places Tisch, Esstisch&lt;br /&gt;
  attr Lampe2 T2F_properties dunkel,schwach,!&lt;br /&gt;
&lt;br /&gt;
  attr Lampe3 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe3 T2F_rooms Haus, Obergeschoss, !Küche&lt;br /&gt;
  attr Lampe3 T2F_places Besenschrank&lt;br /&gt;
  &lt;br /&gt;
  attr Nachtlicht T2F_types_switch Lampe, !Licht, Eule, Nachtlicht&lt;br /&gt;
  attr Nachtlicht T2F_rooms Haus, Obergeschoss, !Kinderschlafzimmer&lt;br /&gt;
  attr Nachtlicht T2F_places Steckdose&lt;br /&gt;
&lt;br /&gt;
Durch die in Punkt 2 der Voraussetzungen genannten Funktionen wurden folgende T2F-keywordlisten automatisch angelegt:&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_keywordlist rooms = Kinderschlafzimmer, Haus, Küche, Obergeschoss, Esszimmer &lt;br /&gt;
                            places = Tür, Steckdose, Tisch, Decke, Esstisch&lt;br /&gt;
                            properties = hell, dunkel, schwach&lt;br /&gt;
                            types_switch = Lampe, Licht, Eule&lt;br /&gt;
&lt;br /&gt;
Die Definition für das T2F-Device lautet dann wie folgt:&lt;br /&gt;
&lt;br /&gt;
  #   1              2                 3                4            5          6          7      &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; ?(@properties) &amp;amp;&amp;amp; (@types_switch) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) &amp;amp;&amp;amp; (\S+)(schalten|machen)?$ =&lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_switch=.*$3@.*:FILTER=T2F_rooms=.*$4@.*:FILTER=T2F_properties=.*$2@.*:FILTER=T2F_places=.*$5@.* $6{true=&amp;gt;on, false=&amp;gt;off}&#039;,&lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;$AGAIN&amp;quot; ? &amp;quot;dann $DATE wieder $6{true=&amp;gt;ein, false=&amp;gt;aus}&amp;quot; : &amp;quot;$1{/bitte/=&amp;gt;Gern, else=&amp;gt;Das heißt Bitte}, ich schalte $1{/bitte/=&amp;gt;, else=&amp;gt;trotzdem} folgende Geräte $6{true=&amp;gt;ein, false=&amp;gt;aus}: &amp;quot;.T2F_answer(&amp;quot;T2F_types_switch=.*$3@.*:FILTER=T2F_rooms=.*$4@.*:FILTER=T2F_properties=.*$2@.*:FILTER=T2F_places=.*$5@.*&amp;quot;,&amp;quot;T2F_types_switch&amp;quot;)&#039;)&lt;br /&gt;
                            &lt;br /&gt;
Damit sind dann die folgenden Sprachbefehle möglich:&lt;br /&gt;
&lt;br /&gt;
  Schalte das Licht in der Küche ein                      =&amp;gt; schaltet Lampe3 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte die helle Lampe im Esszimmer an                 =&amp;gt; schaltet Lampe1 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht im Esszimmer über dem Esstisch ein    =&amp;gt; schaltet Lampe2 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte die Eule ein                                    =&amp;gt; schaltet Nachtlicht ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht im Esszimmer aus}                     =&amp;gt; schaltet Lampe1 und Lampe2 aus&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht aus                                   =&amp;gt; schaltet alle vier Lichter aus&lt;br /&gt;
&lt;br /&gt;
Um in der Antwort die Liste der geschalteten Geräte genannt zu bekommen, wird die sub T2F_answer aus der 99_myUtils aufgerufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub T2F_answer&lt;br /&gt;
{&lt;br /&gt;
  my ($filter, $type) = @_;&lt;br /&gt;
  my $answer = &#039;&#039;;&lt;br /&gt;
  my @devices = devspec2array($filter);&lt;br /&gt;
  if (@devices &amp;gt; 0 and defined($defs{$devices[0]}))&lt;br /&gt;
  {&lt;br /&gt;
    foreach (@devices){&lt;br /&gt;
      my $devAttr = AttrVal($_, $type, &#039;&#039;);&lt;br /&gt;
      if ($answer ne &#039;&#039;)&lt;br /&gt;
      {&lt;br /&gt;
        $answer = $answer.&amp;quot;, &amp;quot;;&lt;br /&gt;
      }&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      $devAttr = AttrVal($_, &#039;T2F_properties&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      $devAttr = AttrVal($_, &#039;T2F_rooms&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      $devAttr = AttrVal($_, &#039;T2F_places&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return $answer.&amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Benennung der Geräte erfolgt auf Basis derer T2F-Attribute: Typ, Eigenschaft, Raum, Ort. Ist das jeweilige Attribut leer, ist es auch in der Antwort leer. Enthält die jeweilige Attributliste ein Ausrufezeichen (!), so wird der Eintrag nach dem Ausrufezeichen für die Antwort verwendet (z.B. Esszimmer als Raum). Steht das Ausrufezeichen am Ende, so wird der Eintrag in der Antwort leer gelassen (z.B. die Eigenschaft bei Lampe1). Ist kein Ausrufezeichen vorhanden, so wird der erste Eintrag verwendet.&lt;br /&gt;
&lt;br /&gt;
==== Einstellen der Heizung ====&lt;br /&gt;
&lt;br /&gt;
Das gleiche Prinzp wie bei den Lampen kann auch für die Einstellung der Heizung verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Ausgangssituation: In der Küche, im Kinderschlafzimmer und im Esszimmer gibt es jeweils eine Heizung (Homematic HM-CC-RT-DN) mit folgenden Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr HeizungEsszimmer T2F_places Heizung,!&lt;br /&gt;
  attr HeizungEsszimmer T2F_rooms Haus,Obergeschoss,Essbereich,!Esszimmer&lt;br /&gt;
  attr HeizungEsszimmer T2F_types_heating Heizung,Temperatur,Esszimmer,Essbereich,!&lt;br /&gt;
&lt;br /&gt;
  attr HeizungKüche T2F_places Heizung,!&lt;br /&gt;
  attr HeizungKüche T2F_rooms Haus,Obergeschoss,Essbereich,!Küche&lt;br /&gt;
  attr HeizungKüche T2F_types_heating Heizung,Temperatur,Küche,Essbereich,!&lt;br /&gt;
&lt;br /&gt;
  attr HeizungKiSchla T2F_places Heizung,!&lt;br /&gt;
  attr HeizungKiSchla T2F_rooms Haus,Obergeschoss,!Kinderschlafzimmer&lt;br /&gt;
  attr HeizungKiSchla T2F_types_heating Heizung,Temperatur,Kinderschlafzimmer,!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mit der T2F-Definition&lt;br /&gt;
&lt;br /&gt;
  #   1             2                  3        4      5                  &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; (@types_heating) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; (auf (\d+) grad|auto\S*)( stellen| setzen| einstellen| ein)?$ = &lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.* $5{integer=&amp;gt;desired-temp $5, else=&amp;gt;controlMode auto}&#039;,&lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;$AGAIN&amp;quot; ? &amp;quot;dann $DATE wieder auf Automatik&amp;quot; : &amp;quot;Die Durchschnittstemperatur beträgt dort zur Zeit &amp;quot;.averageTemp(&amp;quot;T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.*&amp;quot;).&amp;quot; Grad\n$1{/bitte/=&amp;gt;Gern, else=&amp;gt;Das heißt Bitte}, ich stelle die Heizung in folgenden Räumen auf $5{integer=&amp;gt;$5 Grad, else=&amp;gt;Automatik}: &amp;quot;.T2F_answer(&amp;quot;T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.*&amp;quot;,&amp;quot;T2F_types_heating&amp;quot;)&#039;)&lt;br /&gt;
  &lt;br /&gt;
funktionieren folgende Sprachbefehle:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Esszimmer auf 21 Grad        =&amp;gt; Stellt die Heizung im Esszimmer auf 21 Grad&lt;br /&gt;
  &lt;br /&gt;
  Bitte stell die Heizung im Essbereich auf 21 Grad       =&amp;gt; Stellt die Heizungen im Esszimmer und in der Küche auf 21 Grad&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Obergeschoss auf Automatik   =&amp;gt; Stellt die drei Heizungen auf Automatik&lt;br /&gt;
  &lt;br /&gt;
Dadurch, dass im Attribut T2F_types_heating auch die Räume aufgeführt sind, sind auch Befehle in folgender Form möglich:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Küche auf 21 Grad                       =&amp;gt; Stellt die Heizung in der Küche auf 21 Grad&lt;br /&gt;
&lt;br /&gt;
Auch kann in diesem (wie auch in den oben aufgeführten Schaltbefehlen) mit &amp;quot;wieder&amp;quot; gearbeitet werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Essbereich auf 21 Grad und in 2 Stunden wieder auf Automatik&lt;br /&gt;
  &lt;br /&gt;
Für die Generierung der Antwort wird neben der bei den Schaltbefehlen bereits gezeigten sub T2F_answer eine weiter Funktion verwende, welche die Durchschnittstemperatur im zu schaltenden Bereich ermittelt und ausgibt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
  sub averageTemp($)&lt;br /&gt;
  {&lt;br /&gt;
    my ($filter) = @_;&lt;br /&gt;
    my @tempDevices = devspec2array($filter);&lt;br /&gt;
    my $count = 0;&lt;br /&gt;
    my $measuredTemp = 0;&lt;br /&gt;
    if (@tempDevices &amp;gt; 0 and defined($defs{$tempDevices[0]})){&lt;br /&gt;
      foreach (@tempDevices){&lt;br /&gt;
        $measuredTemp = $measuredTemp + ReadingsVal($_, &amp;quot;measured-temp&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        $count = $count + 1;&lt;br /&gt;
      }&lt;br /&gt;
      return $measuredTemp / $count;&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
==== Einstellen der Farbe von Farbwechsellampen (Philips Hue, Wifilight, ...) ====&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel zum Einstellen der Lichtfarbe nehmen wir eine Farbwechsellampe LampeBunt an, welche den Befehl RGB unterstützt. Diese erhält folgende Attribute:&lt;br /&gt;
&lt;br /&gt;
  attr LampeBunt T2F_places Decke,Couch,Sofa&lt;br /&gt;
  attr LampeBunt T2F_rooms Haus,Dachgeschoss,!Wohnzimmer&lt;br /&gt;
  attr LampeBunt T2F_types_color Lampe,Licht&lt;br /&gt;
  attr LampeBunt T2F_types_switch Lampe,Licht&lt;br /&gt;
  &lt;br /&gt;
Durch das Attribut T2F_types_switch lässt sich diese über die bereits beschriebene Schaltlogik ein und ausschalten. Durch die zusätzlich T2F-Definition&lt;br /&gt;
&lt;br /&gt;
  #   1              2               3             4              5               6 &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; (@types_color) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) &amp;amp;&amp;amp; auf (@colors)( schalten| stellen)?$ = &lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_color=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_places=.*$4@.* RGB $5[@rgb]&#039;, &lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;Ich schalte folgende Geräte auf $5@: &amp;quot;.T2F_answer(&amp;quot;T2F_types_color=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_places=.*$4@.*&amp;quot;,&amp;quot;T2F_types_color&amp;quot;)&#039;)&lt;br /&gt;
&lt;br /&gt;
und die entsprechenden Attribute am T2F-Device talk (HINWEIS: eigene Listen können Problemlos ergänzt werden, diese werden durch die Hilfsfunktionen NICHT überschrieben)&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_keywordlist colors = Aus, Schwarz, Dunkles Schiefergrau, Schiefergrau, Helles Schiefergrau, Helles Stahlblau, Mattes Grau, Grau, Dunkelgrau, Silber, Hellgrau, Gainsboro, Rauchiges Weiß, Geisterweiß, Weiß, Schneeweiß, Elfenbein, Blütenweiß, Muschel, Altgold, Leinenfarbe, Antikes Weiß, Mandelweiß, Cremiges Papaya, Beige, Mais, Helles Goldrutengelb, Hellgelb, Chiffongelb, Blasse Goldrutenfarbe, Khaki, Gelb, Gold, Orange, Dunkles Orange, Goldrute, dunkle Goldrutenfarbe, Peru, Schokolade, Sattelbraun, Ocker, Braun, Dunkelrot, Kastanienbraun, Ziegelfarbe, Indischrot, Karmesinrot, Rot, Orangenrot, Tomatenrot, Koralle, Lachs, Helles Korallenrot, Dunkle Lachsfarbe, Helle Lachsfarbe, Sandbraun, Rosiges Braun, Gelbbraun, Grobes Braun, Weizen, Pfirsich, Navajoweiß, Tomatencreme, Rosige Lavenderfarbe, Altrosa, Rosa, Hellrosa, Leuchtendes Rosa, Fuchsie, Magentarot, Tiefrosa, Mittleres Violettrot, Blasses Violettrot, Pflaume, Distel, Lavendelfarbe, Violett, Orchidee, Dunkles Magentarot, Violett, Indigo, Blauviolett, Dunkles Violett, Dunkle Orchideenfarbe, Mittleres Violett, Mittlere Orchideenfarbe, Mittleres Schieferblau, Schieferblau, Dunkles Schieferblau, Mitternachtsblau, Marineblau, Dunkelblau, Mittelblau, Blau, Königsblau, Stahlblau, Kornblumenblau, Dodger-Blau, Tiefes Himmelblau, Helles Himmelblau, Himmelblau, Hellblau, Zyanblau, Blaugrün, Taubenblau, Helles Cyanblau, Aliceblau, Himmelblau, Cremig Pfefferminz, Honigmelone, Aquamarinblau, Türkis, Blasses Türkis, Mittleres Türkis, Dunkles Türkis, Mittleres Aquamarinblau, Helles Seegrün, Dunkles Zyanblau, Entenbraun, Kadettblau, Mittleres Seegrün, Dunkles Seegrün, Hellgrün, Blassgrün, Mittleres Frühlingsgrün, Frühlingsgrün, Zitronengrün, Gelbgrün, Seegrün, Waldgrün, Grün, Dunkelgrün, Olivfarbiges Graubraun, Dunkles Olivgrün, Olivgrün, Dunkles Khaki, Gelbgrün, Hellgrün, Grüngelb&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_modwordlist rgb = 000000, 000000, 8FBC8F, 708090, 778899, B0C4DE, 696969, 808080, A9A9A9, C0C0C0, D3D3D3, DCDCDC, F5F5F5, F8F8FF, FFFFFF, FFFAFA, FFFFF0, FFFAF0, FFF5EE, FDF5E6, FAF0E6, FAEBD7, FFEBCD, FFEFD5, F5F5DC, FFF8DC, FAFAD2, FFFFE0, FFFACD, EEE8AA, F0E68C, FFFF00, FFD700, FFA500, FF8C00, DAA520, B8860B, CD853F, D2691E, 8B4513, A0522D, A52A2A, 8B0000, 800000, B22222, CD5C5C, DC143C, FF0000, FF4500, FF6347, FF7F50, FA8072, F08080, E9967A, FFA07A, F4A460, BC8F8F, D2B48C, DEB887, F5DEB3, FFDAB9, FFDEAD, FFE4C4, FFF0F5, FFE4E1, FFC0CB, FFB6C1, FF69B4, FF00FF, FF00FF, FF1493, C71585, DB7093, DDA0DD, D8BFD8, E6E6FA, EE82EE, DA70D6, 8B008B, 800080, 4B0082, 8A2BE2, 9400D3, 9932CC, 9370DB, BA55D3, 7B68EE, 6A5ACD, 483D8B, 191970, 000080, 00008B, 0000CD, 0000FF, 4169E1, 4682B4, 6495ED, 1E90FF, 00BFFF, 87CEFA, 87CEEB, ADD8E6, 00FFFF, 00FFFF, B0E0E6, E0FFFF, A0CE00, F0FFFF, F5FFFA, F0FFF0, 7FFFD4, 40E0D0, AFEEEE, 48D1CC, 00CED1, 66CDAA, 20B2AA, 008B8B, 008080, 5F9EA0, 3CB371, 8FBC8F, 90EE90, 98FB98, 00FA9A, 00FF7F, 00FF00, 32CD32, 2E8B57, 228B22, 008000, 006400, 6B8E23, 556B2F, 808000, BDB76B, 9ACD32, 7FFF00, ADFF2F&lt;br /&gt;
&lt;br /&gt;
kann die Farbe nun auch über folgenden Sprachbefehle eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte schalte die Lampe im Wohnzimmer an der Couch auf Olivfarbiges Graubraun&lt;br /&gt;
&lt;br /&gt;
Dadurch, das die Liste colors den Wert &amp;quot;Aus&amp;quot; mit dem entsprechenden Wert &amp;quot;000000&amp;quot; in der Liste rgb enthält, kann die Lampe über die gleiche Logik auch ausgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte schalte das Licht im Wohnzimmer auf Pflaume und in einer Stunde wieder aus&lt;br /&gt;
  &lt;br /&gt;
==== Abfragen beliebiger Geräteinformationen ====&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Möglichkeit auf, die Antworten für Statusabfragen direkt am abgefragten Gerät zu definieren. Hierfür werden zunächst eine Definition am T2F-Device&lt;br /&gt;
&lt;br /&gt;
  #              1             2                3            4&lt;br /&gt;
  Wie &amp;amp;&amp;amp; ?(@properties)&amp;amp;&amp;amp; (@types_info) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) = &lt;br /&gt;
  (answer=&amp;gt;&#039;T2F_getInfo(&amp;quot;T2F_types_info=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_properties=.*$1@.*:FILTER=T2F_places=.*$4@.*&amp;quot;,&amp;quot;$2@&amp;quot;)&#039;)&lt;br /&gt;
  &lt;br /&gt;
und eine Funktion in der 99_myUtils&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub T2F_getInfo&lt;br /&gt;
{&lt;br /&gt;
  my ($filter,$info) = @_;&lt;br /&gt;
  my @devices = devspec2array($filter);&lt;br /&gt;
  if (@devices &amp;gt; 0 and defined($defs{$devices[0]}))&lt;br /&gt;
  {&lt;br /&gt;
    my $answer = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
    foreach (@devices){&lt;br /&gt;
      if ($answer ne &#039;&#039;)&lt;br /&gt;
      {&lt;br /&gt;
        $answer = $answer.&amp;quot;, &amp;quot;;&lt;br /&gt;
      }&lt;br /&gt;
      my $device = $_;&lt;br /&gt;
      my @attrVals = split(/\n/,AttrVal($device, &#039;T2F_types_info&#039;, &#039;&#039;));&lt;br /&gt;
      foreach (@attrVals){&lt;br /&gt;
        my $attrVal = $_;&lt;br /&gt;
        $attrVal =~ s/  / /g;&lt;br /&gt;
        $attrVal =~ s/ =&amp;gt; /=&amp;gt;/g;&lt;br /&gt;
        my @attrValParts = split(/=&amp;gt;/,$attrVal);&lt;br /&gt;
        if (@attrValParts[0] =~ /$info/)&lt;br /&gt;
        {&lt;br /&gt;
          my $cmd = &amp;quot;&#039; &amp;quot;.@attrValParts[1].&amp;quot;&#039;&amp;quot;;&lt;br /&gt;
          $cmd =~ s/=/\//g;&lt;br /&gt;
          $cmd =~ s/\)\(/\/r=~s\//g;&lt;br /&gt;
          $cmd =~ s/\)/\/r.&#039;/g;&lt;br /&gt;
          $cmd =~ s/#\(/&#039;, &#039;&#039;)=~s\//g;&lt;br /&gt;
          $cmd =~ s/ #/ &#039;.ReadingsVal(&#039;$device&#039;, &#039;/g;&lt;br /&gt;
          $cmd =~ s/#/&#039;, &#039;&#039;).&#039;/g;&lt;br /&gt;
          $cmd =~ s/T2F_answer/&#039;.T2F_answer(&#039;$device&#039;, &#039;T2F_types_switch&#039;).&#039;/g;&lt;br /&gt;
          $answer = $answer.&#039; &#039;.eval($cmd);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    return $answer;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration und Funktionsweise sind nun wie folgt: Das Gerät, dessen Status abgefragt werden sollen erhält neben den Oben bereits beschriebenen Attributen für Eigenschaft, Raum und Ort noch das Attribut T2F_types_info, welches Zeilenweise die abzufragenen Status in der folgenden Form enthält:&lt;br /&gt;
&lt;br /&gt;
  abfragewert =&amp;gt; Das ist die Antwort von Gerät T2F_answer mit den Wert #reading#(suchen1=ersetzen1)...(suchenn=ersetzenn)&lt;br /&gt;
  &lt;br /&gt;
Mit der Form #reading#(suchen1=ersetzen1)...(suchenn=ersetzenn) können die Werte von Readings des abgefragten Device zum Zeitpunkt der Abfrage ermittelt werden und im Ergebnis Ersetzungen vorgenommen werden (z.B. (on=an)(off=aus)). T2F_answer wird mit der T2F-Konfiguration (siehe oben) ersetzt. Für das Beispiel einer Heizung im Esszimmer wäre das zum Beispiel wie folgt möglich:&lt;br /&gt;
&lt;br /&gt;
  attr HeizungEsszimmer T2F_places Heizung,!&lt;br /&gt;
  attr HeizungEsszimmer T2F_rooms Haus,Obergeschoss,Essbereich,!Esszimmer&lt;br /&gt;
  attr HeizungEsszimmer T2F_types_info warm,Temperatur =&amp;gt; Die Temperatur T2F_answer beträgt #measured-temp# Grad und soll #desired-temp# Grad erreichen\&lt;br /&gt;
                                       modus,Betriebsart =&amp;gt; Die Betriebsart T2F_answer ist #controlMode#(auto=Automatik)(manu=Hand)\&lt;br /&gt;
                                       Ventilstellung =&amp;gt; Das Ventil T2F_answer ist #ValvePosition# Prozent geöffnet&lt;br /&gt;
&lt;br /&gt;
Damit sind dann folgende Abfragen möglich:&lt;br /&gt;
&lt;br /&gt;
  Wie warm ist die Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
  Wie ist die Temperatur der Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
  Wie ist die Ventilstellung der Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
  Wie warm sind die Heizungen?&lt;br /&gt;
&lt;br /&gt;
== Häufig verwendete RegExp ==&lt;br /&gt;
Perl Regular Expression, also ein regulärer Ausdruck der Programmiersprache Perl, ist eine Werkzeug um Zeichenketten zu beschreiben. Hier wird ein kurzer Einblick auf die im Artikel häufig genutzten RegExp zu geben.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung der Syntax kann hier eingesehen werden. [http://jkorpela.fi/perl/regexp.html]&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! RegExp !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| \S* || Beliebig viele (*) nicht Leerzeichen (\S). Für unbekannten und unwichtigen Wortendungen&amp;lt;br&amp;gt;z.b. garage\S* ist bei Garage, Garagentor oder Garagentür erfolgreich&lt;br /&gt;
|-&lt;br /&gt;
| \S+ || Mehr als ein Zeichen (+) welches kein Leerzeichen ist (\S)&lt;br /&gt;
|-&lt;br /&gt;
| \S\S? || Ein oder zwei Zeichen die keine Leerzeichen sind. Das &amp;quot;?&amp;quot; wirkt hier nur auf das angrenzende &amp;quot;\S&amp;quot;.&amp;lt;br&amp;gt;Sollte für Umlaute verwendet werden, da bei manchen Eingabemethoden Probleme mit Umlauten auftreten können.&lt;br /&gt;
|-&lt;br /&gt;
| (wort )?  || Ein bestimmtes Wort oder nicht.&lt;br /&gt;
|-&lt;br /&gt;
| (wort1&amp;amp;#124;wort2) || Entweder wort1 oder Wort2&lt;br /&gt;
|-&lt;br /&gt;
| wort$ || Nur wenn das Wort am ende der Zeichenkette steht.&lt;br /&gt;
|-&lt;br /&gt;
| (\S+){0,2} || Keins, eins oder zwei Wörter. Kann für Artikel wie z.B. &amp;quot;(in der&amp;amp;#124;in dem&amp;amp;#124;im&amp;amp;#124;auf der&amp;amp;#124;...)?&amp;quot; eingesetzt werden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Eingabemethoden ==&lt;br /&gt;
Die Herkunft der Sprachbefehle für das Modul sind vielfältig. Hier werden einige Methoden beschrieben wie der Sprachbefehl in das Modul gelangen kann.&lt;br /&gt;
=== Messenger Telegram ===&lt;br /&gt;
Ist ein [[TelegramBot]] telbot definiert, reicht ein einfaches &amp;quot;notify&amp;quot; um die Nachrichten an FHEM an Talk2Fhem weiterzuleiten.&lt;br /&gt;
 define &amp;lt;span style=&#039;color:red&#039;&amp;gt;n_telbot&amp;lt;/span&amp;gt; notify &amp;lt;span style=&#039;color:red&#039;&amp;gt;telbot&amp;lt;/span&amp;gt;:msgText.* set talk $EVENT&lt;br /&gt;
Schon kann mit FHEM gechattet werden... ;)&lt;br /&gt;
&lt;br /&gt;
=== Google Home Geräte ===&lt;br /&gt;
Momentan ist es leider noch notwendig über einen Umweg die Sprache von einem GoogleHome in FHEM zu bringen. Hierzu ist es notwendig einen funktionierenden DNS Service am laufen zu haben. Damit FHEM per Webadresse im Internet erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
*Ein FHEMWEB Device anlegen&lt;br /&gt;
 define api FHEMWEB 8087 global&lt;br /&gt;
 attr api HTTPS 1&lt;br /&gt;
 attr api allowfrom  1&lt;br /&gt;
 attr api csrfToken  None&lt;br /&gt;
*Ein allowed Device anlegen&lt;br /&gt;
 define allowed_api allowed api&lt;br /&gt;
 attr allowed_api allowedCommands set&lt;br /&gt;
 attr allowed_api allowedDevices talk&lt;br /&gt;
 attr allowed_api basicAuth  {&amp;quot;$user:$password&amp;quot; eq &#039;user:passwort&#039;}&lt;br /&gt;
 attr allowed_api validFor   api&lt;br /&gt;
*Mit Googlekono bei IFTTT.com anmelden&lt;br /&gt;
*New Applet&lt;br /&gt;
*+this GoogleAssistant -&amp;gt; Say a phrase with a text ingredient&lt;br /&gt;
* Die drei Triggertexte wählen z.b.&lt;br /&gt;
**das Haus $&lt;br /&gt;
**sag dem Haus $&lt;br /&gt;
**frag das Haus $&lt;br /&gt;
***Problem bei zu kurzen Texten hat GoogleHome keine anderen Anfragen mehr angenommen.&lt;br /&gt;
*Einen Antworttext überlegen z.B. OK und in &amp;quot;What do you want the Assistant to say in response?&amp;quot; eintragen&lt;br /&gt;
*Language Deutsch&lt;br /&gt;
*+that Webhooks&lt;br /&gt;
*URL wählen&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;https://user:password@dnsservice:54387/fhem?cmd.talk=set talk {{TextField}}&amp;amp;XHR=1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
*Fertig&lt;br /&gt;
&lt;br /&gt;
Jetzt wird der gesamte Text bei dem genannten Triggerworten an FHEM weitergeleitet.&lt;br /&gt;
&lt;br /&gt;
== Ausgabemethoden ==&lt;br /&gt;
&lt;br /&gt;
Siehe hierzu [[Modul_Talk2Fhem#Beispiel|Anwendungsbeispiel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Sprachsteuerung|Talk2FHEM]]&lt;/div&gt;</summary>
		<author><name>RoBra81</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Talk2Fhem&amp;diff=24861</id>
		<title>Talk2Fhem</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Talk2Fhem&amp;diff=24861"/>
		<updated>2018-01-30T13:26:01Z</updated>

		<summary type="html">&lt;p&gt;RoBra81: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Das Modul stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her&lt;br /&gt;
|ModType=h]&lt;br /&gt;
|ModCmdRef=Talk2Fhem&lt;br /&gt;
|ModForumArea=Unterst&amp;amp;uuml;tzende Dienste&lt;br /&gt;
|ModTechName=39_Talk2Fhem.pm&lt;br /&gt;
|ModOwner=Oliver Georgi&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Seite beschreibt die Funktionsweise und Konfiguration des Moduls 39_Talk2Fhem.pm&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen ==&lt;br /&gt;
[[Datei:ModulTalk2FhemScreenshot.png|360px|thumb|right]]&lt;br /&gt;
Es ist sehr zu empfehlen, für die Konfiguration des Moduls, im Webfrontend von FHEM die Syntaxhervorhebung zu aktivieren. Die Aktivierung des erweiterten Editors ist [[Konfiguration#Syntaxhervorhebung|hier]] beschrieben.&lt;br /&gt;
&lt;br /&gt;
Kenntnisse im Bereich Regulärer Ausdrücke (RegExp) in Perl sind hilfreich, aber nicht zwingend erforderlich. Ein kurzer Einstieg kann hier eingesehen werden. [[Modul_Talk2Fhem#Häufig_verwendete_RegExp|Häufig_verwendete_RegExp]]&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
Das Modul Talk2Fhem stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her. Es ist ein überaus flexibles und relativ einfach zu konfigurierendes Script mit dem man sehr natürlich kommunizieren kann. Die Konfiguration erfolgt dabei über das FHEM Webfrontend. &lt;br /&gt;
&lt;br /&gt;
Es werden diverse [[Modul_Talk2Fhem#Zeitenerkennung|Zeit- und Datumsangaben]] erkannt. Außerdem ist es möglich [[Modul_Talk2Fhem#Eventenerkennung|Events zu formulieren]], welche die Befehle zu einem bestimmten Ereignis ausführen lassen. Bei der weiteren Verarbeitung der Sprachbefehle wird die Sprache mit selbst definierte Schlüsselwörter verglichen. &lt;br /&gt;
&lt;br /&gt;
=== Funktionsweise ===&lt;br /&gt;
&lt;br /&gt;
Die Zerlegung des Sprachbefehls erfolgt in mehreren Schritten. &lt;br /&gt;
# Aufteilen des Sprachbefehls in einzelne Kommandos anhand des Wortes UND&lt;br /&gt;
# Erkennen von Zeit- und Datumsangaben und entfernen für die weitere Verarbeitung&lt;br /&gt;
# Entfernung unnötiger Wörter&lt;br /&gt;
# Vergleich mit den definierten Schlüsselwörtern&lt;br /&gt;
# Konvertieren in ein FHEM Kommando&lt;br /&gt;
# Zeit- und Eventgebundenes auslösen des FHEM Kommandos&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Solange das Modul noch nicht offiziell aufgenommen wurde, muss die Datei 39_Talk2Fhem.pm manuell in das Verzeichnis FHEM/ kopiert werden. Siehe Forumsbeitrag. [https://forum.fhem.de/index.php/topic,80960.0.html]&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
 define talk Talk2Fhem&lt;br /&gt;
Zum testen der Konfiguration ist es Ratsam vorerst das Attribut disable auf 1 zu setzen. Hierbei wird die Auslösung der FHEM Kommandos unterdrückt.&lt;br /&gt;
 attr talk disable 1&lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
Der Sprachbefehl wird über das Kommando &#039;&#039;&#039;set&#039;&#039;&#039; oder &#039;&#039;&#039;set !&#039;&#039;&#039; an das Modul geleitet.&lt;br /&gt;
 set talk Guten Morgen liebes Zuhause&lt;br /&gt;
&#039;&#039;Wird kein Text angehängt, wird der letzte Sprachbefehl erneut ausgeführt.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Readings ===&lt;br /&gt;
&lt;br /&gt;
Im Reading &#039;&#039;&#039;set&#039;&#039;&#039; steht der letzte gesendete Sprachbefehl.&lt;br /&gt;
&amp;lt;br&amp;gt;Im Reading &#039;&#039;&#039;cmds&#039;&#039;&#039; steht das letzte ausgeführte FHEM-Kommando dessen Rückgabe in in das Reading &#039;&#039;&#039;fhem&#039;&#039;&#039; geschrieben wird. &lt;br /&gt;
&lt;br /&gt;
Die Antworten und Modulinterne Fehler werden in den Readings &#039;&#039;&#039;answers&#039;&#039;&#039; und &#039;&#039;&#039;err&#039;&#039;&#039; ausgegben. &lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;ifs&#039;&#039;&#039; stehen die Bedingungen bei dem das letzte Kommando ausgeführt werden wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;notifies&#039;&#039;&#039; enthält eine Auflistung der Devices die für die aktuell wartenden bedingten Kommandos relevant sind. Auf diesen Devices liegt ein internes notify.   &lt;br /&gt;
&lt;br /&gt;
Das Reading &#039;&#039;&#039;status&#039;&#039;&#039; wird jedes mal gesetzt und erhält Werte nach folgender Priorität.&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|1.||&#039;&#039;&#039;response&#039;&#039;&#039; ||wenn das FHEM Kommando eine Meldung ausgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|2.||&#039;&#039;&#039;disabled&#039;&#039;&#039; ||wenn das Attribute disable auf 1 steht&lt;br /&gt;
|-&lt;br /&gt;
|3.||&#039;&#039;&#039;err&#039;&#039;&#039; ||wenn der Sprachbefehl einen Fehler zurückgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|4.||&#039;&#039;&#039;answer&#039;&#039;&#039; ||wenn der Sprachbefehl eine Antwort ausgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|5.||&#039;&#039;&#039;done&#039;&#039;&#039; ||wenn keines der oberen Fälle eingetreten ist, also alles gut verlaufen ist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Beispiel ===&lt;br /&gt;
Die FHEM Befehle werden eigenständig ausgeführt, sie können aber zur Überprüfung auch weitergeleitet werden. Das Beispiel zeigt auch wie auf Fehler und Antworten von Talk2Fhem reragiert werden kann.&lt;br /&gt;
Erstellen eines Notify&lt;br /&gt;
 define n_talk notify talk:.* {}&lt;br /&gt;
Folgendes in der Definition von n_talk einfügen&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 talk:.* {&lt;br /&gt;
 # Sende die Antwort per Telegram und gebe es über das GoogleHome aus&lt;br /&gt;
 	if ($EVENT =~ s/^answers: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telegram _msg \@USER $EVENT&amp;quot;);&lt;br /&gt;
 		fhem(&amp;quot;set d_googlespeak $EVENT&amp;quot;);	&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 # Schicke den Fehler per Telegram und sag am GoogleHome das es nicht geklappt hat.&lt;br /&gt;
 	if ($EVENT =~ s/^err: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telbot _msg \@Oliver $EVENT&amp;quot;);&lt;br /&gt;
 		my @a = (&amp;quot;Das hat leider nicht geklappt&amp;quot;, &amp;quot;Es gab leider einen Fehler&amp;quot;, &amp;quot;Es tut mir leid. Das hat nicht funktioniert.&amp;quot;, &amp;quot;Es ist leider zu einem Fehler gekommen&amp;quot;,&amp;quot;Könntest du das vielleicht nochmal anders sagen&amp;quot;, &amp;quot;Mhhh, das kann ich so nicht verstehen&amp;quot;);&lt;br /&gt;
 		fhem(&amp;quot;set d_googlespeak $a[int(rand($#a))]&amp;quot;);&lt;br /&gt;
 	} &lt;br /&gt;
 &lt;br /&gt;
 # Schick mir alle ausgeführten Befehle als Telegram&lt;br /&gt;
 &lt;br /&gt;
 	if ($EVENT =~ s/^cmds: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telbot _msg \@USER $EVENT&amp;quot;);&lt;br /&gt;
 	} &lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Eine weitere Möglichkeit Talk2Fhem mit anderen Modulen zu verbinden, ist über das Reading &#039;&#039;&#039;status&#039;&#039;&#039; möglich.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Lösung hat den Vorteil das eine Standardantwort definiert werden kann. &lt;br /&gt;
&#039;&#039;&#039;!Achtung noch nicht getestet vom Author!&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
talk:status {&lt;br /&gt;
my $text = ReadingsVal(&amp;quot;talk&amp;quot;, $EVENT, &amp;quot;Komisch, hier sollte eigentlich etwas Text stehen.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
if (&amp;quot;$EVENT&amp;quot; eq &amp;quot;response&amp;quot;) {&lt;br /&gt;
  #FHEM gibt bei Erfolg eig. keine Rückmeldung, also ist vermutlich was schief gelaufen&lt;br /&gt;
  $text = &amp;quot;Die Haussteuerung hat folgende Meldung gebracht. $text&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; eq &amp;quot;err&amp;quot;) {&lt;br /&gt;
  $text = [&amp;quot;Das habe ich nicht verstanden!&amp;quot;,&amp;quot;Phuu das kann ich noch nicht!&amp;quot;,&amp;quot;Nein! Heute nicht.&amp;quot;, &amp;quot;Wie bitte?&amp;quot;]-&amp;gt;[rand(4)];&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; =~ /^answer/) {&lt;br /&gt;
  $text = ReadingsVal(&amp;quot;talk&amp;quot;, &amp;quot;answers&amp;quot;, &amp;quot;Ich habe nichts zu sagen.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; eq &amp;quot;err&amp;quot;) {&lt;br /&gt;
  #in $text steht schon der fehler drin&lt;br /&gt;
&lt;br /&gt;
} elsif (&amp;quot;$EVENT&amp;quot; eq &amp;quot;done&amp;quot;) {&lt;br /&gt;
  $text = [&amp;quot;Ok.&amp;quot;,&amp;quot;Ja.&amp;quot;,&amp;quot;Gerne.&amp;quot;, &amp;quot;Mach ich!&amp;quot;]-&amp;gt;[rand(4)];&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
  $text = &amp;quot;Oh, es gibt etwas neues, bitte schau mal im Forum bei Talk2Fhem vorbei.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fhem(&#039;set speaker speak &amp;quot;$text&amp;quot;&#039;) if $text;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zeitenerkennung ===&lt;br /&gt;
Die Zeit- und Datum Eingabe kann auf viele verschiedene Arten erfolgen.&amp;lt;br&amp;gt;&lt;br /&gt;
Die Datumerkennung umfasst folgende Phrasen:&lt;br /&gt;
*morgen, übermorgen&lt;br /&gt;
*in ... Wochen, Monat, Jahr&lt;br /&gt;
*nächste Woche, Monat, Jahr&lt;br /&gt;
*Wochentage&lt;br /&gt;
*in ... Tagen&lt;br /&gt;
*am DATUM&lt;br /&gt;
&lt;br /&gt;
Die Zeiterkennung umfasst folgende Phrasen:&lt;br /&gt;
*in,nach ... stunden,minuten,sekunden&lt;br /&gt;
*um ... (Uhr) (...)&lt;br /&gt;
*heute - entspricht 12:00&lt;br /&gt;
*früh - entspricht 9 Uhr&lt;br /&gt;
*abend - entspricht 18 Uhr&lt;br /&gt;
*nachmittag - entspricht 16 Uhr&lt;br /&gt;
*vormittag - entspricht 10:30 Uhr&lt;br /&gt;
*mittag - entspricht 12 Uhr&lt;br /&gt;
*gleich - entspricht 5 Minuten&lt;br /&gt;
*nachher - entspricht 30 Minuten&lt;br /&gt;
*später - entspricht 1 Stunde&lt;br /&gt;
*jetzt&lt;br /&gt;
*sofort&lt;br /&gt;
&lt;br /&gt;
Datum und Zeitangaben können natürlich kombiniert werden.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wird eine Zeit erfolgreich erkannt erfolgt die Ausführung des FHEM-Kommandos über das Modul &#039;&#039;&#039;at&#039;&#039;&#039;. Es wird ein at Eregnis angelegt welches den Namen &#039;&#039;at_&amp;lt;modulname&amp;gt;_&amp;lt;zeitindex&amp;gt;&#039;&#039; erhält.&lt;br /&gt;
&lt;br /&gt;
Bei mehreren Kommandos über das Schlüsselwort &#039;&#039;UND&#039;&#039; wirkt sich der Zeitpunkt des ersten Kommandos auch auf das zweite und dritte ... aus.&lt;br /&gt;
 Schalte die Heizung um 20 Uhr aus und mache die Rollläden runter&lt;br /&gt;
Beide Kommandos werden um 20 Uhr ausgelöst.&lt;br /&gt;
&lt;br /&gt;
Hat das zweite Kommando ebenfalls eine Zeitphrase wird diese Zeit genommen.&lt;br /&gt;
 schalte die Heizung heute Abend ab und mache die Rollläden jetzt runter&lt;br /&gt;
==== Zeitenmodifikation ====&lt;br /&gt;
Wie oben gesehen wird der Zeitpunkt des ersten Kommandos vor dem &amp;quot;und&amp;quot; auch für das zweite nach dem &amp;quot;und&amp;quot; gesetzt. Vorausgesetzt er wird beim 2. Kommando nicht durch eine eigenständige Zeit (hier &amp;quot;jetzt&amp;quot;) ersetzt.&lt;br /&gt;
Wenn man die Zeit des zweiten Kommandos, relativ zum ersten setzen möchte, kann dies mit den Schlüsselwörtern &#039;&#039;dann&#039;&#039;, &#039;&#039;danach&#039;&#039; oder &#039;&#039;wieder&#039;&#039;  formuliert werden.&lt;br /&gt;
 Fahre um 14 Uhr die Rollläden an der Terrasse runter und schalte dann in 2 Minuten die Bewässerung an&lt;br /&gt;
oder&lt;br /&gt;
 Mach am Freitag um 5 Uhr die Heizung aus und in einer Woche wieder an&lt;br /&gt;
&lt;br /&gt;
Manchmal ist es notwendig etwas vor der angegebenen Zeit auszuführen. Hier lässt sich ein Offset zu dem ermittelten Zeitpunkt hinzufügen, um ihn zu ändern.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;perl&#039;&amp;gt;dusche\S?$ = (offset=&amp;gt;-3600, cmd=&amp;gt;&#039;set d_log bad warm&#039;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Der Sprachbefehl&lt;br /&gt;
 ich will um 18:30 Uhr duschen&lt;br /&gt;
Legt folgendes at Ergnis an&lt;br /&gt;
 define at_assi_1513096200 at 2017-12-12T17:30:00 set d_log bad warm&lt;br /&gt;
&lt;br /&gt;
=== Eventkonfiguration ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Befehlsumkehr ===&lt;br /&gt;
Ein zusätzlicher Vorteil dieser Methode ist, dass über das Schlüsselwort &amp;quot;wieder&amp;quot; ein Befehlsumkehr ausgelöst werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
 mach bitte die Garage auf und in 5 Minuten wieder zu&lt;br /&gt;
&lt;br /&gt;
== Konfiguration ==&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration des Moduls wird hauptsächlich über die Definition (DEF) vorgenommen.&lt;br /&gt;
Eine Konfiguration beginnt immer mit der Definition der gesuchten Schlüsselwörtern gefolgt von einem Gleichheitszeichen &#039;&#039;(siehe Randnotiz)&#039;&#039;. Diese werden Anhand von Regulären Ausdrücken (RegExp) beschrieben. Also z.B.:&lt;br /&gt;
 garage auf =&lt;br /&gt;
Das bededutet, sobald die Wörter in der Reihenfolge &amp;quot;garage&amp;quot; und &amp;quot;auf&amp;quot; erkannt werden, wird der Kommandoteil der Konfiguration ausgeführt. Groß- und Kleinschreibung wird grundsätzlich ignoriert.&lt;br /&gt;
&lt;br /&gt;
{{Randnotiz|RNText=Wichtig&lt;br /&gt;
Vor und nach dem Gleichheitszeichen muss mindestens ein Trennzeichen vorhanden sein&lt;br /&gt;
*Vor dem &amp;quot;=&amp;quot; mindestens ein Leer- oder Tabulatorzeichen&lt;br /&gt;
*Nach dem &amp;quot;=&amp;quot; können zusätzlich auch Zeilenumbrüche eingefügt werden&lt;br /&gt;
}}&lt;br /&gt;
Der Kommandoteil folgt dem Gleichheitszeichen &#039;&#039;(siehe Randnotiz)&#039;&#039;. Und kann auf folgende Arten vorliegen.&lt;br /&gt;
* FHEM Kommando&lt;br /&gt;
* { Perl Befehl }&lt;br /&gt;
* ( [[Modul_Talk2Fhem#erweiterte_Befehlskonfiguration]] )&lt;br /&gt;
&lt;br /&gt;
=== Übersicht ===&lt;br /&gt;
 &amp;lt;regexp&amp;gt; = &amp;lt;command&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im ganzen könnte die Konfiguration dann so aussehen:&lt;br /&gt;
 garage\S* auf = set dev_garage open&lt;br /&gt;
&#039;&#039;\S* Siehe hierzu [[Modul_Talk2Fhem#Häufig_verwendete_RegExp|Häufig verwendete RegExp]].&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bei dem vorherigen Beispiel, würde der FHEM Befehl &amp;quot;set garage open&amp;quot; bei allen folgenden Sprachbefehlen ausgeführt werden.&lt;br /&gt;
 Mach bitte die Garage auf&lt;br /&gt;
 Das haus soll das Garagentor aufmachen&lt;br /&gt;
 Garagentür in 5 Minuten auf&lt;br /&gt;
 Die Garagen soll in einer Stunde aufgemacht werden&lt;br /&gt;
&lt;br /&gt;
=== Klammerüberführung ===&lt;br /&gt;
&lt;br /&gt;
Es ist nicht notwendig für jeden Zustand oder jedes Gerät eine eigene Konfigurationzeile zu erzeugen. Hierfür gibt es die Möglichkeit, wie bei Regulären Ausdrücken üblich, Klammern &amp;quot;( )&amp;quot; im &amp;lt;regex&amp;gt;-Teil zu erfassen. Dies erfolgt über die Standartvariablen $1, $2, ..., $n. &amp;quot;n&amp;quot; steht hier für die nte Klammer.&lt;br /&gt;
Zusätzlich gibt es in Talk2Fhem die Möglichkeit die Klammern zu modifizieren.&lt;br /&gt;
&lt;br /&gt;
Soll die Garage auf und zugemacht werden, lässt sich folgendermaßen beschreiben.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
 garage\S* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(\S+)&amp;lt;/span&amp;gt; = set dev_garage &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Satz: &amp;quot;Mach die Garage auf&amp;quot; ergibt dann als FHEM Kommando&lt;br /&gt;
 set dev_garage auf&lt;br /&gt;
&lt;br /&gt;
=== Klammermodifikation ===&lt;br /&gt;
&lt;br /&gt;
Da es in den meißten Fällen nicht gewünscht ist, nur das gefunde Wort in das FHEM Kommando zu überführen, lässt sich zusätzlich das gefundene Wort modifizieren.&lt;br /&gt;
&lt;br /&gt;
==== Variante 1: nach Typ ====&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kann die Klammer auf ihren Typ hin modifiziert werden.&lt;br /&gt;
&lt;br /&gt;
===== Definition =====&lt;br /&gt;
&lt;br /&gt;
 $n{ &#039;&#039;&#039;typ&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;modification&#039;&#039;&#039;, typ2 =&amp;gt; mod2, ..., typn =&amp;gt; modn }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;typ&#039;&#039;&#039; kann eines der folgenden Wörtern enthalten:&lt;br /&gt;
*&#039;&#039;&#039;true&#039;&#039;&#039; sind alle Wörter die eine positive Richtung enthalten. Wie z.B. auf, ein, hoch, an, usw.&lt;br /&gt;
*&#039;&#039;&#039;false&#039;&#039;&#039; sind alle Wörter die eine negative Richtung enthalten. Wie z.B. ab, aus, runter, zu, usw.&lt;br /&gt;
*&#039;&#039;&#039;integer&#039;&#039;&#039; Wort enthält eine Zahl&lt;br /&gt;
*&#039;&#039;&#039;float&#039;&#039;&#039; Wort enthält eine Gleitkommazahl&lt;br /&gt;
*&#039;&#039;&#039;/&amp;lt;regexp&amp;gt;/&#039;&#039;&#039; Wort entspricht der &amp;lt;regexp&amp;gt;&lt;br /&gt;
*&#039;&#039;&#039;word&#039;&#039;&#039; Wort enthält gleich oder mehr als 4 Zeichen &lt;br /&gt;
*&#039;&#039;&#039;empty&#039;&#039;&#039; Wort enthält eine Leere Zeichenkette&lt;br /&gt;
*&#039;&#039;&#039;else&#039;&#039;&#039; Falls keines der Fälle zutrifft&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;modification&#039;&#039;&#039; enthält das einzufügende Wort.&lt;br /&gt;
&lt;br /&gt;
===== Beispiel =====&lt;br /&gt;
 garage\S* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(\S*)&amp;lt;/span&amp;gt; = set dev_garage &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;{ true =&amp;gt; open , false =&amp;gt; close }&lt;br /&gt;
Die Sätze:&lt;br /&gt;
 mach die Garage auf&lt;br /&gt;
 bitte Garagentor schließen &lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set dev_garage open&lt;br /&gt;
 set dev_garage close&lt;br /&gt;
&lt;br /&gt;
==== Variante 2: nach Liste ====&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kann die Klammer anhand einer oder zweier Listen selektiert werden.&lt;br /&gt;
&lt;br /&gt;
===== Definition =====&lt;br /&gt;
&lt;br /&gt;
 $n[ wert1, wert2,,,,, wertn ]&lt;br /&gt;
oder&lt;br /&gt;
 $n[ @liste ]&lt;br /&gt;
&lt;br /&gt;
Innerhalb der Klammern [ ] wird eine Komma separierte Liste mit Namen erwartet die als Modifikatorliste dient. Die sogenannte Modwordlist. Die Werte sind immer optional und können leer gelassen werden. Über das Attribut &#039;&#039;T2F_modwordlist&#039;&#039; können diese Listen zur Übersicht und Wiederverwendbarkeit angelegt werden. Siehe Attribute. Auf diese Listen, lässt sich über den Namen der Liste, mit einem vorangestelltes &#039;@&#039; zugreifen.&lt;br /&gt;
&lt;br /&gt;
===== Beispiel nach Position =====&lt;br /&gt;
&lt;br /&gt;
Beim ersten Beispiel wird eine Zahl im regex-Teil erwartet (\d+). Diese Zahl entscheidet welche Position aus der Modwordlist ausgewählt werden soll.&lt;br /&gt;
 ventilator auf (stufe )?&amp;lt;span style=&#039;color:red&#039;&amp;gt;(\d+)&amp;lt;/span&amp;gt; = set aircon &amp;lt;span style=&#039;color:red&#039;&amp;gt;$2&amp;lt;/span&amp;gt;[ off, level1, level2, level3 ]                                                                                              &lt;br /&gt;
                &amp;lt;span style=&#039;color:gray&#039;&amp;gt;           |------------------&amp;gt;  0      1       2       3&amp;lt;/span&amp;gt;            &lt;br /&gt;
&#039;&#039;(Stufe )?&#039;&#039; bedeutet: Das Wort Stufe kann, muss aber nicht.&lt;br /&gt;
&lt;br /&gt;
Die Sätze:&lt;br /&gt;
 Ventilator in 10 Minuten auf Stufe 0&lt;br /&gt;
 Ventilator auf 3&lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set aircon off&lt;br /&gt;
 set aircon level3&lt;br /&gt;
&lt;br /&gt;
===== Beispiel nach Vergleichsliste =====&lt;br /&gt;
&lt;br /&gt;
Hier kommt eine weitere Liste ins Spiel. Die sogenannte Keywordlist ist im Eigentlichen eine RegExp &amp;quot;Ver-oder-ung&amp;quot;.&lt;br /&gt;
 ( key1 | key2 | ... | keyn )&lt;br /&gt;
oder&lt;br /&gt;
 ( @keywordlist )&lt;br /&gt;
Diese Liste mit Schlüsselwörtern wird im &amp;lt;regex&amp;gt;-Teil angegeben. Hier entscheidet nicht eine Zahl über die Position, sondern die Position die in der Keywordlist einen Treffer hat wird an selber Position in der Modwordlist ausgewählt. Im Attribut T2F_keywordlist können vordefinierte Listen angelegt werden und mit @keylist ausgewählt werden&lt;br /&gt;
&lt;br /&gt;
 blendet.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(Wohnzimmer|Esszimmer|Küche)&amp;lt;/span&amp;gt; = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;[act_lvgroom, act_dinroom, act_kitchen] 70&lt;br /&gt;
               &amp;lt;span style=&#039;color:gray&#039;&amp;gt;|__________|_______|___________________|_____________|____________|&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;.*&#039;&#039; beliebig viele Zeichen&lt;br /&gt;
&lt;br /&gt;
Die Sätze: &lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 ich sitze geblendet im Wohnzimmer&lt;br /&gt;
 die sonne blendet in der Küche&lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set act_dinroom 70&lt;br /&gt;
 set act_lvgroom 70&lt;br /&gt;
 set act_kitchen 70&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Auswahl des Listenelements &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Soll bei der Nutzung der Variable nicht der Wert aus dem Sprachbefehl, sondern der Wert der Liste genutzt werden, so wird an die Variable ein @ angehängt. So wird bei&lt;br /&gt;
 blendet.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(Wohnzimmer|Esszimmer|Küche)&amp;lt;/span&amp;gt; = set act_&amp;lt;span style=&#039;color:red&#039;&amp;gt;$1@&amp;lt;/span&amp;gt; 70&lt;br /&gt;
&lt;br /&gt;
Die Sätze &lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 es blendet im esszimmer&lt;br /&gt;
immer zu&lt;br /&gt;
 set act_Esszimmer 70&lt;br /&gt;
&lt;br /&gt;
führen, da die Liste das Esszimmer großgeschrieben enthält.&lt;br /&gt;
&lt;br /&gt;
===== Ergänzung =====&lt;br /&gt;
Ähnlich wie in Variante 1, könne  auch hier auf die Schlüsselwörte &lt;br /&gt;
 empty für leere Zeichenkette &lt;br /&gt;
und &lt;br /&gt;
 else für alle anderen Fälle&lt;br /&gt;
zugegriffen werden. Hierbei wird der Modwordlist einfach empty oder else gefolgt von dem gewünschten Wert als nächstes Element angehängt.&lt;br /&gt;
 $n[ wert1, wert2,,,, empty, wert3, else, wert4 ]&lt;br /&gt;
&lt;br /&gt;
=== erweiterte Befehlskonfiguration ===&lt;br /&gt;
Um Talk2Fhem in den Konfigurationszeilen weitere Parameter zu übergeben, ist eine gesonderte Syntax zu verwenden.&lt;br /&gt;
 &amp;lt;regexp&amp;gt; = ( option =&amp;gt; &#039;value&#039;  ,&lt;br /&gt;
              opt2   =&amp;gt; &#039;value2&#039; ,&lt;br /&gt;
              ... &lt;br /&gt;
              optn   =&amp;gt; &#039;valuen&#039; ) &lt;br /&gt;
Es stehen folgende Optionen zur Verfügung:&lt;br /&gt;
*cmd    =&amp;gt; enthält das FHEM Kommando.  Wie oben beschrieben.&lt;br /&gt;
*answer  =&amp;gt;  Ein in Anführungszeichen (&amp;quot; oder &#039;) gesetzter Perl-Befehl, dessen Rückgabe in das Reading &#039;&#039;answer&#039;&#039; geschrieben wird.&lt;br /&gt;
* offset =&amp;gt;  Ganzzahliger Wert in Sekunden der dem Zeitpunkt addiert wird. Siehe [[Modul_Talk2Fhem#Zeitenmodifikation]]&lt;br /&gt;
&lt;br /&gt;
=== Antworten ===&lt;br /&gt;
In Talk2Fhem können Antworten, die das Modul ausgeben soll, definiert werden. Hier können Fragen verarbeitet werden oder auch den Erfolg eines Kommandos bestätigt werden.&lt;br /&gt;
&lt;br /&gt;
Über die [[Modul_Talk2Fhem#erweiterte_Befehlskonfiguration]], erhält der Parameter &amp;quot;answer&amp;quot; einen Perl Befehl, dessen Rückgabe die Antwort darstellt.&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Erfolgsmeldung ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;tu was = ( cmd =&amp;gt; &amp;quot;set tue es&amp;quot; , answer =&amp;gt; &#039;&amp;quot;Erledigt&amp;quot;&#039; )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Man beachte hier, dass die Parameter immer in Anführungszeichen gesetzt werden müssen. In diesem Fall der Perl Befehl. Ein Text in Perl wird ebenfalls in Anführungszeichen gesetzt, deswegen die doppelten Anführungszeichen!&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Zustandsabfrage ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;wurde es getan = ( answer =&amp;gt; &#039;Value(&amp;quot;tue&amp;quot;) eq &amp;quot;es&amp;quot; ? &amp;quot;Ja&amp;quot; : &amp;quot;Nein&amp;quot;&#039;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Temperaturabfragen ====&lt;br /&gt;
Eine einfache Temperaturabfrage könnte so aussehen.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;wie.*(kalt|warm|grad|temperatur) = ( answer =&amp;gt; &#039;&amp;quot;Die Temperatur beträgt &amp;quot;.ReadingsVal(&amp;quot;tempdev&amp;quot;, &amp;quot;temperature&amp;quot;, &amp;quot;Fehler&amp;quot;)&#039; )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Für eine Raumbezogene Temperaturabfrage, siehe [[Modul_Talk2Fhem#Anwendungsbeispiele_und_Vorlagen]]&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Folgende Attribute werden zur Zeit unterstützt&lt;br /&gt;
=== T2F_keywordlist ===&lt;br /&gt;
 &amp;lt;Name&amp;gt; = &amp;lt;kommaseparierte Liste mit RegExp&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Beispiele&#039;&#039;&#039;&lt;br /&gt;
 rooms = haus|überall|wohnung , wohnzimmer , bad\S* , toilette|wc , büro , ...&lt;br /&gt;
 names = Mama , Papa , Kevin , Jacqueline&lt;br /&gt;
 channels = ard|das erste , zdf , rtl , sat 1 , vox , rtl2 , prosieben , kabel eins , arte&lt;br /&gt;
Man beachte hier die möglichkeit der RegExp&amp;lt;br&amp;gt;&lt;br /&gt;
Das Schlüsselwort &#039;&#039;&#039;haus&#039;&#039;&#039; löst das selbe aus wie &#039;&#039;&#039;überall&#039;&#039;&#039; und &#039;&#039;&#039;wohnung&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;Genauso &#039;&#039;&#039;bad&#039;&#039;&#039; oder &#039;&#039;&#039;badezimmer&#039;&#039;&#039; oder &#039;&#039;&#039;badeirgendewas&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== T2F_modwordlist ===&lt;br /&gt;
 &amp;lt;Name&amp;gt; = &amp;lt;kommaseparierte Liste mir RegExp&amp;gt;&lt;br /&gt;
Die Positionen der gewählten Geräte, ist eine Zuordnung zu den Listen in&#039;&#039;T2F_keywordlist&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;Wenn Wohnzimmer in der keywordliste &amp;lt;rooms&amp;gt; an Position 2 steht muss der Rolladenaktor in der modworliste &amp;lt;roll&amp;gt; auch an Position 2 stehen.&lt;br /&gt;
 roll = rollos_alle , d_rollo_wz , hm_roll_bad.* , hm_roll_wc , hm_roll_buero.* , ...&lt;br /&gt;
 lights = alle_lichte , &#039;&#039;&#039;&amp;quot;sw_wz1,sw_wz2&amp;quot;&#039;&#039;&#039; , sw_bad.* , sw_wc&lt;br /&gt;
Sollen einem Schlüsselwort mehrere Aktoren zugeordnet werden, geht das über sogenannte &amp;quot;Quotes&amp;quot;. (Anführungszeichen) Siehe &amp;lt;lights&amp;gt;.&lt;br /&gt;
 &amp;quot;a,b&amp;quot;  oder  &#039;a,b&#039;  oder  a\,b&lt;br /&gt;
&lt;br /&gt;
=== T2F_disableumlautescaping ===&lt;br /&gt;
&lt;br /&gt;
Deaktiviert das Konvertieren der Umlaute innnerhalb von regulären Ausdrücken in &#039;&#039;&#039;\S\S?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== T2F_language ===&lt;br /&gt;
&lt;br /&gt;
Legt die verwendete Sprache fest. Alternativ wird das Globale Attribut &#039;&#039;language&#039;&#039; verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== disable ===&lt;br /&gt;
Deaktiviert das Ausführen des FHEM Kommandos&lt;br /&gt;
=== verbose ===&lt;br /&gt;
&lt;br /&gt;
== Anwendungsbeispiele und Vorlagen ==&lt;br /&gt;
Hier folgen diverse Vorlagen und Beispiele die jeweils an die eigenen Bedürfnisse angepassst werden sollten/müssen. Hierzu sind die entsprechenden Stellen &amp;lt;span style=&#039;color:red&#039;&amp;gt;rot&amp;lt;/span&amp;gt; markiert.&lt;br /&gt;
=== Keywordlist ===&lt;br /&gt;
Eine typische Keywordlist wäre eine Auflistung der benötigten Räume&lt;br /&gt;
 rooms = haus|überall|wohnung,wohnzimmer,esszimmer,bad\S*,toilette|wc,&lt;br /&gt;
 büro,schlafzimmer,ankleide|garderobe,kinderzimmer,spielzimmer,&lt;br /&gt;
 flur|gang|diele,garage,garten,terrasse,balkon,&lt;br /&gt;
 eg|erdgescho\S*,og|obergescho\S*,\S*auße\S*( haus)?|vor der tür&lt;br /&gt;
&lt;br /&gt;
=== Einfaches schalten ===&lt;br /&gt;
 licht (\S+) = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;dev_light&amp;lt;/span&amp;gt; $1{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
=== Einfaches schalten mit eigenen Wörtern ===&lt;br /&gt;
Will man neben an/aus einen weiteren Zustand selbst definieren, kann das so geschehen.&lt;br /&gt;
 garage (\S+) = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;dev_gate&amp;lt;/span&amp;gt; $1{ /&amp;lt;span style=&#039;color:red&#039;&amp;gt;kurz&amp;lt;/span&amp;gt;/ =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;open-for-time 5&amp;lt;/span&amp;gt;, true =&amp;gt; open, false =&amp;gt; close }&lt;br /&gt;
&lt;br /&gt;
=== Einfaches schalten mit Räumen ===&lt;br /&gt;
 licht (\S+ ){0,2} (&amp;lt;span style=&#039;color:red&#039;&amp;gt;wohnzimmer|esszimmer|küche|terrasse&amp;lt;/span&amp;gt;) (\S+) = set $2[&amp;lt;span style=&#039;color:red&#039;&amp;gt;light_wz,light_ez,light_kitchen,light_outside&amp;lt;/span&amp;gt;] $3{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
Bei größeren Mengen an Räumen und Geräten bietet sich das anlegen von Keyword- und Modwordlisten an. &lt;br /&gt;
 licht (\S+ ){0,2} (&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;) (\S+) = set $2[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@lights&amp;lt;/span&amp;gt;] $3{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
&lt;br /&gt;
=== Rolladen fahren ===&lt;br /&gt;
Sind die Rollläden innerhalb von FHEM über das Attribut &amp;quot;room&amp;quot; den Räumen mit Klarnamen zugeordnet, lässt sich das ganze am einfachsten konfigurieren.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;1.  nach Devicetyp&#039;&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(\S+) (auf )?(\S+) = {fhem(&#039;set room=&#039;.ucfirst(&#039;$3&#039;).&#039;:FILTER=a:subType=blindActuator &amp;lt;span style=&#039;color:red&#039;&amp;gt;$5&amp;lt;/span&amp;gt;{true=&amp;gt;on, false=&amp;gt;off, integer=&amp;gt;&#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;set_$5&amp;lt;/span&amp;gt;&#039;)}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erklärung&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn das Device vom subTyp &amp;quot;blindActuator&amp;quot; ist (HomeMatic Rolladenactor) und es im Raum $3 ist, wird dieses Device gefahren. Die Funktion ucfirst ist notwendig damit der erste Buchstabe groß geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;2.  nach Devicenamen&#039;&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(\S+) (auf )?(\S+) = {fhem(&#039;set room=&#039;.ucfirst(&#039;$3&#039;).&#039;:FILTER=rollo.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;$5&amp;lt;/span&amp;gt;{true=&amp;gt;on, false=&amp;gt;off, integer=&amp;gt;&#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;set_$5&amp;lt;/span&amp;gt;&#039;)}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erklärung&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Gleiche wie oben, nur das alle Devices die mit rollo beginnen im Raum $3 gefahren werden. (rollo.*)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;3.  nach Benutzerdefinierten Räumen&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Ansonsten müssen wir dem Modul sagen in welchem Raum welches Device sitzt. Das hat dafür den Vorteil das die Räume als RegExp angegeben werden können.&amp;lt;br&amp;gt;Wir erzeugen eine Modwordlist &#039;&#039;rollos&#039;&#039; in der wir alle Rollladen &amp;quot;Devices&amp;quot; auflisten. Die Reihenfolge ist an der Keywordlist &amp;quot;rooms&amp;quot; ([[Modul_Talk2Fhem#Keywordlist]]) anzupassen.&lt;br /&gt;
 rollos = &amp;lt;span style=&#039;color:red&#039;&amp;gt;r_alle&amp;lt;/span&amp;gt;,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_wz&amp;lt;/span&amp;gt;,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_ez&amp;lt;/span&amp;gt;,,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_buero&amp;lt;/span&amp;gt;,...&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;)? (auf )?(\S+) = set $3[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rollos&amp;lt;/span&amp;gt;, empty, &amp;lt;span style=&#039;color:red&#039;&amp;gt;rollos_alle&amp;lt;/span&amp;gt;] $5{true=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt;, integer=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;&amp;quot;set_$5&amp;quot;&amp;lt;/span&amp;gt;}&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 Rollos auf&lt;br /&gt;
 Rolllos Überall schließen &lt;br /&gt;
 Rollo im Wohnzimmer hoch&lt;br /&gt;
 Rolladen im Esszimmer runter&lt;br /&gt;
 Rollläden in der Küche auf 50&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Damit wäre eigentlich schon alles abgedeckt. Folgendes Beispiel ist aber auch noch nützlich.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
  (blendet|schatte\S?) ?(\S+ ){0,2}(&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;) = set $3[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rollos&amp;lt;/span&amp;gt;] &amp;lt;span style=&#039;color:red&#039;&amp;gt;set_70&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 ich werde geblendet in der Küche&lt;br /&gt;
 die Sonne blendet mich im Badezimmer&lt;br /&gt;
 beschatte das Haus&lt;br /&gt;
 mach schatten im Erdgeschoss&lt;br /&gt;
&lt;br /&gt;
=== GoogleCast Befehle ===&lt;br /&gt;
Etwas bessere Lautstärkebefehle als die von Google.&lt;br /&gt;
Die Lautstärken müssten noch dem eigenen Geschmack angepasst werden&lt;br /&gt;
 #GoogleCast Commandos&lt;br /&gt;
 leise$            =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 14&lt;br /&gt;
 normale lautstärke =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 20&lt;br /&gt;
 laut$             =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 30&lt;br /&gt;
 (ein wenig|etwas|viel)? ?(lauter|leiser)  =  { fhem(&amp;quot;set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume &amp;quot;.(ReadingsVal(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;volume&amp;quot;, 0)$2[+,-]$1[3,5,10,empty,7])) }&lt;br /&gt;
&#039;&#039;&#039; Beispielsätze &#039;&#039;&#039;&lt;br /&gt;
 Mach leise&lt;br /&gt;
 Mach lauter&lt;br /&gt;
 Mach etwas leiser&lt;br /&gt;
 Mach viel lauter&lt;br /&gt;
&lt;br /&gt;
=== Talk Timer zurücksetzen ===&lt;br /&gt;
Sollen alle von Talk2Fhem angelegten Timer gelöscht werden.&lt;br /&gt;
 (timer|kommandos) (löschen|zurücksetzen) = delete at_&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;.*&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 bitte alle timer zurücksetzen&lt;br /&gt;
 zukünftige kommandos löschen&lt;br /&gt;
&lt;br /&gt;
=== Frage Antwort ===&lt;br /&gt;
==== Raumbezogene Temperaturansage ====&lt;br /&gt;
Wir erzeugen wieder unsere Modwordlist sagen wir @sens gefüllt mit den Temperaturfühler &amp;quot;Devices&amp;quot;. Reihenfolge wie immer die der Keywordlist @rooms.&lt;br /&gt;
 wie.*(kalt|warm|grad|temperatur).*(&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;@rooms&amp;lt;/span&amp;gt;) = ( answer =&amp;gt; &#039;&amp;quot;Die Temperatur beträgt &amp;quot;.ReadingsVal(&amp;quot;$2[&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;@sens&amp;lt;/span&amp;gt;]&amp;quot;, &amp;quot;&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;temperature&amp;lt;/span&amp;gt;&amp;quot;, &amp;quot;unbekannt&amp;quot;).&amp;quot; grad&amp;quot;&#039; )&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 wie warm ist es im Wohnzimmer&lt;br /&gt;
 wie ist die Temperatur in der Küche&lt;br /&gt;
 wie kalt ist es draußen&lt;br /&gt;
&lt;br /&gt;
==== Multiple Antworten ====&lt;br /&gt;
 Hallo Haus = ( answer =&amp;gt; &#039;[&amp;quot;Hallo auch!&amp;quot;,&amp;quot;Guten Tag!&amp;quot;,&amp;quot;Ahoi!&amp;quot;]-&amp;gt;[rand(&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt;)]&#039; ) &lt;br /&gt;
Wählt zufällig eine der drei Aussagen.&lt;br /&gt;
&lt;br /&gt;
==== Ausgabe eines oder mehrerer Zustände ====&lt;br /&gt;
Angenommen man möchte wissen ob das Haus abgeschlossen ist. Und in FHEM existiert ein Dummy der diesen Zustand wiederspiegelt und im Reading text die offenen Fenster und Türen aufgelistet sind. Kann man folgendermaßen den Status erfragen&lt;br /&gt;
 (alles|das haus) (zu|abgeschlossen) = (&lt;br /&gt;
   answer =&amp;gt; &#039;(Value(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;d_schliessung&amp;lt;/span&amp;gt;&amp;quot;) eq &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;zu&amp;lt;/span&amp;gt;&amp;quot;) &lt;br /&gt;
   ? &amp;quot;Es ist alles zu&amp;quot; &lt;br /&gt;
   : &amp;quot;Nein, offen sind: &amp;quot;.ReadingsVal(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;d_schliessung&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;text&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;&amp;quot;)&#039;&lt;br /&gt;
&lt;br /&gt;
==== Zustandsabfrage anhand des Aliasnamen ====&lt;br /&gt;
Möchte man alle Geräte anhand seines Attribut &amp;quot;alias&amp;quot; ansprechen, um dessen Status zu erfragen, könnte das so erfolgen.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039; &lt;br /&gt;
 (zustand|status) (\S+)* (\S+) = (answer=&amp;gt;&#039;my $s=Value((grep { &amp;quot;$3&amp;quot; =~ /$attr{$_}{&amp;lt;span style=&#039;color:red&#039;&amp;gt;alias&amp;lt;/span&amp;gt;}/i } (keys %attr))[0]);; &amp;quot;Der Status ist &amp;quot;.$s if $s&#039;)&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 Wie ist der Zustand der Lüftung&lt;br /&gt;
 sag mir den Status der Haustür&lt;br /&gt;
Es ist auch möglich ein eigenes Attribut zu kreieren, und dieses als Klarnamenattribut zu verwenden. Hierzu einfach im Device global ein userattr hinzufügen. z.B.&lt;br /&gt;
 attr global userattr T2F_alias&lt;br /&gt;
Jetzt stehen in allen Devices das Attribut T2F_alias zur Verfügung. Vorteil ist das dann auch wieder RegExp verwendet werden können. Im oberen Beispiel müsste dann dass rot markierte &amp;quot;alias&amp;quot; durch &amp;quot;T2F_alias&amp;quot; ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration innerhalb der Geräte ===&lt;br /&gt;
Neben der Identifikation der Geräte über die vorhandenen FHEM-Attribute (z.B. room, alias, ...) kann eine alternative Konfiguration auch über eigens für Talk2Fhem angelegte Attribute erfolgen. Die hierfür notwendigen Grundlagen und einige Beispiele sollen im Folgenden beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Grundlagen / Voraussetzungen ====&lt;br /&gt;
1. Anlegen der notwendigen userattr am global-Device:&lt;br /&gt;
&lt;br /&gt;
Erweiterung des Attributes userattr des Gerätes global um folgende Einträge:&lt;br /&gt;
  T2F_places:textField-long T2F_properties:textField-long T2F_rooms:textField-long T2F_types_color:textField-long T2F_types_heating:textField-long T2F_types_info:textField-long T2F_types_switch:textField-long&lt;br /&gt;
&lt;br /&gt;
2. Optional: Hilfsfunktionen für das automatische Füllen der T2F_keywordlist im talk-Device bei Änderung eines T2F-Attributes eines Gerätes&lt;br /&gt;
&lt;br /&gt;
2a. erstellen einer sub in der 99_myUtils.pm:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;  sub fill_T2F_keywordlist&lt;br /&gt;
  {&lt;br /&gt;
    my ($name, $t2f_device) = @_;&lt;br /&gt;
    $name =~ s/T2F_//g;&lt;br /&gt;
    if ($name eq &#039;userattr&#039;)&lt;br /&gt;
    {&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    Log 0, &amp;quot;List: &amp;quot;.$name;&lt;br /&gt;
    my $currentAttr = AttrVal($t2f_device,&amp;quot;T2F_keywordlist&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    my @currentAttrParts = split(/$name = /, $currentAttr);&lt;br /&gt;
    my $currentAttrBeg = @currentAttrParts[0];&lt;br /&gt;
    $currentAttrBeg = substr($currentAttrBeg, 0, -1);&lt;br /&gt;
    my @currentAttrEnd = split(/\n/, @currentAttrParts[1], 2);&lt;br /&gt;
    my @array = devspec2array(&#039;a:T2F_&#039;.$name.&#039;=.+&#039;);&lt;br /&gt;
    my @attributes = ();&lt;br /&gt;
    if (@array &amp;gt; 0 and defined($defs{$array[0]}))&lt;br /&gt;
    {&lt;br /&gt;
      foreach (@array){&lt;br /&gt;
      my @attrVals = split(/\n/,AttrVal($_, &#039;T2F_&#039;.$name, &#039;&#039;));&lt;br /&gt;
      foreach (@attrVals){&lt;br /&gt;
          my $attrVal = $_;&lt;br /&gt;
          $attrVal =~ s/  / /g;&lt;br /&gt;
          $attrVal =~ s/ =&amp;gt; /=&amp;gt;/g;&lt;br /&gt;
          my @attrValParts = split(/=&amp;gt;/,$attrVal);&lt;br /&gt;
          $attrVal = @attrValParts[0];&lt;br /&gt;
          $attrVal =~ s/!//g;&lt;br /&gt;
          $attrVal =~ s/, /,/g;&lt;br /&gt;
          my @attr = split(/,/, $attrVal);&lt;br /&gt;
          push(@attributes, @attr);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    my %hash   = map { $_ =&amp;gt; 1 } @attributes;&lt;br /&gt;
    my @unique = keys %hash;&lt;br /&gt;
    my $result = $currentAttrBeg.&amp;quot;\n&amp;quot;.$name.&amp;quot; = &amp;quot;.join(&amp;quot;, &amp;quot;, @unique).&amp;quot;\n&amp;quot;.@currentAttrEnd[1];&lt;br /&gt;
    $result =~ s/\n\n/\n/g;&lt;br /&gt;
    $result =~ s/  / /g;&lt;br /&gt;
    fhem(&#039;attr &#039;.$t2f_device.&#039; T2F_keywordlist &#039;.$result);&lt;br /&gt;
  }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2b. Erstellen eines DOIFs zum Aufruf der sub:&lt;br /&gt;
&lt;br /&gt;
  defmod talk.DI.fillAttr DOIF ([global:&amp;quot;^ATTR.*T2F_.*&amp;quot;]) ({my $val = ReadingsVal(&amp;quot;$SELF&amp;quot;, &amp;quot;e_global_events&amp;quot;, &amp;quot;&amp;quot;); $val =~ m/(\S*) (\S*) (\S*) (.*)/; if ($2 ne &#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;&#039; &amp;amp;&amp;amp; $2 ne &#039;global&#039;) { fill_T2F_keywordlist(&amp;quot;$3&amp;quot;, &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;&amp;quot;);}})&lt;br /&gt;
  attr talk.DI.fillAttr do always&lt;br /&gt;
&lt;br /&gt;
3. Optional: Erlauben von Umlauten in den T2F-Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_disableumlautescaping 1  &lt;br /&gt;
  &lt;br /&gt;
Nun können die T2F-Attribute pro FHEM-Device definiert und dann in den Talk2Fhem-Befehlen benutzt werden. Wurde der Punkt 2 abgearbeitet, so werden mit dem Füllen der Attribute am Geräte auch die Keywordlisten am talk-Device gefüllt. Wie diese dann verwendet werden können, sollen die folgenden Beispiele zeigen.&lt;br /&gt;
&lt;br /&gt;
==== Schalten von Geräten ====&lt;br /&gt;
&lt;br /&gt;
Ausgangssituation: Es gibt drei Lampen Lampe1, Lampe2, Lampe3 und ein Nachtlicht mit einer Eule mit folgenden Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr Lampe1 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe1 T2F_rooms Haus, Obergeschoss, !Esszimmer&lt;br /&gt;
  attr Lampe1 T2F_places Decke, Tür&lt;br /&gt;
  attr Lampe1 T2F_properties hell,!&lt;br /&gt;
&lt;br /&gt;
  attr Lampe2 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe2 T2F_rooms Haus, Obergeschoss, !Esszimmer&lt;br /&gt;
  attr Lampe2 T2F_places Tisch, Esstisch&lt;br /&gt;
  attr Lampe2 T2F_properties dunkel,schwach,!&lt;br /&gt;
&lt;br /&gt;
  attr Lampe3 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe3 T2F_rooms Haus, Obergeschoss, !Küche&lt;br /&gt;
  attr Lampe3 T2F_places Besenschrank&lt;br /&gt;
  &lt;br /&gt;
  attr Nachtlicht T2F_types_switch Lampe, !Licht, Eule, Nachtlicht&lt;br /&gt;
  attr Nachtlicht T2F_rooms Haus, Obergeschoss, !Kinderschlafzimmer&lt;br /&gt;
  attr Nachtlicht T2F_places Steckdose&lt;br /&gt;
&lt;br /&gt;
Durch die in Punkt 2 der Voraussetzungen genannten Funktionen wurden folgende T2F-keywordlisten automatisch angelegt:&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_keywordlist rooms = Kinderschlafzimmer, Haus, Küche, Obergeschoss, Esszimmer &lt;br /&gt;
                            places = Tür, Steckdose, Tisch, Decke, Esstisch&lt;br /&gt;
                            properties = hell, dunkel, schwach&lt;br /&gt;
                            types_switch = Lampe, Licht, Eule&lt;br /&gt;
&lt;br /&gt;
Die Definition für das T2F-Device lautet dann wie folgt:&lt;br /&gt;
&lt;br /&gt;
  #   1              2                 3                4            5          6          7      &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; ?(@properties) &amp;amp;&amp;amp; (@types_switch) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) &amp;amp;&amp;amp; (\S+)(schalten|machen)?$ =&lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_switch=.*$3@.*:FILTER=T2F_rooms=.*$4@.*:FILTER=T2F_properties=.*$2@.*:FILTER=T2F_places=.*$5@.* $6{true=&amp;gt;on, false=&amp;gt;off}&#039;,&lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;$AGAIN&amp;quot; ? &amp;quot;dann $DATE wieder $6{true=&amp;gt;ein, false=&amp;gt;aus}&amp;quot; : &amp;quot;$1{/bitte/=&amp;gt;Gern, else=&amp;gt;Das heißt Bitte}, ich schalte $1{/bitte/=&amp;gt;, else=&amp;gt;trotzdem} folgende Geräte $6{true=&amp;gt;ein, false=&amp;gt;aus}: &amp;quot;.T2F_answer(&amp;quot;T2F_types_switch=.*$3@.*:FILTER=T2F_rooms=.*$4@.*:FILTER=T2F_properties=.*$2@.*:FILTER=T2F_places=.*$5@.*&amp;quot;,&amp;quot;T2F_types_switch&amp;quot;)&#039;)&lt;br /&gt;
                            &lt;br /&gt;
Damit sind dann die folgenden Sprachbefehle möglich:&lt;br /&gt;
&lt;br /&gt;
  Schalte das Licht in der Küche ein                      =&amp;gt; schaltet Lampe3 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte die helle Lampe im Esszimmer an                 =&amp;gt; schaltet Lampe1 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht im Esszimmer über dem Esstisch ein    =&amp;gt; schaltet Lampe2 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte die Eule ein                                    =&amp;gt; schaltet Nachtlicht ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht im Esszimmer aus}                     =&amp;gt; schaltet Lampe1 und Lampe2 aus&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht aus                                   =&amp;gt; schaltet alle vier Lichter aus&lt;br /&gt;
&lt;br /&gt;
Um in der Antwort die Liste der geschalteten Geräte genannt zu bekommen, wird die sub T2F_answer aus der 99_myUtils aufgerufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;  sub T2F_answer&lt;br /&gt;
  {&lt;br /&gt;
    my ($filter, $type) = @_;&lt;br /&gt;
    my $answer;&lt;br /&gt;
    my @devices = devspec2array($filter);&lt;br /&gt;
    if (@devices &amp;gt; 0 and defined($defs{$devices[0]}))&lt;br /&gt;
    {&lt;br /&gt;
      #$answer = &amp;quot;Ich habe folgende Geräte &amp;quot;.$command.&amp;quot;: &amp;quot;;&lt;br /&gt;
      foreach (@devices){&lt;br /&gt;
        $answer = $answer.&amp;quot;\n&amp;quot;;&lt;br /&gt;
        my $devAttr = AttrVal($_, $type, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        $devAttr = AttrVal($_, &#039;T2F_properties&#039;, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        $devAttr = AttrVal($_, &#039;T2F_rooms&#039;, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        $devAttr = AttrVal($_, &#039;T2F_places&#039;, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    return $answer.&amp;quot;\n&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Benennung der Geräte erfolgt auf Basis derer T2F-Attribute: Typ, Eigenschaft, Raum, Ort. Ist das jeweilige Attribut leer, ist es auch in der Antwort leer. Enthält die jeweilige Attributliste ein Ausrufezeichen (!), so wird der Eintrag nach dem Ausrufezeichen für die Antwort verwendet (z.B. Esszimmer als Raum). Steht das Ausrufezeichen am Ende, so wird der Eintrag in der Antwort leer gelassen (z.B. die Eigenschaft bei Lampe1). Ist kein Ausrufezeichen vorhanden, so wird der erste Eintrag verwendet.&lt;br /&gt;
&lt;br /&gt;
==== Einstellen der Heizung ====&lt;br /&gt;
&lt;br /&gt;
Das gleiche Prinzp wie bei den Lampen kann auch für die Einstellung der Heizung verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Ausgangssituation: In der Küche, im Kinderschlafzimmer und im Esszimmer gibt es jeweils eine Heizung (Homematic HM-CC-RT-DN) mit folgenden Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr HeizungEsszimmer T2F_places Heizung,!&lt;br /&gt;
  attr HeizungEsszimmer T2F_rooms Haus,Obergeschoss,Essbereich,!Esszimmer&lt;br /&gt;
  attr HeizungEsszimmer T2F_types_heating Heizung,Temperatur,Esszimmer,Essbereich,!&lt;br /&gt;
&lt;br /&gt;
  attr HeizungKüche T2F_places Heizung,!&lt;br /&gt;
  attr HeizungKüche T2F_rooms Haus,Obergeschoss,Essbereich,!Küche&lt;br /&gt;
  attr HeizungKüche T2F_types_heating Heizung,Temperatur,Küche,Essbereich,!&lt;br /&gt;
&lt;br /&gt;
  attr HeizungKiSchla T2F_places Heizung,!&lt;br /&gt;
  attr HeizungKiSchla T2F_rooms Haus,Obergeschoss,!Kinderschlafzimmer&lt;br /&gt;
  attr HeizungKiSchla T2F_types_heating Heizung,Temperatur,Kinderschlafzimmer,!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mit der T2F-Definition&lt;br /&gt;
&lt;br /&gt;
  #   1             2                  3        4      5                  &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; (@types_heating) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; (auf (\d+) grad|auto\S*)( stellen| setzen| einstellen| ein)?$ = &lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.* $5{integer=&amp;gt;desired-temp $5, else=&amp;gt;controlMode auto}&#039;,&lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;$AGAIN&amp;quot; ? &amp;quot;dann $DATE wieder auf Automatik&amp;quot; : &amp;quot;Die Durchschnittstemperatur beträgt dort zur Zeit &amp;quot;.averageTemp(&amp;quot;T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.*&amp;quot;).&amp;quot; Grad\n$1{/bitte/=&amp;gt;Gern, else=&amp;gt;Das heißt Bitte}, ich stelle die Heizung in folgenden Räumen auf $5{integer=&amp;gt;$5 Grad, else=&amp;gt;Automatik}: &amp;quot;.T2F_answer(&amp;quot;T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.*&amp;quot;,&amp;quot;T2F_types_heating&amp;quot;)&#039;)&lt;br /&gt;
  &lt;br /&gt;
funktionieren folgende Sprachbefehle:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Esszimmer auf 21 Grad        =&amp;gt; Stellt die Heizung im Esszimmer auf 21 Grad&lt;br /&gt;
  &lt;br /&gt;
  Bitte stell die Heizung im Essbereich auf 21 Grad       =&amp;gt; Stellt die Heizungen im Esszimmer und in der Küche auf 21 Grad&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Obergeschoss auf Automatik   =&amp;gt; Stellt die drei Heizungen auf Automatik&lt;br /&gt;
  &lt;br /&gt;
Dadurch, dass im Attribut T2F_types_heating auch die Räume aufgeführt sind, sind auch Befehle in folgender Form möglich:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Küche auf 21 Grad                       =&amp;gt; Stellt die Heizung in der Küche auf 21 Grad&lt;br /&gt;
&lt;br /&gt;
Auch kann in diesem (wie auch in den oben aufgeführten Schaltbefehlen) mit &amp;quot;wieder&amp;quot; gearbeitet werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Essbereich auf 21 Grad und in 2 Stunden wieder auf Automatik&lt;br /&gt;
  &lt;br /&gt;
Für die Generierung der Antwort wird neben der bei den Schaltbefehlen bereits gezeigten sub T2F_answer eine weiter Funktion verwende, welche die Durchschnittstemperatur im zu schaltenden Bereich ermittelt und ausgibt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
  sub averageTemp($)&lt;br /&gt;
  {&lt;br /&gt;
    my ($filter) = @_;&lt;br /&gt;
    my @tempDevices = devspec2array($filter);&lt;br /&gt;
    my $count = 0;&lt;br /&gt;
    my $measuredTemp = 0;&lt;br /&gt;
    if (@tempDevices &amp;gt; 0 and defined($defs{$tempDevices[0]})){&lt;br /&gt;
      foreach (@tempDevices){&lt;br /&gt;
        $measuredTemp = $measuredTemp + ReadingsVal($_, &amp;quot;measured-temp&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        $count = $count + 1;&lt;br /&gt;
      }&lt;br /&gt;
      return $measuredTemp / $count;&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
==== Einstellen der Farbe von Farbwechsellampen (Philips Hue, Wifilight, ...) ====&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel zum Einstellen der Lichtfarbe nehmen wir eine Farbwechsellampe LampeBunt an, welche den Befehl RGB unterstützt. Diese erhält folgende Attribute:&lt;br /&gt;
&lt;br /&gt;
  attr LampeBunt T2F_places Decke,Couch,Sofa&lt;br /&gt;
  attr LampeBunt T2F_rooms Haus,Dachgeschoss,!Wohnzimmer&lt;br /&gt;
  attr LampeBunt T2F_types_color Lampe,Licht&lt;br /&gt;
  attr LampeBunt T2F_types_switch Lampe,Licht&lt;br /&gt;
  &lt;br /&gt;
Durch das Attribut T2F_types_switch lässt sich diese über die bereits beschriebene Schaltlogik ein und ausschalten. Durch die zusätzlich T2F-Definition&lt;br /&gt;
&lt;br /&gt;
  #   1              2               3             4              5               6 &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; (@types_color) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) &amp;amp;&amp;amp; auf (@colors)( schalten| stellen)?$ = &lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_color=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_places=.*$4@.* RGB $5[@rgb]&#039;, &lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;Ich schalte folgende Geräte auf $5@: &amp;quot;.T2F_answer(&amp;quot;T2F_types_color=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_places=.*$4@.*&amp;quot;,&amp;quot;T2F_types_color&amp;quot;)&#039;)&lt;br /&gt;
&lt;br /&gt;
und die entsprechenden Attribute am T2F-Device talk (HINWEIS: eigene Listen können Problemlos ergänzt werden, diese werden durch die Hilfsfunktionen NICHT überschrieben)&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_keywordlist colors = Aus, Schwarz, Dunkles Schiefergrau, Schiefergrau, Helles Schiefergrau, Helles Stahlblau, Mattes Grau, Grau, Dunkelgrau, Silber, Hellgrau, Gainsboro, Rauchiges Weiß, Geisterweiß, Weiß, Schneeweiß, Elfenbein, Blütenweiß, Muschel, Altgold, Leinenfarbe, Antikes Weiß, Mandelweiß, Cremiges Papaya, Beige, Mais, Helles Goldrutengelb, Hellgelb, Chiffongelb, Blasse Goldrutenfarbe, Khaki, Gelb, Gold, Orange, Dunkles Orange, Goldrute, dunkle Goldrutenfarbe, Peru, Schokolade, Sattelbraun, Ocker, Braun, Dunkelrot, Kastanienbraun, Ziegelfarbe, Indischrot, Karmesinrot, Rot, Orangenrot, Tomatenrot, Koralle, Lachs, Helles Korallenrot, Dunkle Lachsfarbe, Helle Lachsfarbe, Sandbraun, Rosiges Braun, Gelbbraun, Grobes Braun, Weizen, Pfirsich, Navajoweiß, Tomatencreme, Rosige Lavenderfarbe, Altrosa, Rosa, Hellrosa, Leuchtendes Rosa, Fuchsie, Magentarot, Tiefrosa, Mittleres Violettrot, Blasses Violettrot, Pflaume, Distel, Lavendelfarbe, Violett, Orchidee, Dunkles Magentarot, Violett, Indigo, Blauviolett, Dunkles Violett, Dunkle Orchideenfarbe, Mittleres Violett, Mittlere Orchideenfarbe, Mittleres Schieferblau, Schieferblau, Dunkles Schieferblau, Mitternachtsblau, Marineblau, Dunkelblau, Mittelblau, Blau, Königsblau, Stahlblau, Kornblumenblau, Dodger-Blau, Tiefes Himmelblau, Helles Himmelblau, Himmelblau, Hellblau, Zyanblau, Blaugrün, Taubenblau, Helles Cyanblau, Aliceblau, Himmelblau, Cremig Pfefferminz, Honigmelone, Aquamarinblau, Türkis, Blasses Türkis, Mittleres Türkis, Dunkles Türkis, Mittleres Aquamarinblau, Helles Seegrün, Dunkles Zyanblau, Entenbraun, Kadettblau, Mittleres Seegrün, Dunkles Seegrün, Hellgrün, Blassgrün, Mittleres Frühlingsgrün, Frühlingsgrün, Zitronengrün, Gelbgrün, Seegrün, Waldgrün, Grün, Dunkelgrün, Olivfarbiges Graubraun, Dunkles Olivgrün, Olivgrün, Dunkles Khaki, Gelbgrün, Hellgrün, Grüngelb&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_modwordlist rgb = 000000, 000000, 8FBC8F, 708090, 778899, B0C4DE, 696969, 808080, A9A9A9, C0C0C0, D3D3D3, DCDCDC, F5F5F5, F8F8FF, FFFFFF, FFFAFA, FFFFF0, FFFAF0, FFF5EE, FDF5E6, FAF0E6, FAEBD7, FFEBCD, FFEFD5, F5F5DC, FFF8DC, FAFAD2, FFFFE0, FFFACD, EEE8AA, F0E68C, FFFF00, FFD700, FFA500, FF8C00, DAA520, B8860B, CD853F, D2691E, 8B4513, A0522D, A52A2A, 8B0000, 800000, B22222, CD5C5C, DC143C, FF0000, FF4500, FF6347, FF7F50, FA8072, F08080, E9967A, FFA07A, F4A460, BC8F8F, D2B48C, DEB887, F5DEB3, FFDAB9, FFDEAD, FFE4C4, FFF0F5, FFE4E1, FFC0CB, FFB6C1, FF69B4, FF00FF, FF00FF, FF1493, C71585, DB7093, DDA0DD, D8BFD8, E6E6FA, EE82EE, DA70D6, 8B008B, 800080, 4B0082, 8A2BE2, 9400D3, 9932CC, 9370DB, BA55D3, 7B68EE, 6A5ACD, 483D8B, 191970, 000080, 00008B, 0000CD, 0000FF, 4169E1, 4682B4, 6495ED, 1E90FF, 00BFFF, 87CEFA, 87CEEB, ADD8E6, 00FFFF, 00FFFF, B0E0E6, E0FFFF, A0CE00, F0FFFF, F5FFFA, F0FFF0, 7FFFD4, 40E0D0, AFEEEE, 48D1CC, 00CED1, 66CDAA, 20B2AA, 008B8B, 008080, 5F9EA0, 3CB371, 8FBC8F, 90EE90, 98FB98, 00FA9A, 00FF7F, 00FF00, 32CD32, 2E8B57, 228B22, 008000, 006400, 6B8E23, 556B2F, 808000, BDB76B, 9ACD32, 7FFF00, ADFF2F&lt;br /&gt;
&lt;br /&gt;
kann die Farbe nun auch über folgenden Sprachbefehle eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte schalte die Lampe im Wohnzimmer an der Couch auf Olivfarbiges Graubraun&lt;br /&gt;
&lt;br /&gt;
Dadurch, das die Liste colors den Wert &amp;quot;Aus&amp;quot; mit dem entsprechenden Wert &amp;quot;000000&amp;quot; in der Liste rgb enthält, kann die Lampe über die gleiche Logik auch ausgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte schalte das Licht im Wohnzimmer auf Pflaume und in einer Stunde wieder aus&lt;br /&gt;
  &lt;br /&gt;
==== Abfragen beliebiger Geräteinformationen ====&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Möglichkeit auf, die Antworten für Statusabfragen direkt am abgefragten Gerät zu definieren. Hierfür werden zunächst eine Definition am T2F-Device&lt;br /&gt;
&lt;br /&gt;
  #              1             2                3            4&lt;br /&gt;
  Wie &amp;amp;&amp;amp; ?(@properties)&amp;amp;&amp;amp; (@types_info) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) = &lt;br /&gt;
  (answer=&amp;gt;&#039;T2F_getInfo(&amp;quot;T2F_types_info=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_properties=.*$1@.*:FILTER=T2F_places=.*$4@.*&amp;quot;,&amp;quot;$2@&amp;quot;)&#039;)&lt;br /&gt;
  &lt;br /&gt;
und eine Funktion in der 99_myUtils&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
  sub T2F_getInfo&lt;br /&gt;
  {&lt;br /&gt;
    my ($filter,$info) = @_;&lt;br /&gt;
    my @devices = devspec2array($filter);&lt;br /&gt;
    if (@devices &amp;gt; 0 and defined($defs{$devices[0]}))&lt;br /&gt;
    {&lt;br /&gt;
      if (@devices &amp;gt; 1)&lt;br /&gt;
      {&lt;br /&gt;
        return &amp;quot;Ich habe mehr als ein Gerät gefunden, die Information kann nicht abgerufen werden.&amp;quot;;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      my $answer = &amp;quot;Die Abfrage von &amp;quot;.$info.&amp;quot; für &amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      my $devAttr = AttrVal($_, &#039;T2F_properties&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      $devAttr = AttrVal($_, &#039;T2F_rooms&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      $devAttr = AttrVal($_, &#039;T2F_places&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
        &lt;br /&gt;
      my @attrVals = split(/\n/,AttrVal(@devices[0], &#039;T2F_types_info&#039;, &#039;&#039;));&lt;br /&gt;
      foreach (@attrVals){&lt;br /&gt;
        my $attrVal = $_;&lt;br /&gt;
        $attrVal =~ s/  / /g;&lt;br /&gt;
        $attrVal =~ s/ =&amp;gt; /=&amp;gt;/g;&lt;br /&gt;
        my @attrValParts = split(/=&amp;gt;/,$attrVal);&lt;br /&gt;
        if (@attrValParts[0] =~ /$info/)&lt;br /&gt;
        {&lt;br /&gt;
          my $cmd = &amp;quot;&#039;&amp;quot;.@attrValParts[1].&amp;quot;&#039;&amp;quot;;&lt;br /&gt;
          $cmd =~ s/ #/ &#039;.ReadingsVal(&#039;@devices[0]&#039;, &#039;/g;&lt;br /&gt;
          $cmd =~ s/#/&#039;, &#039;&#039;).&#039;/g;&lt;br /&gt;
          return eval($cmd);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration und Funktionsweise sind nun wie folgt: Das Gerät, dessen Status abgefragt werden sollen erhält neben den Oben bereits beschriebenen Attributen für Eigenschaft, Raum und Ort noch das Attribut T2F_types_info, welches Zeilenweise die abzufragenen Status in der folgenden Form enthält:&lt;br /&gt;
&lt;br /&gt;
  abfragewert =&amp;gt; Das ist die Antwort mit den Wert #reading#&lt;br /&gt;
  &lt;br /&gt;
Mit der Form #reading# können die Werte von Readings des abgefragten Device zum Zeitpunkt der Abfrage ermittelt werden. Für das Beispiel einer Heizung im Esszimmer wäre das zum Beispiel wie folgt möglich:&lt;br /&gt;
&lt;br /&gt;
  attr HeizungEsszimmer T2F_places Heizung,!&lt;br /&gt;
  attr HeizungEsszimmer T2F_rooms Haus,Obergeschoss,Essbereich,!Esszimmer&lt;br /&gt;
  attr HeizungEsszimmer T2F_types_info warm,Temperatur =&amp;gt; Die Temperatur beträgt #measured-temp# Grad und soll #desired-temp# Grad erreichen\&lt;br /&gt;
                                       Ventilstellung =&amp;gt; Das Ventil ist #ValvePosition# Prozent geöffnet&lt;br /&gt;
&lt;br /&gt;
Damit sind dann folgende Abfragen möglich:&lt;br /&gt;
&lt;br /&gt;
  Wie warm ist die Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
  Wie ist die Temperatur der Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
  Wie ist die Ventilstellung der Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
Anders als bei den anderen Beispielen, wo alle gefundenen Geräte geschaltet werden, muss die Abfrage hier so detailliert sein, dass nur ein Gerät gefunden wird.&lt;br /&gt;
&lt;br /&gt;
== Häufig verwendete RegExp ==&lt;br /&gt;
Perl Regular Expression, also ein regulärer Ausdruck der Programmiersprache Perl, ist eine Werkzeug um Zeichenketten zu beschreiben. Hier wird ein kurzer Einblick auf die im Artikel häufig genutzten RegExp zu geben.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung der Syntax kann hier eingesehen werden. [http://jkorpela.fi/perl/regexp.html]&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! RegExp !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| \S* || Beliebig viele (*) nicht Leerzeichen (\S). Für unbekannten und unwichtigen Wortendungen&amp;lt;br&amp;gt;z.b. garage\S* ist bei Garage, Garagentor oder Garagentür erfolgreich&lt;br /&gt;
|-&lt;br /&gt;
| \S+ || Mehr als ein Zeichen (+) welches kein Leerzeichen ist (\S)&lt;br /&gt;
|-&lt;br /&gt;
| \S\S? || Ein oder zwei Zeichen die keine Leerzeichen sind. Das &amp;quot;?&amp;quot; wirkt hier nur auf das angrenzende &amp;quot;\S&amp;quot;.&amp;lt;br&amp;gt;Sollte für Umlaute verwendet werden, da bei manchen Eingabemethoden Probleme mit Umlauten auftreten können.&lt;br /&gt;
|-&lt;br /&gt;
| (wort )?  || Ein bestimmtes Wort oder nicht.&lt;br /&gt;
|-&lt;br /&gt;
| (wort1&amp;amp;#124;wort2) || Entweder wort1 oder Wort2&lt;br /&gt;
|-&lt;br /&gt;
| wort$ || Nur wenn das Wort am ende der Zeichenkette steht.&lt;br /&gt;
|-&lt;br /&gt;
| (\S+){0,2} || Keins, eins oder zwei Wörter. Kann für Artikel wie z.B. &amp;quot;(in der&amp;amp;#124;in dem&amp;amp;#124;im&amp;amp;#124;auf der&amp;amp;#124;...)?&amp;quot; eingesetzt werden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Eingabemethoden ==&lt;br /&gt;
Die Herkunft der Sprachbefehle für das Modul sind vielfältig. Hier werden einige Methoden beschrieben wie der Sprachbefehl in das Modul gelangen kann.&lt;br /&gt;
=== Messenger Telegram ===&lt;br /&gt;
Ist ein [[TelegramBot]] telbot definiert, reicht ein einfaches &amp;quot;notify&amp;quot; um die Nachrichten an FHEM an Talk2Fhem weiterzuleiten.&lt;br /&gt;
 define &amp;lt;span style=&#039;color:red&#039;&amp;gt;n_telbot&amp;lt;/span&amp;gt; notify &amp;lt;span style=&#039;color:red&#039;&amp;gt;telbot&amp;lt;/span&amp;gt;:msgText.* set talk $EVENT&lt;br /&gt;
Schon kann mit FHEM gechattet werden... ;)&lt;br /&gt;
&lt;br /&gt;
=== Google Home Geräte ===&lt;br /&gt;
Momentan ist es leider noch notwendig über einen Umweg die Sprache von einem GoogleHome in FHEM zu bringen. Hierzu ist es notwendig einen funktionierenden DNS Service am laufen zu haben. Damit FHEM per Webadresse im Internet erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
*Ein FHEMWEB Device anlegen&lt;br /&gt;
 define api FHEMWEB 8087 global&lt;br /&gt;
 attr api HTTPS 1&lt;br /&gt;
 attr api allowfrom  1&lt;br /&gt;
 attr api csrfToken  None&lt;br /&gt;
*Ein allowed Device anlegen&lt;br /&gt;
 define allowed_api allowed api&lt;br /&gt;
 attr allowed_api allowedCommands set&lt;br /&gt;
 attr allowed_api allowedDevices talk&lt;br /&gt;
 attr allowed_api basicAuth  {&amp;quot;$user:$password&amp;quot; eq &#039;user:passwort&#039;}&lt;br /&gt;
 attr allowed_api validFor   api&lt;br /&gt;
*Mit Googlekono bei IFTTT.com anmelden&lt;br /&gt;
*New Applet&lt;br /&gt;
*+this GoogleAssistant -&amp;gt; Say a phrase with a text ingredient&lt;br /&gt;
* Die drei Triggertexte wählen z.b.&lt;br /&gt;
**das Haus $&lt;br /&gt;
**sag dem Haus $&lt;br /&gt;
**frag das Haus $&lt;br /&gt;
***Problem bei zu kurzen Texten hat GoogleHome keine anderen Anfragen mehr angenommen.&lt;br /&gt;
*Einen Antworttext überlegen z.B. OK und in &amp;quot;What do you want the Assistant to say in response?&amp;quot; eintragen&lt;br /&gt;
*Language Deutsch&lt;br /&gt;
*+that Webhooks&lt;br /&gt;
*URL wählen&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;https://user:password@dnsservice:54387/fhem?cmd.talk=set talk {{TextField}}&amp;amp;XHR=1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
*Fertig&lt;br /&gt;
&lt;br /&gt;
Jetzt wird der gesamte Text bei dem genannten Triggerworten an FHEM weitergeleitet.&lt;br /&gt;
&lt;br /&gt;
== Ausgabemethoden ==&lt;br /&gt;
&lt;br /&gt;
Siehe hierzu [[Modul_Talk2Fhem#Beispiel|Anwendungsbeispiel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Sprachsteuerung|Talk2FHEM]]&lt;/div&gt;</summary>
		<author><name>RoBra81</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Talk2Fhem&amp;diff=24792</id>
		<title>Talk2Fhem</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Talk2Fhem&amp;diff=24792"/>
		<updated>2018-01-28T12:40:15Z</updated>

		<summary type="html">&lt;p&gt;RoBra81: Ergänzung von Beispielen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Das Modul stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her&lt;br /&gt;
|ModType=h]&lt;br /&gt;
|ModCmdRef=Talk2Fhem&lt;br /&gt;
|ModForumArea=Unterst&amp;amp;uuml;tzende Dienste&lt;br /&gt;
|ModTechName=39_Talk2Fhem.pm&lt;br /&gt;
|ModOwner=Oliver Georgi&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Seite beschreibt die Funktionsweise und Konfiguration des Moduls 39_Talk2Fhem.pm&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen ==&lt;br /&gt;
[[Datei:ModulTalk2FhemScreenshot.png|360px|thumb|right]]&lt;br /&gt;
Es ist sehr zu empfehlen, für die Konfiguration des Moduls, im Webfrontend von FHEM die Syntaxhervorhebung zu aktivieren. Die Aktivierung des erweiterten Editors ist [[Konfiguration#Syntaxhervorhebung|hier]] beschrieben.&lt;br /&gt;
&lt;br /&gt;
Kenntnisse im Bereich Regulärer Ausdrücke (RegExp) in Perl sind hilfreich, aber nicht zwingend erforderlich. Ein kurzer Einstieg kann hier eingesehen werden. [[Modul_Talk2Fhem#Häufig_verwendete_RegExp|Häufig_verwendete_RegExp]]&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
Das Modul Talk2Fhem stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her. Es ist ein überaus flexibles und relativ einfach zu konfigurierendes Script mit dem man sehr natürlich kommunizieren kann. Die Konfiguration erfolgt dabei über das FHEM Webfrontend. &lt;br /&gt;
&lt;br /&gt;
Bei der Verarbeitung der Sprachbefehle erfolgt keine grammatikalische Analyse, sondern es wird auf definierte Schlüsselwörter reagiert. Das Modul erkennt von sich aus diverse Zeit- und Datumsangaben und löst bei Bedarf zu diesen Zeiten die FHEM Kommandos aus.&lt;br /&gt;
&lt;br /&gt;
=== Funktionsweise ===&lt;br /&gt;
&lt;br /&gt;
Die Zerlegung des Sprachbefehls erfolgt in mehreren Schritten. &lt;br /&gt;
# Aufteilen des Sprachbefehls in einzelne Kommandos anhand des Wortes UND&lt;br /&gt;
# Erkennen von Zeit- und Datumsangaben und entfernen für die weitere Verarbeitung&lt;br /&gt;
# Entfernung unnötiger Wörter&lt;br /&gt;
# Vergleich mit den definierten Schlüsselwörtern&lt;br /&gt;
# Konvertieren in ein FHEM Kommando&lt;br /&gt;
# Zeitgebundenes auslösen des FHEM Kommandos&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Solange das Modul noch nicht offiziell aufgenommen wurde, muss die Datei 39_Talk2Fhem.pm manuell in das Verzeichnis FHEM/ kopiert werden. Siehe Forumsbeitrag. [https://forum.fhem.de/index.php/topic,80960.0.html]&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
 define talk Talk2Fhem&lt;br /&gt;
Zum testen der Konfiguration ist es Ratsam vorerst das Attribut disable auf 1 zu setzen. Hierbei wird die Auslösung der FHEM Kommandos unterdrückt.&lt;br /&gt;
 attr talk disable 1&lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
Der Sprachbefehl wird über das Kommando &#039;&#039;&#039;set&#039;&#039;&#039; oder &#039;&#039;&#039;set !&#039;&#039;&#039; an das Modul geleitet.&lt;br /&gt;
 set talk Guten Morgen liebes Zuhause&lt;br /&gt;
Wird kein Text angehängt, wird der letzte Sprachbefehl erneut ausgeführt.&lt;br /&gt;
&lt;br /&gt;
=== Readings ===&lt;br /&gt;
&lt;br /&gt;
Im Reading &#039;&#039;&#039;set&#039;&#039;&#039; steht der letzte gesendete Sprachbefehl.&lt;br /&gt;
&amp;lt;br&amp;gt;Im Reading &#039;&#039;&#039;cmds&#039;&#039;&#039; steht das letzte ausgeführte FHEM-Kommando dessen Rückgabe in in das Reading &#039;&#039;&#039;fhem&#039;&#039;&#039; geschrieben wird. &lt;br /&gt;
&lt;br /&gt;
Die Antworten und Modulinterne Fehler werden in den Readings &#039;&#039;&#039;answers&#039;&#039;&#039; und &#039;&#039;&#039;err&#039;&#039;&#039; ausgegben. &lt;br /&gt;
&lt;br /&gt;
Das Reading &#039;&#039;&#039;status&#039;&#039;&#039; wird jedes mal gesetzt und erhält Werte nach folgender Priorität.&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|1.||&#039;&#039;&#039;response&#039;&#039;&#039; ||wenn das FHEM Kommando eine Meldung ausgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|2.||&#039;&#039;&#039;disabled&#039;&#039;&#039; ||wenn das Attribute disable auf 1 steht&lt;br /&gt;
|-&lt;br /&gt;
|3.||&#039;&#039;&#039;err&#039;&#039;&#039; ||wenn der Sprachbefehl einen Fehler zurückgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|4.||&#039;&#039;&#039;answer&#039;&#039;&#039; ||wenn der Sprachbefehl eine Antwort ausgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|5.||&#039;&#039;&#039;done&#039;&#039;&#039; ||wenn keines der oberen Fälle eingetreten ist, also alles gut verlaufen ist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Beispiel ===&lt;br /&gt;
Die FHEM Befehle werden eigenständig ausgeführt, sie können aber zur Überprüfung auch weitergeleitet werden. Das Beispiel zeigt auch wie auf Fehler und Antworten von Talk2Fhem reragiert werden kann.&lt;br /&gt;
Erstellen eines Notify&lt;br /&gt;
 define n_talk notify talk:.* {}&lt;br /&gt;
Folgendes in der Definition von n_talk einfügen&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 talk:.* {&lt;br /&gt;
 # Sende die Antwort per Telegram und gebe es über das GoogleHome aus&lt;br /&gt;
 	if ($EVENT =~ s/^answers: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telegram _msg \@USER $EVENT&amp;quot;);&lt;br /&gt;
 		fhem(&amp;quot;set d_googlespeak $EVENT&amp;quot;);	&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 # Schicke den Fehler per Telegram und sag am GoogleHome das es nicht geklappt hat.&lt;br /&gt;
 	if ($EVENT =~ s/^err: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telbot _msg \@Oliver $EVENT&amp;quot;);&lt;br /&gt;
 		my @a = (&amp;quot;Das hat leider nicht geklappt&amp;quot;, &amp;quot;Es gab leider einen Fehler&amp;quot;, &amp;quot;Es tut mir leid. Das hat nicht funktioniert.&amp;quot;, &amp;quot;Es ist leider zu einem Fehler gekommen&amp;quot;,&amp;quot;Könntest du das vielleicht nochmal anders sagen&amp;quot;, &amp;quot;Mhhh, das kann ich so nicht verstehen&amp;quot;);&lt;br /&gt;
 		fhem(&amp;quot;set d_googlespeak $a[int(rand($#a))]&amp;quot;);&lt;br /&gt;
 	} &lt;br /&gt;
 &lt;br /&gt;
 # Schick mir alle ausgeführten Befehle als Telegram&lt;br /&gt;
 &lt;br /&gt;
 	if ($EVENT =~ s/^cmds: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telbot _msg \@USER $EVENT&amp;quot;);&lt;br /&gt;
 	} &lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zeitenerkennung ===&lt;br /&gt;
Die Zeit- und Datum Eingabe kann auf viele verschiedene Arten erfolgen.&amp;lt;br&amp;gt;&lt;br /&gt;
Die Datumerkennung umfasst folgende Phrasen:&lt;br /&gt;
*morgen, übermorgen&lt;br /&gt;
*in ... Wochen, Monat, Jahr&lt;br /&gt;
*nächste Woche, Monat, Jahr&lt;br /&gt;
*Wochentage&lt;br /&gt;
*in ... Tagen&lt;br /&gt;
*am DATUM&lt;br /&gt;
&lt;br /&gt;
Die Zeiterkennung umfasst folgende Phrasen:&lt;br /&gt;
*in,nach ... stunden,minuten,sekunden&lt;br /&gt;
*um ... (Uhr) (...)&lt;br /&gt;
*heute - entspricht 12:00&lt;br /&gt;
*früh - entspricht 9 Uhr&lt;br /&gt;
*abend - entspricht 18 Uhr&lt;br /&gt;
*nachmittag - entspricht 16 Uhr&lt;br /&gt;
*vormittag - entspricht 10:30 Uhr&lt;br /&gt;
*mittag - entspricht 12 Uhr&lt;br /&gt;
*gleich - entspricht 5 Minuten&lt;br /&gt;
*nachher - entspricht 30 Minuten&lt;br /&gt;
*später - entspricht 1 Stunde&lt;br /&gt;
*jetzt&lt;br /&gt;
*sofort&lt;br /&gt;
&lt;br /&gt;
Datum und Zeitangaben können natürlich kombiniert werden.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wird eine Zeit erfolgreich erkannt erfolgt die Ausführung des FHEM-Kommandos über das Modul &#039;&#039;&#039;at&#039;&#039;&#039;. Es wird ein at Eregnis angelegt welches den Namen &#039;&#039;at_&amp;lt;modulname&amp;gt;_&amp;lt;zeitindex&amp;gt;&#039;&#039; erhält.&lt;br /&gt;
&lt;br /&gt;
Bei mehreren Kommandos über das Schlüsselwort &#039;&#039;UND&#039;&#039; wirkt sich der Zeitpunkt des ersten Kommandos auch auf das zweite und dritte ... aus.&lt;br /&gt;
 Schalte die Heizung um 20 Uhr aus und mache die Rollläden runter&lt;br /&gt;
Beide Kommandos werden um 20 Uhr ausgelöst.&lt;br /&gt;
&lt;br /&gt;
Hat das zweite Kommando ebenfalls eine Zeitphrase wird diese Zeit genommen.&lt;br /&gt;
 schalte die Heizung heute Abend ab und mache die Rollläden jetzt runter&lt;br /&gt;
==== Zeitenmodifikation ====&lt;br /&gt;
Wie oben gesehen wird der Zeitpunkt des ersten Kommandos vor dem &amp;quot;und&amp;quot; auch für das zweite nach dem &amp;quot;und&amp;quot; gesetzt. Vorausgesetzt er wird beim 2. Kommando nicht durch eine eigenständige Zeit (hier &amp;quot;jetzt&amp;quot;) ersetzt.&lt;br /&gt;
Wenn man die Zeit des zweiten Kommandos, relativ zum ersten setzen möchte, kann dies mit den Schlüsselwörtern &#039;&#039;dann&#039;&#039;, &#039;&#039;danach&#039;&#039; oder &#039;&#039;wieder&#039;&#039;  formuliert werden.&lt;br /&gt;
 Fahre um 14 Uhr die Rollläden an der Terrasse runter und schalte dann in 2 Minuten die Bewässerung an&lt;br /&gt;
oder&lt;br /&gt;
 Mach am Freitag um 5 Uhr die Heizung aus und in einer Woche wieder an&lt;br /&gt;
&lt;br /&gt;
Manchmal ist es notwendig etwas vor der angegebenen Zeit auszuführen. Hier lässt sich ein Offset zu dem ermittelten Zeitpunkt hinzufügen, um ihn zu ändern.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;perl&#039;&amp;gt;dusche\S?$ = (offset=&amp;gt;-3600, cmd=&amp;gt;&#039;set d_log bad warm&#039;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Der Sprachbefehl&lt;br /&gt;
 ich will um 18:30 Uhr duschen&lt;br /&gt;
Legt folgendes at Ergnis an&lt;br /&gt;
 define at_assi_1513096200 at 2017-12-12T17:30:00 set d_log bad warm&lt;br /&gt;
&lt;br /&gt;
== Konfiguration ==&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration des Moduls wird hauptsächlich über die Definition (DEF) vorgenommen.&lt;br /&gt;
Eine Konfiguration beginnt immer mit der Definition der gesuchten Schlüsselwörtern gefolgt von einem Gleichheitszeichen &#039;&#039;(siehe Randnotiz)&#039;&#039;. Diese werden Anhand von Regulären Ausdrücken (RegExp) beschrieben. Also z.B.:&lt;br /&gt;
 garage auf =&lt;br /&gt;
Das bededutet, sobald die Wörter in der Reihenfolge &amp;quot;garage&amp;quot; und &amp;quot;auf&amp;quot; erkannt werden, wird der Kommandoteil der Konfiguration ausgeführt. Groß- und Kleinschreibung wird grundsätzlich ignoriert.&lt;br /&gt;
&lt;br /&gt;
{{Randnotiz|RNText=Wichtig&lt;br /&gt;
Vor und nach dem Gleichheitszeichen muss mindestens ein Trennzeichen vorhanden sein&lt;br /&gt;
*Vor dem &amp;quot;=&amp;quot; mindestens ein Leer- oder Tabulatorzeichen&lt;br /&gt;
*Nach dem &amp;quot;=&amp;quot; können zusätzlich auch Zeilenumbrüche eingefügt werden&lt;br /&gt;
}}&lt;br /&gt;
Der Kommandoteil folgt dem Gleichheitszeichen &#039;&#039;(siehe Randnotiz)&#039;&#039;. Und kann auf folgende Arten vorliegen.&lt;br /&gt;
* FHEM Kommando&lt;br /&gt;
* { Perl Befehl }&lt;br /&gt;
* ( [[Modul_Talk2Fhem#erweiterte_Befehlskonfiguration]] )&lt;br /&gt;
&lt;br /&gt;
=== Übersicht ===&lt;br /&gt;
 &amp;lt;regexp&amp;gt; = &amp;lt;command&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im ganzen könnte die Konfiguration dann so aussehen:&lt;br /&gt;
 garage\S* auf = set dev_garage open&lt;br /&gt;
&#039;&#039;\S* Siehe hierzu [[Modul_Talk2Fhem#Häufig_verwendete_RegExp|Häufig verwendete RegExp]].&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bei dem vorherigen Beispiel, würde der FHEM Befehl &amp;quot;set garage open&amp;quot; bei allen folgenden Sprachbefehlen ausgeführt werden.&lt;br /&gt;
 Mach bitte die Garage auf&lt;br /&gt;
 Das haus soll das Garagentor aufmachen&lt;br /&gt;
 Garagentür in 5 Minuten auf&lt;br /&gt;
 Die Garagen soll in einer Stunde aufgemacht werden&lt;br /&gt;
&lt;br /&gt;
=== Klammerüberführung ===&lt;br /&gt;
&lt;br /&gt;
Es ist nicht notwendig für jeden Zustand oder jedes Gerät eine eigene Konfigurationzeile zu erzeugen. Hierfür gibt es die Möglichkeit, wie bei Regulären Ausdrücken üblich, Klammern &amp;quot;( )&amp;quot; im &amp;lt;regex&amp;gt;-Teil zu erfassen. Dies erfolgt über die Standartvariablen $1, $2, ..., $n. &amp;quot;n&amp;quot; steht hier für die nte Klammer.&lt;br /&gt;
Zusätzlich gibt es in Talk2Fhem die Möglichkeit die Klammern zu modifizieren.&lt;br /&gt;
&lt;br /&gt;
Soll die Garage auf und zugemacht werden, lässt sich folgendermaßen beschreiben.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
 garage\S* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(\S+)&amp;lt;/span&amp;gt; = set dev_garage &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Satz: &amp;quot;Mach die Garage auf&amp;quot; ergibt dann als FHEM Kommando&lt;br /&gt;
 set dev_garage auf&lt;br /&gt;
&lt;br /&gt;
=== Klammermodifikation ===&lt;br /&gt;
&lt;br /&gt;
Da es in den meißten Fällen nicht gewünscht ist, nur das gefunde Wort in das FHEM Kommando zu überführen, lässt sich zusätzlich das gefundene Wort modifizieren.&lt;br /&gt;
&lt;br /&gt;
==== Variante 1: nach Typ ====&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kann die Klammer auf ihren Typ hin modifiziert werden.&lt;br /&gt;
&lt;br /&gt;
===== Definition =====&lt;br /&gt;
&lt;br /&gt;
 $n{ &#039;&#039;&#039;typ&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;modification&#039;&#039;&#039;, typ2 =&amp;gt; mod2, ..., typn =&amp;gt; modn }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;typ&#039;&#039;&#039; kann eines der folgenden Wörtern enthalten:&lt;br /&gt;
*&#039;&#039;true&#039;&#039; sind alle Wörter die eine positive Richtung enthalten. Wie z.B. auf, ein, hoch, an, usw.&lt;br /&gt;
*&#039;&#039;false&#039;&#039; sind alle Wörter die eine negative Richtung enthalten. Wie z.B. ab, aus, runter, zu, usw.&lt;br /&gt;
*&#039;&#039;integer&#039;&#039; Wort enthält eine Zahl&lt;br /&gt;
*&#039;&#039;empty&#039;&#039; Wort enthält eine Leere Zeichenkette&lt;br /&gt;
*&#039;&#039;/&amp;lt;regexp&amp;gt;/&#039;&#039; Wort entspricht der &amp;lt;regexp&amp;gt;&lt;br /&gt;
*&#039;&#039;else&#039;&#039; Falls keines der Fälle zutrifft&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;modification&#039;&#039;&#039; enthält das einzufügende Wort.&lt;br /&gt;
&lt;br /&gt;
===== Beispiel =====&lt;br /&gt;
 garage\S* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(\S*)&amp;lt;/span&amp;gt; = set dev_garage &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;{ true =&amp;gt; open , false =&amp;gt; close }&lt;br /&gt;
Die Sätze:&lt;br /&gt;
 mach die Garage auf&lt;br /&gt;
 bitte Garagentor schließen &lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set dev_garage open&lt;br /&gt;
 set dev_garage close&lt;br /&gt;
&lt;br /&gt;
===== Befehlsumkehr =====&lt;br /&gt;
Ein zusätzlicher Vorteil dieser Methode ist, dass über das Schlüsselwort &amp;quot;wieder&amp;quot; ein Befehlsumkehr ausgelöst werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
 mach bitte die Garage auf und in 5 Minuten wieder zu&lt;br /&gt;
&lt;br /&gt;
==== Variante 2: nach Liste ====&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kann die Klammer anhand einer oder zweier Listen selektiert werden.&lt;br /&gt;
&lt;br /&gt;
===== Definition =====&lt;br /&gt;
&lt;br /&gt;
 $n[ wert1, wert2,,,,, wertn ]&lt;br /&gt;
oder&lt;br /&gt;
 $n[ @liste ]&lt;br /&gt;
&lt;br /&gt;
Innerhalb der Klammern [ ] wird eine Komma separierte Liste mit Namen erwartet die als Modifikatorliste dient. Die sogenannte Modwordlist. Die Werte sind immer optional und können leer gelassen werden. Über das Attribut &#039;&#039;T2F_modwordlist&#039;&#039; können diese Listen zur Übersicht und Wiederverwendbarkeit angelegt werden. Siehe Attribute. Auf diese Listen, lässt sich über den Namen der Liste, mit einem vorangestelltes &#039;@&#039; zugreifen.&lt;br /&gt;
&lt;br /&gt;
===== Beispiel nach Position =====&lt;br /&gt;
&lt;br /&gt;
Beim ersten Beispiel wird eine Zahl im regex-Teil erwartet (\d+). Diese Zahl entscheidet welche Position aus der Modwordlist ausgewählt werden soll.&lt;br /&gt;
 ventilator auf (stufe )?&amp;lt;span style=&#039;color:red&#039;&amp;gt;(\d+)&amp;lt;/span&amp;gt; = set aircon &amp;lt;span style=&#039;color:red&#039;&amp;gt;$2&amp;lt;/span&amp;gt;[ off, level1, level2, level3 ]                                                                                              &lt;br /&gt;
                &amp;lt;span style=&#039;color:gray&#039;&amp;gt;           |------------------&amp;gt;  0      1       2       3&amp;lt;/span&amp;gt;            &lt;br /&gt;
&#039;&#039;(Stufe )?&#039;&#039; bedeutet: Das Wort Stufe kann, muss aber nicht.&lt;br /&gt;
&lt;br /&gt;
Die Sätze:&lt;br /&gt;
 Ventilator in 10 Minuten auf Stufe 0&lt;br /&gt;
 Ventilator auf 3&lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set aircon off&lt;br /&gt;
 set aircon level3&lt;br /&gt;
&lt;br /&gt;
===== Beispiel nach Vergleichsliste =====&lt;br /&gt;
&lt;br /&gt;
Hier kommt eine weitere Liste ins Spiel. Die sogenannte Keywordlist ist im Eigentlichen eine RegExp &amp;quot;Ver-oder-ung&amp;quot;.&lt;br /&gt;
 ( key1 | key2 | ... | keyn )&lt;br /&gt;
oder&lt;br /&gt;
 ( @keywordlist )&lt;br /&gt;
Diese Liste mit Schlüsselwörtern wird im &amp;lt;regex&amp;gt;-Teil angegeben. Hier entscheidet nicht eine Zahl über die Position, sondern die Position die in der Keywordlist einen Treffer hat wird an selber Position in der Modwordlist ausgewählt. Im Attribut T2F_keywordlist können vordefinierte Listen angelegt werden und mit @keylist ausgewählt werden&lt;br /&gt;
&lt;br /&gt;
 blendet.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(Wohnzimmer|Esszimmer|Küche)&amp;lt;/span&amp;gt; = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;[act_lvgroom, act_dinroom, act_kitchen] 70&lt;br /&gt;
               &amp;lt;span style=&#039;color:gray&#039;&amp;gt;|__________|_______|___________________|_____________|____________|&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;.*&#039;&#039; beliebig viele Zeichen&lt;br /&gt;
&lt;br /&gt;
Die Sätze: &lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 ich sitze geblendet im Wohnzimmer&lt;br /&gt;
 die sonne blendet in der Küche&lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set act_dinroom 70&lt;br /&gt;
 set act_lvgroom 70&lt;br /&gt;
 set act_kitchen 70&lt;br /&gt;
&lt;br /&gt;
===== Ergänzung =====&lt;br /&gt;
Ähnlich wie in Variante 1, könne  auch hier auf die Schlüsselwörte &lt;br /&gt;
 empty für leere Zeichenkette &lt;br /&gt;
und &lt;br /&gt;
 else für alle anderen Fälle&lt;br /&gt;
zugegriffen werden. Hierbei wird der Modwordlist einfach empty oder else gefolgt von dem gewünschten Wert als nächstes Element angehängt.&lt;br /&gt;
 $n[ wert1, wert2,,,, empty, wert3, else, wert4 ]&lt;br /&gt;
&lt;br /&gt;
=== erweiterte Befehlskonfiguration ===&lt;br /&gt;
Um Talk2Fhem in den Konfigurationszeilen weitere Parameter zu übergeben, ist eine gesonderte Syntax zu verwenden.&lt;br /&gt;
 &amp;lt;regexp&amp;gt; = ( option =&amp;gt; &#039;value&#039;  ,&lt;br /&gt;
              opt2   =&amp;gt; &#039;value2&#039; ,&lt;br /&gt;
              ... &lt;br /&gt;
              optn   =&amp;gt; &#039;valuen&#039; ) &lt;br /&gt;
Es stehen folgende Optionen zur Verfügung:&lt;br /&gt;
*cmd    =&amp;gt; enthält das FHEM Kommando.  Wie oben beschrieben.&lt;br /&gt;
*answer  =&amp;gt;  Ein in Anführungszeichen (&amp;quot; oder &#039;) gesetzter Perl-Befehl, dessen Rückgabe in das Reading &#039;&#039;answer&#039;&#039; geschrieben wird.&lt;br /&gt;
* offset =&amp;gt;  Ganzzahliger Wert in Sekunden der dem Zeitpunkt addiert wird. Siehe [[Modul_Talk2Fhem#Zeitenmodifikation]]&lt;br /&gt;
&lt;br /&gt;
=== Antworten ===&lt;br /&gt;
In Talk2Fhem können Antworten, die das Modul ausgeben soll, definiert werden. Hier können Fragen verarbeitet werden oder auch den Erfolg eines Kommandos bestätigt werden.&lt;br /&gt;
&lt;br /&gt;
Über die [[Modul_Talk2Fhem#erweiterte_Befehlskonfiguration]], erhält der Parameter &amp;quot;answer&amp;quot; einen Perl Befehl, dessen Rückgabe die Antwort darstellt.&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Erfolgsmeldung ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;tu was = ( cmd =&amp;gt; &amp;quot;set tue es&amp;quot; , answer =&amp;gt; &#039;&amp;quot;Erledigt&amp;quot;&#039; )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Man beachte hier, dass die Parameter immer in Anführungszeichen gesetzt werden müssen. In diesem Fall der Perl Befehl. Ein Text in Perl wird ebenfalls in Anführungszeichen gesetzt, deswegen die doppelten Anführungszeichen!&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Zustandsabfrage ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;wurde es getan = ( answer =&amp;gt; &#039;Value(&amp;quot;tue&amp;quot;) eq &amp;quot;es&amp;quot; ? &amp;quot;Ja&amp;quot; : &amp;quot;Nein&amp;quot;&#039;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Temperaturabfragen ====&lt;br /&gt;
Eine einfache Temperaturabfrage könnte so aussehen.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;wie.*(kalt|warm|grad|temperatur) = ( answer =&amp;gt; &#039;&amp;quot;Die Temperatur beträgt &amp;quot;.ReadingsVal(&amp;quot;tempdev&amp;quot;, &amp;quot;temperature&amp;quot;, &amp;quot;Fehler&amp;quot;)&#039; )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Für eine Raumbezogene Temperaturabfrage, siehe [[Modul_Talk2Fhem#Anwendungsbeispiele_und_Vorlagen]]&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Folgende Attribute werden zur Zeit unterstützt&lt;br /&gt;
=== T2F_keywordlist ===&lt;br /&gt;
 &amp;lt;Name&amp;gt; = &amp;lt;kommaseparierte Liste mit RegExp&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Beispiele&#039;&#039;&#039;&lt;br /&gt;
 rooms = haus|überall|wohnung , wohnzimmer , bad\S* , toilette|wc , büro , ...&lt;br /&gt;
 names = Mama , Papa , Kevin , Jacqueline&lt;br /&gt;
 channels = ard|das erste , zdf , rtl , sat 1 , vox , rtl2 , prosieben , kabel eins , arte&lt;br /&gt;
Man beachte hier die möglichkeit der RegExp&amp;lt;br&amp;gt;&lt;br /&gt;
Das Schlüsselwort &#039;&#039;&#039;haus&#039;&#039;&#039; löst das selbe aus wie &#039;&#039;&#039;überall&#039;&#039;&#039; und &#039;&#039;&#039;wohnung&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;Genauso &#039;&#039;&#039;bad&#039;&#039;&#039; oder &#039;&#039;&#039;badezimmer&#039;&#039;&#039; oder &#039;&#039;&#039;badeirgendewas&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== T2F_modwordlist ===&lt;br /&gt;
 &amp;lt;Name&amp;gt; = &amp;lt;kommaseparierte Liste mir RegExp&amp;gt;&lt;br /&gt;
Die Positionen der gewählten Geräte, ist eine Zuordnung zu den Listen in&#039;&#039;T2F_keywordlist&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;Wenn Wohnzimmer in der keywordliste &amp;lt;rooms&amp;gt; an Position 2 steht muss der Rolladenaktor in der modworliste &amp;lt;roll&amp;gt; auch an Position 2 stehen.&lt;br /&gt;
 roll = rollos_alle , d_rollo_wz , hm_roll_bad.* , hm_roll_wc , hm_roll_buero.* , ...&lt;br /&gt;
 lights = alle_lichte , &#039;&#039;&#039;&amp;quot;sw_wz1,sw_wz2&amp;quot;&#039;&#039;&#039; , sw_bad.* , sw_wc&lt;br /&gt;
Sollen einem Schlüsselwort mehrere Aktoren zugeordnet werden, geht das über sogenannte &amp;quot;Quotes&amp;quot;. (Anführungszeichen) Siehe &amp;lt;lights&amp;gt;.&lt;br /&gt;
 &amp;quot;a,b&amp;quot;  oder  &#039;a,b&#039;  oder  a\,b&lt;br /&gt;
&lt;br /&gt;
=== T2F_disableumlautescaping ===&lt;br /&gt;
&lt;br /&gt;
Deaktiviert das Konvertieren der Umlaute innnerhalb von regulären Ausdrücken in &#039;&#039;&#039;\S\S?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== T2F_language ===&lt;br /&gt;
&lt;br /&gt;
Legt die verwendete Sprache fest. Alternativ wird das Globale Attribut &#039;&#039;language&#039;&#039; verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== disable ===&lt;br /&gt;
Deaktiviert das Ausführen des FHEM Kommandos&lt;br /&gt;
=== verbose ===&lt;br /&gt;
&lt;br /&gt;
== Anwendungsbeispiele und Vorlagen ==&lt;br /&gt;
Hier folgen diverse Vorlagen und Beispiele die jeweils an die eigenen Bedürfnisse angepassst werden sollten/müssen. Hierzu sind die entsprechenden Stellen &amp;lt;span style=&#039;color:red&#039;&amp;gt;rot&amp;lt;/span&amp;gt; markiert.&lt;br /&gt;
=== Keywordlist ===&lt;br /&gt;
Eine typische Keywordlist wäre eine Auflistung der benötigten Räume&lt;br /&gt;
 rooms = haus|überall|wohnung,wohnzimmer,esszimmer,bad\S*,toilette|wc,&lt;br /&gt;
 büro,schlafzimmer,ankleide|garderobe,kinderzimmer,spielzimmer,&lt;br /&gt;
 flur|gang|diele,garage,garten,terrasse,balkon,&lt;br /&gt;
 eg|erdgescho\S*,og|obergescho\S*,\S*auße\S*( haus)?|vor der tür&lt;br /&gt;
&lt;br /&gt;
=== Einfaches schalten ===&lt;br /&gt;
 licht (\S+) = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;dev_light&amp;lt;/span&amp;gt; $1{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
=== Einfaches schalten mit eigenen Wörtern ===&lt;br /&gt;
Will man neben an/aus einen weiteren Zustand selbst definieren, kann das so geschehen.&lt;br /&gt;
 garage (\S+) = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;dev_gate&amp;lt;/span&amp;gt; $1{ /&amp;lt;span style=&#039;color:red&#039;&amp;gt;kurz&amp;lt;/span&amp;gt;/ =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;open-for-time 5&amp;lt;/span&amp;gt;, true =&amp;gt; open, false =&amp;gt; close }&lt;br /&gt;
&lt;br /&gt;
=== Einfaches schalten mit Räumen ===&lt;br /&gt;
 licht (\S+ ){0,2} (&amp;lt;span style=&#039;color:red&#039;&amp;gt;wohnzimmer|esszimmer|küche|terrasse&amp;lt;/span&amp;gt;) (\S+) = set $2[&amp;lt;span style=&#039;color:red&#039;&amp;gt;light_wz,light_ez,light_kitchen,light_outside&amp;lt;/span&amp;gt;] $3{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
Bei größeren Mengen an Räumen und Geräten bietet sich das anlegen von Keyword- und Modwordlisten an. &lt;br /&gt;
 licht (\S+ ){0,2} (&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;) (\S+) = set $2[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@lights&amp;lt;/span&amp;gt;] $3{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
&lt;br /&gt;
=== Rolladen fahren ===&lt;br /&gt;
Sind die Rollläden innerhalb von FHEM über das Attribut &amp;quot;room&amp;quot; den Räumen mit Klarnamen zugeordnet, lässt sich das ganze am einfachsten konfigurieren.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;1.  nach Devicetyp&#039;&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(\S+) (auf )?(\S+) = {fhem(&#039;set room=&#039;.ucfirst(&#039;$3&#039;).&#039;:FILTER=a:subType=blindActuator &amp;lt;span style=&#039;color:red&#039;&amp;gt;$5&amp;lt;/span&amp;gt;{true=&amp;gt;on, false=&amp;gt;off, integer=&amp;gt;&#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;set_$5&amp;lt;/span&amp;gt;&#039;)}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erklärung&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn das Device vom subTyp &amp;quot;blindActuator&amp;quot; ist (HomeMatic Rolladenactor) und es im Raum $3 ist, wird dieses Device gefahren. Die Funktion ucfirst ist notwendig damit der erste Buchstabe groß geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;2.  nach Devicenamen&#039;&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(\S+) (auf )?(\S+) = {fhem(&#039;set room=&#039;.ucfirst(&#039;$3&#039;).&#039;:FILTER=rollo.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;$5&amp;lt;/span&amp;gt;{true=&amp;gt;on, false=&amp;gt;off, integer=&amp;gt;&#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;set_$5&amp;lt;/span&amp;gt;&#039;)}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erklärung&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Gleiche wie oben, nur das alle Devices die mit rollo beginnen im Raum $3 gefahren werden. (rollo.*)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;3.  nach Benutzerdefinierten Räumen&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Ansonsten müssen wir dem Modul sagen in welchem Raum welches Device sitzt. Das hat dafür den Vorteil das die Räume als RegExp angegeben werden können.&amp;lt;br&amp;gt;Wir erzeugen eine Modwordlist &#039;&#039;rollos&#039;&#039; in der wir alle Rollladen &amp;quot;Devices&amp;quot; auflisten. Die Reihenfolge ist an der Keywordlist &amp;quot;rooms&amp;quot; ([[Modul_Talk2Fhem#Keywordlist]]) anzupassen.&lt;br /&gt;
 rollos = &amp;lt;span style=&#039;color:red&#039;&amp;gt;r_alle&amp;lt;/span&amp;gt;,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_wz&amp;lt;/span&amp;gt;,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_ez&amp;lt;/span&amp;gt;,,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_buero&amp;lt;/span&amp;gt;,...&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;)? (auf )?(\S+) = set $3[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rollos&amp;lt;/span&amp;gt;, empty, &amp;lt;span style=&#039;color:red&#039;&amp;gt;rollos_alle&amp;lt;/span&amp;gt;] $5{true=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt;, integer=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;&amp;quot;set_$5&amp;quot;&amp;lt;/span&amp;gt;}&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 Rollos auf&lt;br /&gt;
 Rolllos Überall schließen &lt;br /&gt;
 Rollo im Wohnzimmer hoch&lt;br /&gt;
 Rolladen im Esszimmer runter&lt;br /&gt;
 Rollläden in der Küche auf 50&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Damit wäre eigentlich schon alles abgedeckt. Folgendes Beispiel ist aber auch noch nützlich.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
  (blendet|schatte\S?) ?(\S+ ){0,2}(&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;) = set $3[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rollos&amp;lt;/span&amp;gt;] &amp;lt;span style=&#039;color:red&#039;&amp;gt;set_70&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 ich werde geblendet in der Küche&lt;br /&gt;
 die Sonne blendet mich im Badezimmer&lt;br /&gt;
 beschatte das Haus&lt;br /&gt;
 mach schatten im Erdgeschoss&lt;br /&gt;
&lt;br /&gt;
=== GoogleCast Befehle ===&lt;br /&gt;
Etwas bessere Lautstärkebefehle als die von Google.&lt;br /&gt;
Die Lautstärken müssten noch dem eigenen Geschmack angepasst werden&lt;br /&gt;
 #GoogleCast Commandos&lt;br /&gt;
 leise$            =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 14&lt;br /&gt;
 normale lautstärke =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 20&lt;br /&gt;
 laut$             =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 30&lt;br /&gt;
 (ein wenig|etwas|viel)? ?(lauter|leiser)  =  { fhem(&amp;quot;set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume &amp;quot;.(ReadingsVal(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;volume&amp;quot;, 0)$2[+,-]$1[3,5,10,empty,7])) }&lt;br /&gt;
&#039;&#039;&#039; Beispielsätze &#039;&#039;&#039;&lt;br /&gt;
 Mach leise&lt;br /&gt;
 Mach lauter&lt;br /&gt;
 Mach etwas leiser&lt;br /&gt;
 Mach viel lauter&lt;br /&gt;
&lt;br /&gt;
=== Talk Timer zurücksetzen ===&lt;br /&gt;
Sollen alle von Talk2Fhem angelegten Timer gelöscht werden.&lt;br /&gt;
 (timer|kommandos) (löschen|zurücksetzen) = delete at_&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;.*&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 bitte alle timer zurücksetzen&lt;br /&gt;
 zukünftige kommandos löschen&lt;br /&gt;
&lt;br /&gt;
=== Frage Antwort ===&lt;br /&gt;
==== Raumbezogene Temperaturansage ====&lt;br /&gt;
Wir erzeugen wieder unsere Modwordlist sagen wir @sens gefüllt mit den Temperaturfühler &amp;quot;Devices&amp;quot;. Reihenfolge wie immer die der Keywordlist @rooms.&lt;br /&gt;
 wie.*(kalt|warm|grad|temperatur).*(&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;@rooms&amp;lt;/span&amp;gt;) = ( answer =&amp;gt; &#039;&amp;quot;Die Temperatur beträgt &amp;quot;.ReadingsVal(&amp;quot;$2[&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;@sens&amp;lt;/span&amp;gt;]&amp;quot;, &amp;quot;&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;temperature&amp;lt;/span&amp;gt;&amp;quot;, &amp;quot;unbekannt&amp;quot;).&amp;quot; grad&amp;quot;&#039; )&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 wie warm ist es im Wohnzimmer&lt;br /&gt;
 wie ist die Temperatur in der Küche&lt;br /&gt;
 wie kalt ist es draußen&lt;br /&gt;
&lt;br /&gt;
==== Multiple Antworten ====&lt;br /&gt;
 Hallo Haus = ( answer =&amp;gt; &#039;[&amp;quot;Hallo auch!&amp;quot;,&amp;quot;Guten Tag!&amp;quot;,&amp;quot;Ahoi!&amp;quot;]-&amp;gt;[rand(&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt;)]&#039; ) &lt;br /&gt;
Wählt zufällig eine der drei Aussagen.&lt;br /&gt;
&lt;br /&gt;
==== Ausgabe eines oder mehrerer Zustände ====&lt;br /&gt;
Angenommen man möchte wissen ob das Haus abgeschlossen ist. Und in FHEM existiert ein Dummy der diesen Zustand wiederspiegelt und im Reading text die offenen Fenster und Türen aufgelistet sind. Kann man folgendermaßen den Status erfragen&lt;br /&gt;
 (alles|das haus) (zu|abgeschlossen) = (&lt;br /&gt;
   answer =&amp;gt; &#039;(Value(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;d_schliessung&amp;lt;/span&amp;gt;&amp;quot;) eq &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;zu&amp;lt;/span&amp;gt;&amp;quot;) &lt;br /&gt;
   ? &amp;quot;Es ist alles zu&amp;quot; &lt;br /&gt;
   : &amp;quot;Nein, offen sind: &amp;quot;.ReadingsVal(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;d_schliessung&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;text&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;&amp;quot;)&#039;&lt;br /&gt;
&lt;br /&gt;
==== Zustandsabfrage anhand des Aliasnamen ====&lt;br /&gt;
Möchte man alle Geräte anhand seines Attribut &amp;quot;alias&amp;quot; ansprechen, um dessen Status zu erfragen, könnte das so erfolgen.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039; &lt;br /&gt;
 (zustand|status) (\S+)* (\S+) = (answer=&amp;gt;&#039;my $s=Value((grep { &amp;quot;$3&amp;quot; =~ /$attr{$_}{&amp;lt;span style=&#039;color:red&#039;&amp;gt;alias&amp;lt;/span&amp;gt;}/i } (keys %attr))[0]);; &amp;quot;Der Status ist &amp;quot;.$s if $s&#039;)&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 Wie ist der Zustand der Lüftung&lt;br /&gt;
 sag mir den Status der Haustür&lt;br /&gt;
Es ist auch möglich ein eigenes Attribut zu kreieren, und dieses als Klarnamenattribut zu verwenden. Hierzu einfach im Device global ein userattr hinzufügen. z.B.&lt;br /&gt;
 attr global userattr T2F_alias&lt;br /&gt;
Jetzt stehen in allen Devices das Attribut T2F_alias zur Verfügung. Vorteil ist das dann auch wieder RegExp verwendet werden können. Im oberen Beispiel müsste dann dass rot markierte &amp;quot;alias&amp;quot; durch &amp;quot;T2F_alias&amp;quot; ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration innerhalb der Geräte ===&lt;br /&gt;
Neben der Identifikation der Geräte über die vorhandenen FHEM-Attribute (z.B. room, alias, ...) kann eine alternative Konfiguration auch über eigens für Talk2Fhem angelegte Attribute erfolgen. Die hierfür notwendigen Grundlagen und einige Beispiele sollen im Folgenden beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Grundlagen / Voraussetzungen ====&lt;br /&gt;
1. Anlegen der notwendigen userattr am global-Device:&lt;br /&gt;
&lt;br /&gt;
Erweiterung des Attributes userattr des Gerätes global um folgende Einträge:&lt;br /&gt;
  T2F_places:textField-long T2F_properties:textField-long T2F_rooms:textField-long T2F_types_color:textField-long T2F_types_heating:textField-long T2F_types_info:textField-long T2F_types_switch:textField-long&lt;br /&gt;
&lt;br /&gt;
2. Optional: Hilfsfunktionen für das automatische Füllen der T2F_keywordlist im talk-Device bei Änderung eines T2F-Attributes eines Gerätes&lt;br /&gt;
&lt;br /&gt;
2a. erstellen einer sub in der 99_myUtils.pm:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;  sub fill_T2F_keywordlist&lt;br /&gt;
  {&lt;br /&gt;
    my ($name, $t2f_device) = @_;&lt;br /&gt;
    $name =~ s/T2F_//g;&lt;br /&gt;
    if ($name eq &#039;userattr&#039;)&lt;br /&gt;
    {&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    Log 0, &amp;quot;List: &amp;quot;.$name;&lt;br /&gt;
    my $currentAttr = AttrVal($t2f_device,&amp;quot;T2F_keywordlist&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    my @currentAttrParts = split(/$name = /, $currentAttr);&lt;br /&gt;
    my $currentAttrBeg = @currentAttrParts[0];&lt;br /&gt;
    $currentAttrBeg = substr($currentAttrBeg, 0, -1);&lt;br /&gt;
    my @currentAttrEnd = split(/\n/, @currentAttrParts[1], 2);&lt;br /&gt;
    my @array = devspec2array(&#039;a:T2F_&#039;.$name.&#039;=.+&#039;);&lt;br /&gt;
    my @attributes = ();&lt;br /&gt;
    if (@array &amp;gt; 0 and defined($defs{$array[0]}))&lt;br /&gt;
    {&lt;br /&gt;
      foreach (@array){&lt;br /&gt;
      my @attrVals = split(/\n/,AttrVal($_, &#039;T2F_&#039;.$name, &#039;&#039;));&lt;br /&gt;
      foreach (@attrVals){&lt;br /&gt;
          my $attrVal = $_;&lt;br /&gt;
          $attrVal =~ s/  / /g;&lt;br /&gt;
          $attrVal =~ s/ =&amp;gt; /=&amp;gt;/g;&lt;br /&gt;
          my @attrValParts = split(/=&amp;gt;/,$attrVal);&lt;br /&gt;
          $attrVal = @attrValParts[0];&lt;br /&gt;
          $attrVal =~ s/!//g;&lt;br /&gt;
          $attrVal =~ s/, /,/g;&lt;br /&gt;
          my @attr = split(/,/, $attrVal);&lt;br /&gt;
          push(@attributes, @attr);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    my %hash   = map { $_ =&amp;gt; 1 } @attributes;&lt;br /&gt;
    my @unique = keys %hash;&lt;br /&gt;
    my $result = $currentAttrBeg.&amp;quot;\n&amp;quot;.$name.&amp;quot; = &amp;quot;.join(&amp;quot;, &amp;quot;, @unique).&amp;quot;\n&amp;quot;.@currentAttrEnd[1];&lt;br /&gt;
    $result =~ s/\n\n/\n/g;&lt;br /&gt;
    $result =~ s/  / /g;&lt;br /&gt;
    fhem(&#039;attr &#039;.$t2f_device.&#039; T2F_keywordlist &#039;.$result);&lt;br /&gt;
  }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2b. Erstellen eines DOIFs zum Aufruf der sub:&lt;br /&gt;
&lt;br /&gt;
  defmod talk.DI.fillAttr DOIF ([global:&amp;quot;^ATTR.*T2F_.*&amp;quot;]) ({my $val = ReadingsVal(&amp;quot;$SELF&amp;quot;, &amp;quot;e_global_events&amp;quot;, &amp;quot;&amp;quot;); $val =~ m/(\S*) (\S*) (\S*) (.*)/; if ($2 ne &#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;&#039; &amp;amp;&amp;amp; $2 ne &#039;global&#039;) { fill_T2F_keywordlist(&amp;quot;$3&amp;quot;, &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;&amp;quot;);}})&lt;br /&gt;
  attr talk.DI.fillAttr do always&lt;br /&gt;
&lt;br /&gt;
3. Optional: Erlauben von Umlauten in den T2F-Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_disableumlautescaping 1  &lt;br /&gt;
  &lt;br /&gt;
Nun können die T2F-Attribute pro FHEM-Device definiert und dann in den Talk2Fhem-Befehlen benutzt werden. Wurde der Punkt 2 abgearbeitet, so werden mit dem Füllen der Attribute am Geräte auch die Keywordlisten am talk-Device gefüllt. Wie diese dann verwendet werden können, sollen die folgenden Beispiele zeigen.&lt;br /&gt;
&lt;br /&gt;
==== Schalten von Geräten ====&lt;br /&gt;
&lt;br /&gt;
Ausgangssituation: Es gibt drei Lampen Lampe1, Lampe2, Lampe3 und ein Nachtlicht mit einer Eule mit folgenden Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr Lampe1 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe1 T2F_rooms Haus, Obergeschoss, !Esszimmer&lt;br /&gt;
  attr Lampe1 T2F_places Decke, Tür&lt;br /&gt;
  attr Lampe1 T2F_properties hell,!&lt;br /&gt;
&lt;br /&gt;
  attr Lampe2 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe2 T2F_rooms Haus, Obergeschoss, !Esszimmer&lt;br /&gt;
  attr Lampe2 T2F_places Tisch, Esstisch&lt;br /&gt;
  attr Lampe2 T2F_properties dunkel,schwach,!&lt;br /&gt;
&lt;br /&gt;
  attr Lampe3 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe3 T2F_rooms Haus, Obergeschoss, !Küche&lt;br /&gt;
  attr Lampe3 T2F_places Besenschrank&lt;br /&gt;
  &lt;br /&gt;
  attr Nachtlicht T2F_types_switch Lampe, !Licht, Eule, Nachtlicht&lt;br /&gt;
  attr Nachtlicht T2F_rooms Haus, Obergeschoss, !Kinderschlafzimmer&lt;br /&gt;
  attr Nachtlicht T2F_places Steckdose&lt;br /&gt;
&lt;br /&gt;
Durch die in Punkt 2 der Voraussetzungen genannten Funktionen wurden folgende T2F-keywordlisten automatisch angelegt:&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_keywordlist rooms = Kinderschlafzimmer, Haus, Küche, Obergeschoss, Esszimmer &lt;br /&gt;
                            places = Tür, Steckdose, Tisch, Decke, Esstisch&lt;br /&gt;
                            properties = hell, dunkel, schwach&lt;br /&gt;
                            types_switch = Lampe, Licht, Eule&lt;br /&gt;
&lt;br /&gt;
Die Definition für das T2F-Device lautet dann wie folgt:&lt;br /&gt;
&lt;br /&gt;
  #   1              2                 3                4            5          6          7      &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; ?(@properties) &amp;amp;&amp;amp; (@types_switch) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) &amp;amp;&amp;amp; (\S+)(schalten|machen)?$ =&lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_switch=.*$3@.*:FILTER=T2F_rooms=.*$4@.*:FILTER=T2F_properties=.*$2@.*:FILTER=T2F_places=.*$5@.* $6{true=&amp;gt;on, false=&amp;gt;off}&#039;,&lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;$AGAIN&amp;quot; ? &amp;quot;dann $DATE wieder $6{true=&amp;gt;ein, false=&amp;gt;aus}&amp;quot; : &amp;quot;$1{/bitte/=&amp;gt;Gern, else=&amp;gt;Das heißt Bitte}, ich schalte $1{/bitte/=&amp;gt;, else=&amp;gt;trotzdem} folgende Geräte $6{true=&amp;gt;ein, false=&amp;gt;aus}: &amp;quot;.T2F_answer(&amp;quot;T2F_types_switch=.*$3@.*:FILTER=T2F_rooms=.*$4@.*:FILTER=T2F_properties=.*$2@.*:FILTER=T2F_places=.*$5@.*&amp;quot;,&amp;quot;T2F_types_switch&amp;quot;)&#039;)&lt;br /&gt;
                            &lt;br /&gt;
Damit sind dann die folgenden Sprachbefehle möglich:&lt;br /&gt;
&lt;br /&gt;
  Schalte das Licht in der Küche ein                      =&amp;gt; schaltet Lampe3 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte die helle Lampe im Esszimmer an                 =&amp;gt; schaltet Lampe1 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht im Esszimmer über dem Esstisch ein    =&amp;gt; schaltet Lampe2 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte die Eule ein                                    =&amp;gt; schaltet Nachtlicht ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht im Esszimmer aus}                     =&amp;gt; schaltet Lampe1 und Lampe2 aus&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht aus                                   =&amp;gt; schaltet alle vier Lichter aus&lt;br /&gt;
&lt;br /&gt;
Um in der Antwort die Liste der geschalteten Geräte genannt zu bekommen, wird die sub T2F_answer aus der 99_myUtils aufgerufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;  sub T2F_answer&lt;br /&gt;
  {&lt;br /&gt;
    my ($filter, $type) = @_;&lt;br /&gt;
    my $answer;&lt;br /&gt;
    my @devices = devspec2array($filter);&lt;br /&gt;
    if (@devices &amp;gt; 0 and defined($defs{$devices[0]}))&lt;br /&gt;
    {&lt;br /&gt;
      #$answer = &amp;quot;Ich habe folgende Geräte &amp;quot;.$command.&amp;quot;: &amp;quot;;&lt;br /&gt;
      foreach (@devices){&lt;br /&gt;
        $answer = $answer.&amp;quot;\n&amp;quot;;&lt;br /&gt;
        my $devAttr = AttrVal($_, $type, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        $devAttr = AttrVal($_, &#039;T2F_properties&#039;, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        $devAttr = AttrVal($_, &#039;T2F_rooms&#039;, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        $devAttr = AttrVal($_, &#039;T2F_places&#039;, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    return $answer.&amp;quot;\n&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Benennung der Geräte erfolgt auf Basis derer T2F-Attribute: Typ, Eigenschaft, Raum, Ort. Ist das jeweilige Attribut leer, ist es auch in der Antwort leer. Enthält die jeweilige Attributliste ein Ausrufezeichen (!), so wird der Eintrag nach dem Ausrufezeichen für die Antwort verwendet (z.B. Esszimmer als Raum). Steht das Ausrufezeichen am Ende, so wird der Eintrag in der Antwort leer gelassen (z.B. die Eigenschaft bei Lampe1). Ist kein Ausrufezeichen vorhanden, so wird der erste Eintrag verwendet.&lt;br /&gt;
&lt;br /&gt;
==== Einstellen der Heizung ====&lt;br /&gt;
&lt;br /&gt;
Das gleiche Prinzp wie bei den Lampen kann auch für die Einstellung der Heizung verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Ausgangssituation: In der Küche, im Kinderschlafzimmer und im Esszimmer gibt es jeweils eine Heizung (Homematic HM-CC-RT-DN) mit folgenden Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr HeizungEsszimmer T2F_places Heizung,!&lt;br /&gt;
  attr HeizungEsszimmer T2F_rooms Haus,Obergeschoss,Essbereich,!Esszimmer&lt;br /&gt;
  attr HeizungEsszimmer T2F_types_heating Heizung,Temperatur,Esszimmer,Essbereich,!&lt;br /&gt;
&lt;br /&gt;
  attr HeizungKüche T2F_places Heizung,!&lt;br /&gt;
  attr HeizungKüche T2F_rooms Haus,Obergeschoss,Essbereich,!Küche&lt;br /&gt;
  attr HeizungKüche T2F_types_heating Heizung,Temperatur,Küche,Essbereich,!&lt;br /&gt;
&lt;br /&gt;
  attr HeizungKiSchla T2F_places Heizung,!&lt;br /&gt;
  attr HeizungKiSchla T2F_rooms Haus,Obergeschoss,!Kinderschlafzimmer&lt;br /&gt;
  attr HeizungKiSchla T2F_types_heating Heizung,Temperatur,Kinderschlafzimmer,!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mit der T2F-Definition&lt;br /&gt;
&lt;br /&gt;
  #   1             2                  3        4      5                  &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; (@types_heating) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; (auf (\d+) grad|auto\S*)( stellen| setzen| einstellen| ein)?$ = &lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.* $5{integer=&amp;gt;desired-temp $5, else=&amp;gt;controlMode auto}&#039;,&lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;$AGAIN&amp;quot; ? &amp;quot;dann $DATE wieder auf Automatik&amp;quot; : &amp;quot;Die Durchschnittstemperatur beträgt dort zur Zeit &amp;quot;.averageTemp(&amp;quot;T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.*&amp;quot;).&amp;quot; Grad\n$1{/bitte/=&amp;gt;Gern, else=&amp;gt;Das heißt Bitte}, ich stelle die Heizung in folgenden Räumen auf $5{integer=&amp;gt;$5 Grad, else=&amp;gt;Automatik}: &amp;quot;.T2F_answer(&amp;quot;T2F_types_heating=.*$2{empty=&amp;gt;.+, else=&amp;gt;$2@}.*:FILTER=T2F_rooms=.*$3@.*&amp;quot;,&amp;quot;T2F_types_heating&amp;quot;)&#039;)&lt;br /&gt;
  &lt;br /&gt;
funktionieren folgende Sprachbefehle:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Esszimmer auf 21 Grad        =&amp;gt; Stellt die Heizung im Esszimmer auf 21 Grad&lt;br /&gt;
  &lt;br /&gt;
  Bitte stell die Heizung im Essbereich auf 21 Grad       =&amp;gt; Stellt die Heizungen im Esszimmer und in der Küche auf 21 Grad&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Obergeschoss auf Automatik   =&amp;gt; Stellt die drei Heizungen auf Automatik&lt;br /&gt;
  &lt;br /&gt;
Dadurch, dass im Attribut T2F_types_heating auch die Räume aufgeführt sind, sind auch Befehle in folgender Form möglich:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Küche auf 21 Grad                       =&amp;gt; Stellt die Heizung in der Küche auf 21 Grad&lt;br /&gt;
&lt;br /&gt;
Auch kann in diesem (wie auch in den oben aufgeführten Schaltbefehlen) mit &amp;quot;wieder&amp;quot; gearbeitet werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte stell die Heizung im Essbereich auf 21 Grad und in 2 Stunden wieder auf Automatik&lt;br /&gt;
  &lt;br /&gt;
Für die Generierung der Antwort wird neben der bei den Schaltbefehlen bereits gezeigten sub T2F_answer eine weiter Funktion verwende, welche die Durchschnittstemperatur im zu schaltenden Bereich ermittelt und ausgibt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
  sub averageTemp($)&lt;br /&gt;
  {&lt;br /&gt;
    my ($filter) = @_;&lt;br /&gt;
    my @tempDevices = devspec2array($filter);&lt;br /&gt;
    my $count = 0;&lt;br /&gt;
    my $measuredTemp = 0;&lt;br /&gt;
    if (@tempDevices &amp;gt; 0 and defined($defs{$tempDevices[0]})){&lt;br /&gt;
      foreach (@tempDevices){&lt;br /&gt;
        $measuredTemp = $measuredTemp + ReadingsVal($_, &amp;quot;measured-temp&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        $count = $count + 1;&lt;br /&gt;
      }&lt;br /&gt;
      return $measuredTemp / $count;&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
==== Einstellen der Farbe von Farbwechsellampen (Philips Hue, Wifilight, ...) ====&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel zum Einstellen der Lichtfarbe nehmen wir eine Farbwechsellampe LampeBunt an, welche den Befehl RGB unterstützt. Diese erhält folgende Attribute:&lt;br /&gt;
&lt;br /&gt;
  attr LampeBunt T2F_places Decke,Couch,Sofa&lt;br /&gt;
  attr LampeBunt T2F_rooms Haus,Dachgeschoss,!Wohnzimmer&lt;br /&gt;
  attr LampeBunt T2F_types_color Lampe,Licht&lt;br /&gt;
  attr LampeBunt T2F_types_switch Lampe,Licht&lt;br /&gt;
  &lt;br /&gt;
Durch das Attribut T2F_types_switch lässt sich diese über die bereits beschriebene Schaltlogik ein und ausschalten. Durch die zusätzlich T2F-Definition&lt;br /&gt;
&lt;br /&gt;
  #   1              2               3             4              5               6 &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; (@types_color) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) &amp;amp;&amp;amp; auf (@colors)( schalten| stellen)?$ = &lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_color=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_places=.*$4@.* RGB $5[@rgb]&#039;, &lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;Ich schalte folgende Geräte auf $5@: &amp;quot;.T2F_answer(&amp;quot;T2F_types_color=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_places=.*$4@.*&amp;quot;,&amp;quot;T2F_types_color&amp;quot;)&#039;)&lt;br /&gt;
&lt;br /&gt;
und die entsprechenden Attribute am T2F-Device talk (HINWEIS: eigene Listen können Problemlos ergänzt werden, diese werden durch die Hilfsfunktionen NICHT überschrieben)&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_keywordlist colors = Aus, Schwarz, Dunkles Schiefergrau, Schiefergrau, Helles Schiefergrau, Helles Stahlblau, Mattes Grau, Grau, Dunkelgrau, Silber, Hellgrau, Gainsboro, Rauchiges Weiß, Geisterweiß, Weiß, Schneeweiß, Elfenbein, Blütenweiß, Muschel, Altgold, Leinenfarbe, Antikes Weiß, Mandelweiß, Cremiges Papaya, Beige, Mais, Helles Goldrutengelb, Hellgelb, Chiffongelb, Blasse Goldrutenfarbe, Khaki, Gelb, Gold, Orange, Dunkles Orange, Goldrute, dunkle Goldrutenfarbe, Peru, Schokolade, Sattelbraun, Ocker, Braun, Dunkelrot, Kastanienbraun, Ziegelfarbe, Indischrot, Karmesinrot, Rot, Orangenrot, Tomatenrot, Koralle, Lachs, Helles Korallenrot, Dunkle Lachsfarbe, Helle Lachsfarbe, Sandbraun, Rosiges Braun, Gelbbraun, Grobes Braun, Weizen, Pfirsich, Navajoweiß, Tomatencreme, Rosige Lavenderfarbe, Altrosa, Rosa, Hellrosa, Leuchtendes Rosa, Fuchsie, Magentarot, Tiefrosa, Mittleres Violettrot, Blasses Violettrot, Pflaume, Distel, Lavendelfarbe, Violett, Orchidee, Dunkles Magentarot, Violett, Indigo, Blauviolett, Dunkles Violett, Dunkle Orchideenfarbe, Mittleres Violett, Mittlere Orchideenfarbe, Mittleres Schieferblau, Schieferblau, Dunkles Schieferblau, Mitternachtsblau, Marineblau, Dunkelblau, Mittelblau, Blau, Königsblau, Stahlblau, Kornblumenblau, Dodger-Blau, Tiefes Himmelblau, Helles Himmelblau, Himmelblau, Hellblau, Zyanblau, Blaugrün, Taubenblau, Helles Cyanblau, Aliceblau, Himmelblau, Cremig Pfefferminz, Honigmelone, Aquamarinblau, Türkis, Blasses Türkis, Mittleres Türkis, Dunkles Türkis, Mittleres Aquamarinblau, Helles Seegrün, Dunkles Zyanblau, Entenbraun, Kadettblau, Mittleres Seegrün, Dunkles Seegrün, Hellgrün, Blassgrün, Mittleres Frühlingsgrün, Frühlingsgrün, Zitronengrün, Gelbgrün, Seegrün, Waldgrün, Grün, Dunkelgrün, Olivfarbiges Graubraun, Dunkles Olivgrün, Olivgrün, Dunkles Khaki, Gelbgrün, Hellgrün, Grüngelb&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_modwordlist rgb = 000000, 000000, 8FBC8F, 708090, 778899, B0C4DE, 696969, 808080, A9A9A9, C0C0C0, D3D3D3, DCDCDC, F5F5F5, F8F8FF, FFFFFF, FFFAFA, FFFFF0, FFFAF0, FFF5EE, FDF5E6, FAF0E6, FAEBD7, FFEBCD, FFEFD5, F5F5DC, FFF8DC, FAFAD2, FFFFE0, FFFACD, EEE8AA, F0E68C, FFFF00, FFD700, FFA500, FF8C00, DAA520, B8860B, CD853F, D2691E, 8B4513, A0522D, A52A2A, 8B0000, 800000, B22222, CD5C5C, DC143C, FF0000, FF4500, FF6347, FF7F50, FA8072, F08080, E9967A, FFA07A, F4A460, BC8F8F, D2B48C, DEB887, F5DEB3, FFDAB9, FFDEAD, FFE4C4, FFF0F5, FFE4E1, FFC0CB, FFB6C1, FF69B4, FF00FF, FF00FF, FF1493, C71585, DB7093, DDA0DD, D8BFD8, E6E6FA, EE82EE, DA70D6, 8B008B, 800080, 4B0082, 8A2BE2, 9400D3, 9932CC, 9370DB, BA55D3, 7B68EE, 6A5ACD, 483D8B, 191970, 000080, 00008B, 0000CD, 0000FF, 4169E1, 4682B4, 6495ED, 1E90FF, 00BFFF, 87CEFA, 87CEEB, ADD8E6, 00FFFF, 00FFFF, B0E0E6, E0FFFF, A0CE00, F0FFFF, F5FFFA, F0FFF0, 7FFFD4, 40E0D0, AFEEEE, 48D1CC, 00CED1, 66CDAA, 20B2AA, 008B8B, 008080, 5F9EA0, 3CB371, 8FBC8F, 90EE90, 98FB98, 00FA9A, 00FF7F, 00FF00, 32CD32, 2E8B57, 228B22, 008000, 006400, 6B8E23, 556B2F, 808000, BDB76B, 9ACD32, 7FFF00, ADFF2F&lt;br /&gt;
&lt;br /&gt;
kann die Farbe nun auch über folgenden Sprachbefehle eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte schalte die Lampe im Wohnzimmer an der Couch auf Olivfarbiges Graubraun&lt;br /&gt;
&lt;br /&gt;
Dadurch, das die Liste colors den Wert &amp;quot;Aus&amp;quot; mit dem entsprechenden Wert &amp;quot;000000&amp;quot; in der Liste rgb enthält, kann die Lampe über die gleiche Logik auch ausgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
  Bitte schalte das Licht im Wohnzimmer auf Pflaume und in einer Stunde wieder aus&lt;br /&gt;
  &lt;br /&gt;
==== Abfragen beliebiger Geräteinformationen ====&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt die Möglichkeit auf, die Antworten für Statusabfragen direkt am abgefragten Gerät zu definieren. Hierfür werden zunächst eine Definition am T2F-Device&lt;br /&gt;
&lt;br /&gt;
  #              1             2                3            4&lt;br /&gt;
  Wie &amp;amp;&amp;amp; ?(@properties)&amp;amp;&amp;amp; (@types_info) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) = &lt;br /&gt;
  (answer=&amp;gt;&#039;T2F_getInfo(&amp;quot;T2F_types_info=.*$2@.*:FILTER=T2F_rooms=.*$3@.*:FILTER=T2F_properties=.*$1@.*:FILTER=T2F_places=.*$4@.*&amp;quot;,&amp;quot;$2@&amp;quot;)&#039;)&lt;br /&gt;
  &lt;br /&gt;
und eine Funktion in der 99_myUtils&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
  sub T2F_getInfo&lt;br /&gt;
  {&lt;br /&gt;
    my ($filter,$info) = @_;&lt;br /&gt;
    my @devices = devspec2array($filter);&lt;br /&gt;
    if (@devices &amp;gt; 0 and defined($defs{$devices[0]}))&lt;br /&gt;
    {&lt;br /&gt;
      if (@devices &amp;gt; 1)&lt;br /&gt;
      {&lt;br /&gt;
        return &amp;quot;Ich habe mehr als ein Gerät gefunden, die Information kann nicht abgerufen werden.&amp;quot;;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      my $answer = &amp;quot;Die Abfrage von &amp;quot;.$info.&amp;quot; für &amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      my $devAttr = AttrVal($_, &#039;T2F_properties&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      $devAttr = AttrVal($_, &#039;T2F_rooms&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      $devAttr = AttrVal($_, &#039;T2F_places&#039;, &#039;&#039;);&lt;br /&gt;
      if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
      {&lt;br /&gt;
        my @entries = split(/!/, $devAttr);&lt;br /&gt;
        if (@entries &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[0]);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
          @entries = split(/,/, $entries[1]);&lt;br /&gt;
        }&lt;br /&gt;
        if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
        &lt;br /&gt;
      my @attrVals = split(/\n/,AttrVal(@devices[0], &#039;T2F_types_info&#039;, &#039;&#039;));&lt;br /&gt;
      foreach (@attrVals){&lt;br /&gt;
        my $attrVal = $_;&lt;br /&gt;
        $attrVal =~ s/  / /g;&lt;br /&gt;
        $attrVal =~ s/ =&amp;gt; /=&amp;gt;/g;&lt;br /&gt;
        my @attrValParts = split(/=&amp;gt;/,$attrVal);&lt;br /&gt;
        if (@attrValParts[0] =~ /$info/)&lt;br /&gt;
        {&lt;br /&gt;
          my $cmd = &amp;quot;&#039;&amp;quot;.@attrValParts[1].&amp;quot;&#039;&amp;quot;;&lt;br /&gt;
          $cmd =~ s/ #/ &#039;.ReadingsVal(&#039;@devices[0]&#039;, &#039;/g;&lt;br /&gt;
          $cmd =~ s/#/&#039;, &#039;&#039;).&#039;/g;&lt;br /&gt;
          return eval($cmd);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration und Funktionsweise sind nun wie folgt: Das Gerät, dessen Status abgefragt werden sollen erhält neben den Oben bereits beschriebenen Attributen für Eigenschaft, Raum und Ort noch das Attribut T2F_types_info, welches Zeilenweise die abzufragenen Status in der folgenden Form enthält:&lt;br /&gt;
&lt;br /&gt;
  abfragewert =&amp;gt; Das ist die Antwort mit den Wert #reading#&lt;br /&gt;
  &lt;br /&gt;
Mit der Form #reading# können die Werte von Readings des abgefragten Device zum Zeitpunkt der Abfrage ermittelt werden. Für das Beispiel einer Heizung im Esszimmer wäre das zum Beispiel wie folgt möglich:&lt;br /&gt;
&lt;br /&gt;
  attr HeizungEsszimmer T2F_places Heizung,!&lt;br /&gt;
  attr HeizungEsszimmer T2F_rooms Haus,Obergeschoss,Essbereich,!Esszimmer&lt;br /&gt;
  attr HeizungEsszimmer T2F_types_info warm,Temperatur =&amp;gt; Die Temperatur beträgt #measured-temp# Grad und soll #desired-temp# Grad erreichen\&lt;br /&gt;
                                       Ventilstellung =&amp;gt; Das Ventil ist #ValvePosition# Prozent geöffnet&lt;br /&gt;
&lt;br /&gt;
Damit sind dann folgende Abfragen möglich:&lt;br /&gt;
&lt;br /&gt;
  Wie warm ist die Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
  Wie ist die Temperatur der Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
  Wie ist die Ventilstellung der Heizung im Esszimmer?&lt;br /&gt;
  &lt;br /&gt;
Anders als bei den anderen Beispielen, wo alle gefundenen Geräte geschaltet werden, muss die Abfrage hier so detailliert sein, dass nur ein Gerät gefunden wird.&lt;br /&gt;
&lt;br /&gt;
== Häufig verwendete RegExp ==&lt;br /&gt;
Perl Regular Expression, also ein regulärer Ausdruck der Programmiersprache Perl, ist eine Werkzeug um Zeichenketten zu beschreiben. Hier wird ein kurzer Einblick auf die im Artikel häufig genutzten RegExp zu geben.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung der Syntax kann hier eingesehen werden. [http://jkorpela.fi/perl/regexp.html]&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! RegExp !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| \S* || Beliebig viele (*) nicht Leerzeichen (\S). Für unbekannten und unwichtigen Wortendungen&amp;lt;br&amp;gt;z.b. garage\S* ist bei Garage, Garagentor oder Garagentür erfolgreich&lt;br /&gt;
|-&lt;br /&gt;
| \S+ || Mehr als ein Zeichen (+) welches kein Leerzeichen ist (\S)&lt;br /&gt;
|-&lt;br /&gt;
| \S\S? || Ein oder zwei Zeichen die keine Leerzeichen sind. Das &amp;quot;?&amp;quot; wirkt hier nur auf das angrenzende &amp;quot;\S&amp;quot;.&amp;lt;br&amp;gt;Sollte für Umlaute verwendet werden, da bei manchen Eingabemethoden Probleme mit Umlauten auftreten können.&lt;br /&gt;
|-&lt;br /&gt;
| (wort )?  || Ein bestimmtes Wort oder nicht.&lt;br /&gt;
|-&lt;br /&gt;
| (wort1&amp;amp;#124;wort2) || Entweder wort1 oder Wort2&lt;br /&gt;
|-&lt;br /&gt;
| wort$ || Nur wenn das Wort am ende der Zeichenkette steht.&lt;br /&gt;
|-&lt;br /&gt;
| (\S+){0,2} || Keins, eins oder zwei Wörter. Kann für Artikel wie z.B. &amp;quot;(in der&amp;amp;#124;in dem&amp;amp;#124;im&amp;amp;#124;auf der&amp;amp;#124;...)?&amp;quot; eingesetzt werden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Eingabemethoden ==&lt;br /&gt;
Die Herkunft der Sprachbefehle für das Modul sind vielfältig. Hier werden einige Methoden beschrieben wie der Sprachbefehl in das Modul gelangen kann.&lt;br /&gt;
=== Messenger Telegram ===&lt;br /&gt;
Ist ein [[TelegramBot]] telbot definiert, reicht ein einfaches &amp;quot;notify&amp;quot; um die Nachrichten an FHEM an Talk2Fhem weiterzuleiten.&lt;br /&gt;
 define &amp;lt;span style=&#039;color:red&#039;&amp;gt;n_telbot&amp;lt;/span&amp;gt; notify &amp;lt;span style=&#039;color:red&#039;&amp;gt;telbot&amp;lt;/span&amp;gt;:msgText.* set talk $EVENT&lt;br /&gt;
Schon kann mit FHEM gechattet werden... ;)&lt;br /&gt;
&lt;br /&gt;
=== Google Home Geräte ===&lt;br /&gt;
Momentan ist es leider noch notwendig über einen Umweg die Sprache von einem GoogleHome in FHEM zu bringen. Hierzu ist es notwendig einen funktionierenden DNS Service am laufen zu haben. Damit FHEM per Webadresse im Internet erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
*Ein FHEMWEB Device anlegen&lt;br /&gt;
 define api FHEMWEB 8087 global&lt;br /&gt;
 attr api HTTPS 1&lt;br /&gt;
 attr api allowfrom  1&lt;br /&gt;
 attr api csrfToken  None&lt;br /&gt;
*Ein allowed Device anlegen&lt;br /&gt;
 define allowed_api allowed api&lt;br /&gt;
 attr allowed_api allowedCommands set&lt;br /&gt;
 attr allowed_api allowedDevices talk&lt;br /&gt;
 attr allowed_api basicAuth  {&amp;quot;$user:$password&amp;quot; eq &#039;user:passwort&#039;}&lt;br /&gt;
 attr allowed_api validFor   api&lt;br /&gt;
*Mit Googlekono bei IFTTT.com anmelden&lt;br /&gt;
*New Applet&lt;br /&gt;
*+this GoogleAssistant -&amp;gt; Say a phrase with a text ingredient&lt;br /&gt;
* Die drei Triggertexte wählen z.b.&lt;br /&gt;
**das Haus $&lt;br /&gt;
**sag dem Haus $&lt;br /&gt;
**frag das Haus $&lt;br /&gt;
***Problem bei zu kurzen Texten hat GoogleHome keine anderen Anfragen mehr angenommen.&lt;br /&gt;
*Einen Antworttext überlegen z.B. OK und in &amp;quot;What do you want the Assistant to say in response?&amp;quot; eintragen&lt;br /&gt;
*Language Deutsch&lt;br /&gt;
*+that Webhooks&lt;br /&gt;
*URL wählen&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;https://user:password@dnsservice:54387/fhem?cmd.talk=set talk {{TextField}}&amp;amp;XHR=1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
*Fertig&lt;br /&gt;
&lt;br /&gt;
Jetzt wird der gesamte Text bei dem genannten Triggerworten an FHEM weitergeleitet.&lt;br /&gt;
&lt;br /&gt;
== Ausgabemethoden ==&lt;br /&gt;
&lt;br /&gt;
Siehe hierzu [[Modul_Talk2Fhem#Beispiel|Anwendungsbeispiel]]&lt;/div&gt;</summary>
		<author><name>RoBra81</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=Talk2Fhem&amp;diff=24784</id>
		<title>Talk2Fhem</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=Talk2Fhem&amp;diff=24784"/>
		<updated>2018-01-28T07:54:02Z</updated>

		<summary type="html">&lt;p&gt;RoBra81: Neue Beispiele&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul&lt;br /&gt;
|ModPurpose=Das Modul stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her&lt;br /&gt;
|ModType=h]&lt;br /&gt;
|ModCmdRef=Talk2Fhem&lt;br /&gt;
|ModForumArea=Unterst&amp;amp;uuml;tzende Dienste&lt;br /&gt;
|ModTechName=39_Talk2Fhem.pm&lt;br /&gt;
|ModOwner=Oliver Georgi&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Seite beschreibt die Funktionsweise und Konfiguration des Moduls 39_Talk2Fhem.pm&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen ==&lt;br /&gt;
[[Datei:ModulTalk2FhemScreenshot.png|360px|thumb|right]]&lt;br /&gt;
Es ist sehr zu empfehlen, für die Konfiguration des Moduls, im Webfrontend von FHEM die Syntaxhervorhebung zu aktivieren. Die Aktivierung des erweiterten Editors ist [[Konfiguration#Syntaxhervorhebung|hier]] beschrieben.&lt;br /&gt;
&lt;br /&gt;
Kenntnisse im Bereich Regulärer Ausdrücke (RegExp) in Perl sind hilfreich, aber nicht zwingend erforderlich. Ein kurzer Einstieg kann hier eingesehen werden. [[Modul_Talk2Fhem#Häufig_verwendete_RegExp|Häufig_verwendete_RegExp]]&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
Das Modul Talk2Fhem stellt eine Verbindung zwischen natürlicher Sprache und FHEM Befehlen her. Es ist ein überaus flexibles und relativ einfach zu konfigurierendes Script mit dem man sehr natürlich kommunizieren kann. Die Konfiguration erfolgt dabei über das FHEM Webfrontend. &lt;br /&gt;
&lt;br /&gt;
Bei der Verarbeitung der Sprachbefehle erfolgt keine grammatikalische Analyse, sondern es wird auf definierte Schlüsselwörter reagiert. Das Modul erkennt von sich aus diverse Zeit- und Datumsangaben und löst bei Bedarf zu diesen Zeiten die FHEM Kommandos aus.&lt;br /&gt;
&lt;br /&gt;
=== Funktionsweise ===&lt;br /&gt;
&lt;br /&gt;
Die Zerlegung des Sprachbefehls erfolgt in mehreren Schritten. &lt;br /&gt;
# Aufteilen des Sprachbefehls in einzelne Kommandos anhand des Wortes UND&lt;br /&gt;
# Erkennen von Zeit- und Datumsangaben und entfernen für die weitere Verarbeitung&lt;br /&gt;
# Entfernung unnötiger Wörter&lt;br /&gt;
# Vergleich mit den definierten Schlüsselwörtern&lt;br /&gt;
# Konvertieren in ein FHEM Kommando&lt;br /&gt;
# Zeitgebundenes auslösen des FHEM Kommandos&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Solange das Modul noch nicht offiziell aufgenommen wurde, muss die Datei 39_Talk2Fhem.pm manuell in das Verzeichnis FHEM/ kopiert werden. Siehe Forumsbeitrag. [https://forum.fhem.de/index.php/topic,80960.0.html]&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
 define talk Talk2Fhem&lt;br /&gt;
Zum testen der Konfiguration ist es Ratsam vorerst das Attribut disable auf 1 zu setzen. Hierbei wird die Auslösung der FHEM Kommandos unterdrückt.&lt;br /&gt;
 attr talk disable 1&lt;br /&gt;
&lt;br /&gt;
== Anwendung ==&lt;br /&gt;
Der Sprachbefehl wird über das Kommando &amp;quot;set&amp;quot; an das Modul geleitet.&lt;br /&gt;
 set talk Guten Morgen liebes Zuhause&lt;br /&gt;
&lt;br /&gt;
=== Readings ===&lt;br /&gt;
&lt;br /&gt;
Im Reading &#039;&#039;&#039;set&#039;&#039;&#039; steht der letzte gesendete Sprachbefehl.&lt;br /&gt;
&amp;lt;br&amp;gt;Im Reading &#039;&#039;&#039;cmds&#039;&#039;&#039; steht das letzte ausgeführte FHEM-Kommando dessen Rückgabe in in das Reading &#039;&#039;&#039;fhem&#039;&#039;&#039; geschrieben wird. &lt;br /&gt;
&lt;br /&gt;
Die Antworten und Modulinterne Fehler werden in den Readings &#039;&#039;&#039;answers&#039;&#039;&#039; und &#039;&#039;&#039;err&#039;&#039;&#039; ausgegben. &lt;br /&gt;
&lt;br /&gt;
Das Reading &#039;&#039;&#039;status&#039;&#039;&#039; wird jedes mal gesetzt und erhält Werte nach folgender Priorität.&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|1.||&#039;&#039;&#039;response&#039;&#039;&#039; ||wenn das FHEM Kommando eine Meldung ausgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|2.||&#039;&#039;&#039;disabled&#039;&#039;&#039; ||wenn das Attribute disable auf 1 steht&lt;br /&gt;
|-&lt;br /&gt;
|3.||&#039;&#039;&#039;err&#039;&#039;&#039; ||wenn der Sprachbefehl einen Fehler zurückgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|4.||&#039;&#039;&#039;answer&#039;&#039;&#039; ||wenn der Sprachbefehl eine Antwort ausgegeben hat&lt;br /&gt;
|-&lt;br /&gt;
|5.||&#039;&#039;&#039;done&#039;&#039;&#039; ||wenn keines der oberen Fälle eingetreten ist, also alles gut verlaufen ist&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Beispiel ===&lt;br /&gt;
Die FHEM Befehle werden eigenständig ausgeführt, sie können aber zur Überprüfung auch weitergeleitet werden. Das Beispiel zeigt auch wie auf Fehler und Antworten von Talk2Fhem reragiert werden kann.&lt;br /&gt;
Erstellen eines Notify&lt;br /&gt;
 define n_talk notify talk:.* {}&lt;br /&gt;
Folgendes in der Definition von n_talk einfügen&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 talk:.* {&lt;br /&gt;
 # Sende die Antwort per Telegram und gebe es über das GoogleHome aus&lt;br /&gt;
 	if ($EVENT =~ s/^answers: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telegram _msg \@USER $EVENT&amp;quot;);&lt;br /&gt;
 		fhem(&amp;quot;set d_googlespeak $EVENT&amp;quot;);	&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 # Schicke den Fehler per Telegram und sag am GoogleHome das es nicht geklappt hat.&lt;br /&gt;
 	if ($EVENT =~ s/^err: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telbot _msg \@Oliver $EVENT&amp;quot;);&lt;br /&gt;
 		my @a = (&amp;quot;Das hat leider nicht geklappt&amp;quot;, &amp;quot;Es gab leider einen Fehler&amp;quot;, &amp;quot;Es tut mir leid. Das hat nicht funktioniert.&amp;quot;, &amp;quot;Es ist leider zu einem Fehler gekommen&amp;quot;,&amp;quot;Könntest du das vielleicht nochmal anders sagen&amp;quot;, &amp;quot;Mhhh, das kann ich so nicht verstehen&amp;quot;);&lt;br /&gt;
 		fhem(&amp;quot;set d_googlespeak $a[int(rand($#a))]&amp;quot;);&lt;br /&gt;
 	} &lt;br /&gt;
 &lt;br /&gt;
 # Schick mir alle ausgeführten Befehle als Telegram&lt;br /&gt;
 &lt;br /&gt;
 	if ($EVENT =~ s/^cmds: //) {&lt;br /&gt;
 		fhem(&amp;quot;set telbot _msg \@USER $EVENT&amp;quot;);&lt;br /&gt;
 	} &lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zeitenerkennung ===&lt;br /&gt;
Die Zeit- und Datum Eingabe kann auf viele verschiedene Arten erfolgen.&amp;lt;br&amp;gt;&lt;br /&gt;
Die Datumerkennung umfasst folgende Phrasen:&lt;br /&gt;
*morgen, übermorgen&lt;br /&gt;
*in ... Wochen, Monat, Jahr&lt;br /&gt;
*nächste Woche, Monat, Jahr&lt;br /&gt;
*Wochentage&lt;br /&gt;
*in ... Tagen&lt;br /&gt;
*am DATUM&lt;br /&gt;
&lt;br /&gt;
Die Zeiterkennung umfasst folgende Phrasen:&lt;br /&gt;
*in,nach ... stunden,minuten,sekunden&lt;br /&gt;
*um ... (Uhr) (...)&lt;br /&gt;
*heute - entspricht 12:00&lt;br /&gt;
*früh - entspricht 9 Uhr&lt;br /&gt;
*abend - entspricht 18 Uhr&lt;br /&gt;
*nachmittag - entspricht 16 Uhr&lt;br /&gt;
*vormittag - entspricht 10:30 Uhr&lt;br /&gt;
*mittag - entspricht 12 Uhr&lt;br /&gt;
*gleich - entspricht 5 Minuten&lt;br /&gt;
*nachher - entspricht 30 Minuten&lt;br /&gt;
*später - entspricht 1 Stunde&lt;br /&gt;
*jetzt&lt;br /&gt;
*sofort&lt;br /&gt;
&lt;br /&gt;
Datum und Zeitangaben können natürlich kombiniert werden.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Wird eine Zeit erfolgreich erkannt erfolgt die Ausführung des FHEM-Kommandos über das Modul &#039;&#039;&#039;at&#039;&#039;&#039;. Es wird ein at Eregnis angelegt welches den Namen &#039;&#039;at_&amp;lt;modulname&amp;gt;_&amp;lt;zeitindex&amp;gt;&#039;&#039; erhält.&lt;br /&gt;
&lt;br /&gt;
Bei mehreren Kommandos über das Schlüsselwort &#039;&#039;UND&#039;&#039; wirkt sich der Zeitpunkt des ersten Kommandos auch auf das zweite und dritte ... aus.&lt;br /&gt;
 Schalte die Heizung um 20 Uhr aus und mache die Rollläden runter&lt;br /&gt;
Beide Kommandos werden um 20 Uhr ausgelöst.&lt;br /&gt;
&lt;br /&gt;
Hat das zweite Kommando ebenfalls eine Zeitphrase wird diese Zeit genommen.&lt;br /&gt;
 schalte die Heizung heute Abend ab und mache die Rollläden jetzt runter&lt;br /&gt;
==== Zeitenmodifikation ====&lt;br /&gt;
Wie oben gesehen wird der Zeitpunkt des ersten Kommandos vor dem &amp;quot;und&amp;quot; auch für das zweite nach dem &amp;quot;und&amp;quot; gesetzt. Vorausgesetzt er wird beim 2. Kommando nicht durch eine eigenständige Zeit (hier &amp;quot;jetzt&amp;quot;) ersetzt.&lt;br /&gt;
Wenn man die Zeit des zweiten Kommandos, relativ zum ersten setzen möchte, kann dies mit den Schlüsselwörtern &#039;&#039;dann&#039;&#039;, &#039;&#039;danach&#039;&#039; oder &#039;&#039;wieder&#039;&#039;  formuliert werden.&lt;br /&gt;
 Fahre um 14 Uhr die Rollläden an der Terrasse runter und schalte dann in 2 Minuten die Bewässerung an&lt;br /&gt;
oder&lt;br /&gt;
 Mach am Freitag um 5 Uhr die Heizung aus und in einer Woche wieder an&lt;br /&gt;
&lt;br /&gt;
Manchmal ist es notwendig etwas vor der angegebenen Zeit auszuführen. Hier lässt sich ein Offset zu dem ermittelten Zeitpunkt hinzufügen, um ihn zu ändern.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;perl&#039;&amp;gt;dusche\S?$ = (offset=&amp;gt;-3600, cmd=&amp;gt;&#039;set d_log bad warm&#039;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Der Sprachbefehl&lt;br /&gt;
 ich will um 18:30 Uhr duschen&lt;br /&gt;
Legt folgendes at Ergnis an&lt;br /&gt;
 define at_assi_1513096200 at 2017-12-12T17:30:00 set d_log bad warm&lt;br /&gt;
&lt;br /&gt;
== Konfiguration ==&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration des Moduls wird hauptsächlich über die Definition (DEF) vorgenommen.&lt;br /&gt;
Eine Konfiguration beginnt immer mit der Definition der gesuchten Schlüsselwörtern gefolgt von einem Gleichheitszeichen &#039;&#039;(siehe Randnotiz)&#039;&#039;. Diese werden Anhand von Regulären Ausdrücken (RegExp) beschrieben. Also z.B.:&lt;br /&gt;
 garage auf =&lt;br /&gt;
Das bededutet, sobald die Wörter in der Reihenfolge &amp;quot;garage&amp;quot; und &amp;quot;auf&amp;quot; erkannt werden, wird der Kommandoteil der Konfiguration ausgeführt. Groß- und Kleinschreibung wird grundsätzlich ignoriert.&lt;br /&gt;
&lt;br /&gt;
{{Randnotiz|RNText=Wichtig&lt;br /&gt;
Vor und nach dem Gleichheitszeichen muss mindestens ein Trennzeichen vorhanden sein&lt;br /&gt;
*Vor dem &amp;quot;=&amp;quot; mindestens ein Leer- oder Tabulatorzeichen&lt;br /&gt;
*Nach dem &amp;quot;=&amp;quot; können zusätzlich auch Zeilenumbrüche eingefügt werden&lt;br /&gt;
}}&lt;br /&gt;
Der Kommandoteil folgt dem Gleichheitszeichen &#039;&#039;(siehe Randnotiz)&#039;&#039;. Und kann auf folgende Arten vorliegen.&lt;br /&gt;
* FHEM Kommando&lt;br /&gt;
* { Perl Befehl }&lt;br /&gt;
* ( [[Modul_Talk2Fhem#erweiterte_Befehlskonfiguration]] )&lt;br /&gt;
&lt;br /&gt;
=== Übersicht ===&lt;br /&gt;
 &amp;lt;regexp&amp;gt; = &amp;lt;command&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im ganzen könnte die Konfiguration dann so aussehen:&lt;br /&gt;
 garage\S* auf = set dev_garage open&lt;br /&gt;
&#039;&#039;\S* Siehe hierzu [[Modul_Talk2Fhem#Häufig_verwendete_RegExp|Häufig verwendete RegExp]].&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bei dem vorherigen Beispiel, würde der FHEM Befehl &amp;quot;set garage open&amp;quot; bei allen folgenden Sprachbefehlen ausgeführt werden.&lt;br /&gt;
 Mach bitte die Garage auf&lt;br /&gt;
 Das haus soll das Garagentor aufmachen&lt;br /&gt;
 Garagentür in 5 Minuten auf&lt;br /&gt;
 Die Garagen soll in einer Stunde aufgemacht werden&lt;br /&gt;
&lt;br /&gt;
=== Klammerüberführung ===&lt;br /&gt;
&lt;br /&gt;
Es ist nicht notwendig für jeden Zustand oder jedes Gerät eine eigene Konfigurationzeile zu erzeugen. Hierfür gibt es die Möglichkeit, wie bei Regulären Ausdrücken üblich, Klammern &amp;quot;( )&amp;quot; im &amp;lt;regex&amp;gt;-Teil zu erfassen. Dies erfolgt über die Standartvariablen $1, $2, ..., $n. &amp;quot;n&amp;quot; steht hier für die nte Klammer.&lt;br /&gt;
Zusätzlich gibt es in Talk2Fhem die Möglichkeit die Klammern zu modifizieren.&lt;br /&gt;
&lt;br /&gt;
Soll die Garage auf und zugemacht werden, lässt sich folgendermaßen beschreiben.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
 garage\S* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(\S+)&amp;lt;/span&amp;gt; = set dev_garage &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Satz: &amp;quot;Mach die Garage auf&amp;quot; ergibt dann als FHEM Kommando&lt;br /&gt;
 set dev_garage auf&lt;br /&gt;
&lt;br /&gt;
=== Klammermodifikation ===&lt;br /&gt;
&lt;br /&gt;
Da es in den meißten Fällen nicht gewünscht ist, nur das gefunde Wort in das FHEM Kommando zu überführen, lässt sich zusätzlich das gefundene Wort modifizieren.&lt;br /&gt;
&lt;br /&gt;
==== Variante 1: nach Typ ====&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kann die Klammer auf ihren Typ hin modifiziert werden.&lt;br /&gt;
&lt;br /&gt;
===== Definition =====&lt;br /&gt;
&lt;br /&gt;
 $n{ &#039;&#039;&#039;typ&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;modification&#039;&#039;&#039;, typ2 =&amp;gt; mod2, ..., typn =&amp;gt; modn }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;typ&#039;&#039;&#039; kann eines der folgenden Wörtern enthalten:&lt;br /&gt;
*&#039;&#039;true&#039;&#039; sind alle Wörter die eine positive Richtung enthalten. Wie z.B. auf, ein, hoch, an, usw.&lt;br /&gt;
*&#039;&#039;false&#039;&#039; sind alle Wörter die eine negative Richtung enthalten. Wie z.B. ab, aus, runter, zu, usw.&lt;br /&gt;
*&#039;&#039;integer&#039;&#039; Wort enthält eine Zahl&lt;br /&gt;
*&#039;&#039;empty&#039;&#039; Wort enthält eine Leere Zeichenkette&lt;br /&gt;
*&#039;&#039;/&amp;lt;regexp&amp;gt;/&#039;&#039; Wort entspricht der &amp;lt;regexp&amp;gt;&lt;br /&gt;
*&#039;&#039;else&#039;&#039; Falls keines der Fälle zutrifft&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;modification&#039;&#039;&#039; enthält das einzufügende Wort.&lt;br /&gt;
&lt;br /&gt;
===== Beispiel =====&lt;br /&gt;
 garage\S* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(\S*)&amp;lt;/span&amp;gt; = set dev_garage &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;{ true =&amp;gt; open , false =&amp;gt; close }&lt;br /&gt;
Die Sätze:&lt;br /&gt;
 mach die Garage auf&lt;br /&gt;
 bitte Garagentor schließen &lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set dev_garage open&lt;br /&gt;
 set dev_garage close&lt;br /&gt;
&lt;br /&gt;
===== Befehlsumkehr =====&lt;br /&gt;
Ein zusätzlicher Vorteil dieser Methode ist, dass über das Schlüsselwort &amp;quot;wieder&amp;quot; ein Befehlsumkehr ausgelöst werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
 mach bitte die Garage auf und in 5 Minuten wieder zu&lt;br /&gt;
&lt;br /&gt;
==== Variante 2: nach Liste ====&lt;br /&gt;
&amp;lt;hr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier kann die Klammer anhand einer oder zweier Listen selektiert werden.&lt;br /&gt;
&lt;br /&gt;
===== Definition =====&lt;br /&gt;
&lt;br /&gt;
 $n[ wert1, wert2,,,,, wertn ]&lt;br /&gt;
oder&lt;br /&gt;
 $n[ @liste ]&lt;br /&gt;
&lt;br /&gt;
Innerhalb der Klammern [ ] wird eine Komma separierte Liste mit Namen erwartet die als Modifikatorliste dient. Die sogenannte Modwordlist. Die Werte sind immer optional und können leer gelassen werden. Über das Attribut &#039;&#039;T2F_modwordlist&#039;&#039; können diese Listen zur Übersicht und Wiederverwendbarkeit angelegt werden. Siehe Attribute. Auf diese Listen, lässt sich über den Namen der Liste, mit einem vorangestelltes &#039;@&#039; zugreifen.&lt;br /&gt;
&lt;br /&gt;
===== Beispiel nach Position =====&lt;br /&gt;
&lt;br /&gt;
Beim ersten Beispiel wird eine Zahl im regex-Teil erwartet (\d+). Diese Zahl entscheidet welche Position aus der Modwordlist ausgewählt werden soll.&lt;br /&gt;
 ventilator auf (stufe )?&amp;lt;span style=&#039;color:red&#039;&amp;gt;(\d+)&amp;lt;/span&amp;gt; = set aircon &amp;lt;span style=&#039;color:red&#039;&amp;gt;$2&amp;lt;/span&amp;gt;[ off, level1, level2, level3 ]                                                                                              &lt;br /&gt;
                &amp;lt;span style=&#039;color:gray&#039;&amp;gt;           |------------------&amp;gt;  0      1       2       3&amp;lt;/span&amp;gt;            &lt;br /&gt;
&#039;&#039;(Stufe )?&#039;&#039; bedeutet: Das Wort Stufe kann, muss aber nicht.&lt;br /&gt;
&lt;br /&gt;
Die Sätze:&lt;br /&gt;
 Ventilator in 10 Minuten auf Stufe 0&lt;br /&gt;
 Ventilator auf 3&lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set aircon off&lt;br /&gt;
 set aircon level3&lt;br /&gt;
&lt;br /&gt;
===== Beispiel nach Vergleichsliste =====&lt;br /&gt;
&lt;br /&gt;
Hier kommt eine weitere Liste ins Spiel. Die sogenannte Keywordlist ist im Eigentlichen eine RegExp &amp;quot;Ver-oder-ung&amp;quot;.&lt;br /&gt;
 ( key1 | key2 | ... | keyn )&lt;br /&gt;
oder&lt;br /&gt;
 ( @keywordlist )&lt;br /&gt;
Diese Liste mit Schlüsselwörtern wird im &amp;lt;regex&amp;gt;-Teil angegeben. Hier entscheidet nicht eine Zahl über die Position, sondern die Position die in der Keywordlist einen Treffer hat wird an selber Position in der Modwordlist ausgewählt. Im Attribut T2F_keywordlist können vordefinierte Listen angelegt werden und mit @keylist ausgewählt werden&lt;br /&gt;
&lt;br /&gt;
 blendet.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;(Wohnzimmer|Esszimmer|Küche)&amp;lt;/span&amp;gt; = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;$1&amp;lt;/span&amp;gt;[act_lvgroom, act_dinroom, act_kitchen] 70&lt;br /&gt;
               &amp;lt;span style=&#039;color:gray&#039;&amp;gt;|__________|_______|___________________|_____________|____________|&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;.*&#039;&#039; beliebig viele Zeichen&lt;br /&gt;
&lt;br /&gt;
Die Sätze: &lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 ich sitze geblendet im Wohnzimmer&lt;br /&gt;
 die sonne blendet in der Küche&lt;br /&gt;
würden hier folgende Befehle auslösen&lt;br /&gt;
 set act_dinroom 70&lt;br /&gt;
 set act_lvgroom 70&lt;br /&gt;
 set act_kitchen 70&lt;br /&gt;
&lt;br /&gt;
===== Ergänzung =====&lt;br /&gt;
Ähnlich wie in Variante 1, könne  auch hier auf die Schlüsselwörte &lt;br /&gt;
 empty für leere Zeichenkette &lt;br /&gt;
und &lt;br /&gt;
 else für alle anderen Fälle&lt;br /&gt;
zugegriffen werden. Hierbei wird der Modwordlist einfach empty oder else gefolgt von dem gewünschten Wert als nächstes Element angehängt.&lt;br /&gt;
 $n[ wert1, wert2,,,, empty, wert3, else, wert4 ]&lt;br /&gt;
&lt;br /&gt;
=== erweiterte Befehlskonfiguration ===&lt;br /&gt;
Um Talk2Fhem in den Konfigurationszeilen weitere Parameter zu übergeben, ist eine gesonderte Syntax zu verwenden.&lt;br /&gt;
 &amp;lt;regexp&amp;gt; = ( option =&amp;gt; &#039;value&#039;  ,&lt;br /&gt;
              opt2   =&amp;gt; &#039;value2&#039; ,&lt;br /&gt;
              ... &lt;br /&gt;
              optn   =&amp;gt; &#039;valuen&#039; ) &lt;br /&gt;
Es stehen folgende Optionen zur Verfügung:&lt;br /&gt;
*cmd    =&amp;gt; enthält das FHEM Kommando.  Wie oben beschrieben.&lt;br /&gt;
*answer  =&amp;gt;  Ein in Anführungszeichen (&amp;quot; oder &#039;) gesetzter Perl-Befehl, dessen Rückgabe in das Reading &#039;&#039;answer&#039;&#039; geschrieben wird.&lt;br /&gt;
* offset =&amp;gt;  Ganzzahliger Wert in Sekunden der dem Zeitpunkt addiert wird. Siehe [[Modul_Talk2Fhem#Zeitenmodifikation]]&lt;br /&gt;
&lt;br /&gt;
=== Antworten ===&lt;br /&gt;
In Talk2Fhem können Antworten, die das Modul ausgeben soll, definiert werden. Hier können Fragen verarbeitet werden oder auch den Erfolg eines Kommandos bestätigt werden.&lt;br /&gt;
&lt;br /&gt;
Über die [[Modul_Talk2Fhem#erweiterte_Befehlskonfiguration]], erhält der Parameter &amp;quot;answer&amp;quot; einen Perl Befehl, dessen Rückgabe die Antwort darstellt.&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Erfolgsmeldung ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;tu was = ( cmd =&amp;gt; &amp;quot;set tue es&amp;quot; , answer =&amp;gt; &#039;&amp;quot;Erledigt&amp;quot;&#039; )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Man beachte hier, dass die Parameter immer in Anführungszeichen gesetzt werden müssen. In diesem Fall der Perl Befehl. Ein Text in Perl wird ebenfalls in Anführungszeichen gesetzt, deswegen die doppelten Anführungszeichen!&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Zustandsabfrage ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;wurde es getan = ( answer =&amp;gt; &#039;Value(&amp;quot;tue&amp;quot;) eq &amp;quot;es&amp;quot; ? &amp;quot;Ja&amp;quot; : &amp;quot;Nein&amp;quot;&#039;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel Temperaturabfragen ====&lt;br /&gt;
Eine einfache Temperaturabfrage könnte so aussehen.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;wie.*(kalt|warm|grad|temperatur) = ( answer =&amp;gt; &#039;&amp;quot;Die Temperatur beträgt &amp;quot;.ReadingsVal(&amp;quot;tempdev&amp;quot;, &amp;quot;temperature&amp;quot;, &amp;quot;Fehler&amp;quot;)&#039; )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Für eine Raumbezogene Temperaturabfrage, siehe [[Modul_Talk2Fhem#Anwendungsbeispiele_und_Vorlagen]]&lt;br /&gt;
&lt;br /&gt;
== Attribute ==&lt;br /&gt;
Folgende Attribute werden zur Zeit unterstützt&lt;br /&gt;
=== T2F_keywordlist ===&lt;br /&gt;
 &amp;lt;Name&amp;gt; = &amp;lt;kommaseparierte Liste mit RegExp&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Beispiele&#039;&#039;&#039;&lt;br /&gt;
 rooms = haus|überall|wohnung , wohnzimmer , bad\S* , toilette|wc , büro , ...&lt;br /&gt;
 names = Mama , Papa , Kevin , Jacqueline&lt;br /&gt;
 channels = ard|das erste , zdf , rtl , sat 1 , vox , rtl2 , prosieben , kabel eins , arte&lt;br /&gt;
Man beachte hier die möglichkeit der RegExp&amp;lt;br&amp;gt;&lt;br /&gt;
Das Schlüsselwort &#039;&#039;&#039;haus&#039;&#039;&#039; löst das selbe aus wie &#039;&#039;&#039;überall&#039;&#039;&#039; und &#039;&#039;&#039;wohnung&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;Genauso &#039;&#039;&#039;bad&#039;&#039;&#039; oder &#039;&#039;&#039;badezimmer&#039;&#039;&#039; oder &#039;&#039;&#039;badeirgendewas&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== T2F_modwordlist ===&lt;br /&gt;
 &amp;lt;Name&amp;gt; = &amp;lt;kommaseparierte Liste mir RegExp&amp;gt;&lt;br /&gt;
Die Positionen der gewählten Geräte, ist eine Zuordnung zu den Listen in&#039;&#039;T2F_keywordlist&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;Wenn Wohnzimmer in der keywordliste &amp;lt;rooms&amp;gt; an Position 2 steht muss der Rolladenaktor in der modworliste &amp;lt;roll&amp;gt; auch an Position 2 stehen.&lt;br /&gt;
 roll = rollos_alle , d_rollo_wz , hm_roll_bad.* , hm_roll_wc , hm_roll_buero.* , ...&lt;br /&gt;
 lights = alle_lichte , &#039;&#039;&#039;&amp;quot;sw_wz1,sw_wz2&amp;quot;&#039;&#039;&#039; , sw_bad.* , sw_wc&lt;br /&gt;
Sollen einem Schlüsselwort mehrere Aktoren zugeordnet werden, geht das über sogenannte &amp;quot;Quotes&amp;quot;. (Anführungszeichen) Siehe &amp;lt;lights&amp;gt;.&lt;br /&gt;
 &amp;quot;a,b&amp;quot;  oder  &#039;a,b&#039;  oder  a\,b&lt;br /&gt;
&lt;br /&gt;
=== T2F_disableumlautescaping ===&lt;br /&gt;
&lt;br /&gt;
Deaktiviert das Konvertieren der Umlaute innnerhalb von regulären Ausdrücken in &#039;&#039;&#039;\S\S?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== T2F_language ===&lt;br /&gt;
&lt;br /&gt;
Legt die verwendete Sprache fest. Alternativ wird das Globale Attribut &#039;&#039;language&#039;&#039; verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== disable ===&lt;br /&gt;
Deaktiviert das Ausführen des FHEM Kommandos&lt;br /&gt;
=== verbose ===&lt;br /&gt;
&lt;br /&gt;
== Anwendungsbeispiele und Vorlagen ==&lt;br /&gt;
Hier folgen diverse Vorlagen und Beispiele die jeweils an die eigenen Bedürfnisse angepassst werden sollten/müssen. Hierzu sind die entsprechenden Stellen &amp;lt;span style=&#039;color:red&#039;&amp;gt;rot&amp;lt;/span&amp;gt; markiert.&lt;br /&gt;
=== Keywordlist ===&lt;br /&gt;
Eine typische Keywordlist wäre eine Auflistung der benötigten Räume&lt;br /&gt;
 rooms = haus|überall|wohnung,wohnzimmer,esszimmer,bad\S*,toilette|wc,&lt;br /&gt;
 büro,schlafzimmer,ankleide|garderobe,kinderzimmer,spielzimmer,&lt;br /&gt;
 flur|gang|diele,garage,garten,terrasse,balkon,&lt;br /&gt;
 eg|erdgescho\S*,og|obergescho\S*,\S*auße\S*( haus)?|vor der tür&lt;br /&gt;
&lt;br /&gt;
=== Einfaches schalten ===&lt;br /&gt;
 licht (\S+) = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;dev_light&amp;lt;/span&amp;gt; $1{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
=== Einfaches schalten mit eigenen Wörtern ===&lt;br /&gt;
Will man neben an/aus einen weiteren Zustand selbst definieren, kann das so geschehen.&lt;br /&gt;
 garage (\S+) = set &amp;lt;span style=&#039;color:red&#039;&amp;gt;dev_gate&amp;lt;/span&amp;gt; $1{ /&amp;lt;span style=&#039;color:red&#039;&amp;gt;kurz&amp;lt;/span&amp;gt;/ =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;open-for-time 5&amp;lt;/span&amp;gt;, true =&amp;gt; open, false =&amp;gt; close }&lt;br /&gt;
&lt;br /&gt;
=== Einfaches schalten mit Räumen ===&lt;br /&gt;
 licht (\S+ ){0,2} (&amp;lt;span style=&#039;color:red&#039;&amp;gt;wohnzimmer|esszimmer|küche|terrasse&amp;lt;/span&amp;gt;) (\S+) = set $2[&amp;lt;span style=&#039;color:red&#039;&amp;gt;light_wz,light_ez,light_kitchen,light_outside&amp;lt;/span&amp;gt;] $3{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
Bei größeren Mengen an Räumen und Geräten bietet sich das anlegen von Keyword- und Modwordlisten an. &lt;br /&gt;
 licht (\S+ ){0,2} (&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;) (\S+) = set $2[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@lights&amp;lt;/span&amp;gt;] $3{ true =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false =&amp;gt; &amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt; }&lt;br /&gt;
&lt;br /&gt;
=== Rolladen fahren ===&lt;br /&gt;
Sind die Rollläden innerhalb von FHEM über das Attribut &amp;quot;room&amp;quot; den Räumen mit Klarnamen zugeordnet, lässt sich das ganze am einfachsten konfigurieren.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;1.  nach Devicetyp&#039;&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(\S+) (auf )?(\S+) = {fhem(&#039;set room=&#039;.ucfirst(&#039;$3&#039;).&#039;:FILTER=a:subType=blindActuator &amp;lt;span style=&#039;color:red&#039;&amp;gt;$5&amp;lt;/span&amp;gt;{true=&amp;gt;on, false=&amp;gt;off, integer=&amp;gt;&#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;set_$5&amp;lt;/span&amp;gt;&#039;)}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erklärung&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn das Device vom subTyp &amp;quot;blindActuator&amp;quot; ist (HomeMatic Rolladenactor) und es im Raum $3 ist, wird dieses Device gefahren. Die Funktion ucfirst ist notwendig damit der erste Buchstabe groß geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;2.  nach Devicenamen&#039;&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(\S+) (auf )?(\S+) = {fhem(&#039;set room=&#039;.ucfirst(&#039;$3&#039;).&#039;:FILTER=rollo.* &amp;lt;span style=&#039;color:red&#039;&amp;gt;$5&amp;lt;/span&amp;gt;{true=&amp;gt;on, false=&amp;gt;off, integer=&amp;gt;&#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;set_$5&amp;lt;/span&amp;gt;&#039;)}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erklärung&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Gleiche wie oben, nur das alle Devices die mit rollo beginnen im Raum $3 gefahren werden. (rollo.*)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;3.  nach Benutzerdefinierten Räumen&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Ansonsten müssen wir dem Modul sagen in welchem Raum welches Device sitzt. Das hat dafür den Vorteil das die Räume als RegExp angegeben werden können.&amp;lt;br&amp;gt;Wir erzeugen eine Modwordlist &#039;&#039;rollos&#039;&#039; in der wir alle Rollladen &amp;quot;Devices&amp;quot; auflisten. Die Reihenfolge ist an der Keywordlist &amp;quot;rooms&amp;quot; ([[Modul_Talk2Fhem#Keywordlist]]) anzupassen.&lt;br /&gt;
 rollos = &amp;lt;span style=&#039;color:red&#039;&amp;gt;r_alle&amp;lt;/span&amp;gt;,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_wz&amp;lt;/span&amp;gt;,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_ez&amp;lt;/span&amp;gt;,,&amp;lt;span style=&#039;color:red&#039;&amp;gt;r_buero&amp;lt;/span&amp;gt;,...&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
 rolll?(os?|\S\S?den) ?(\S+ ){0,2}(&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;)? (auf )?(\S+) = set $3[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rollos&amp;lt;/span&amp;gt;, empty, &amp;lt;span style=&#039;color:red&#039;&amp;gt;rollos_alle&amp;lt;/span&amp;gt;] $5{true=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;on&amp;lt;/span&amp;gt;, false=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;off&amp;lt;/span&amp;gt;, integer=&amp;gt;&amp;lt;span style=&#039;color:red&#039;&amp;gt;&amp;quot;set_$5&amp;quot;&amp;lt;/span&amp;gt;}&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 Rollos auf&lt;br /&gt;
 Rolllos Überall schließen &lt;br /&gt;
 Rollo im Wohnzimmer hoch&lt;br /&gt;
 Rolladen im Esszimmer runter&lt;br /&gt;
 Rollläden in der Küche auf 50&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Damit wäre eigentlich schon alles abgedeckt. Folgendes Beispiel ist aber auch noch nützlich.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
  (blendet|schatte\S?) ?(\S+ ){0,2}(&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rooms&amp;lt;/span&amp;gt;) = set $3[&amp;lt;span style=&#039;color:red&#039;&amp;gt;@rollos&amp;lt;/span&amp;gt;] &amp;lt;span style=&#039;color:red&#039;&amp;gt;set_70&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 es blendet im Esszimmer&lt;br /&gt;
 ich werde geblendet in der Küche&lt;br /&gt;
 die Sonne blendet mich im Badezimmer&lt;br /&gt;
 beschatte das Haus&lt;br /&gt;
 mach schatten im Erdgeschoss&lt;br /&gt;
&lt;br /&gt;
=== GoogleCast Befehle ===&lt;br /&gt;
Etwas bessere Lautstärkebefehle als die von Google.&lt;br /&gt;
Die Lautstärken müssten noch dem eigenen Geschmack angepasst werden&lt;br /&gt;
 #GoogleCast Commandos&lt;br /&gt;
 leise$            =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 14&lt;br /&gt;
 normale lautstärke =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 20&lt;br /&gt;
 laut$             =  set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume 30&lt;br /&gt;
 (ein wenig|etwas|viel)? ?(lauter|leiser)  =  { fhem(&amp;quot;set &amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt; volume &amp;quot;.(ReadingsVal(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;googlecastdevice&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;volume&amp;quot;, 0)$2[+,-]$1[3,5,10,empty,7])) }&lt;br /&gt;
&#039;&#039;&#039; Beispielsätze &#039;&#039;&#039;&lt;br /&gt;
 Mach leise&lt;br /&gt;
 Mach lauter&lt;br /&gt;
 Mach etwas leiser&lt;br /&gt;
 Mach viel lauter&lt;br /&gt;
&lt;br /&gt;
=== Talk Timer zurücksetzen ===&lt;br /&gt;
Sollen alle von Talk2Fhem angelegten Timer gelöscht werden.&lt;br /&gt;
 (timer|kommandos) (löschen|zurücksetzen) = delete at_&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;.*&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 bitte alle timer zurücksetzen&lt;br /&gt;
 zukünftige kommandos löschen&lt;br /&gt;
&lt;br /&gt;
=== Frage Antwort ===&lt;br /&gt;
==== Raumbezogene Temperaturansage ====&lt;br /&gt;
Wir erzeugen wieder unsere Modwordlist sagen wir @sens gefüllt mit den Temperaturfühler &amp;quot;Devices&amp;quot;. Reihenfolge wie immer die der Keywordlist @rooms.&lt;br /&gt;
 wie.*(kalt|warm|grad|temperatur).*(&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;@rooms&amp;lt;/span&amp;gt;) = ( answer =&amp;gt; &#039;&amp;quot;Die Temperatur beträgt &amp;quot;.ReadingsVal(&amp;quot;$2[&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;@sens&amp;lt;/span&amp;gt;]&amp;quot;, &amp;quot;&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;temperature&amp;lt;/span&amp;gt;&amp;quot;, &amp;quot;unbekannt&amp;quot;).&amp;quot; grad&amp;quot;&#039; )&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 wie warm ist es im Wohnzimmer&lt;br /&gt;
 wie ist die Temperatur in der Küche&lt;br /&gt;
 wie kalt ist es draußen&lt;br /&gt;
&lt;br /&gt;
==== Multiple Antworten ====&lt;br /&gt;
 Hallo Haus = ( answer =&amp;gt; &#039;[&amp;quot;Hallo auch!&amp;quot;,&amp;quot;Guten Tag!&amp;quot;,&amp;quot;Ahoi!&amp;quot;]-&amp;gt;[rand(&amp;lt;span style=&amp;quot;Color:red&amp;quot;&amp;gt;3&amp;lt;/span&amp;gt;)]&#039; ) &lt;br /&gt;
Wählt zufällig eine der drei Aussagen.&lt;br /&gt;
&lt;br /&gt;
==== Ausgabe eines oder mehrerer Zustände ====&lt;br /&gt;
Angenommen man möchte wissen ob das Haus abgeschlossen ist. Und in FHEM existiert ein Dummy der diesen Zustand wiederspiegelt und im Reading text die offenen Fenster und Türen aufgelistet sind. Kann man folgendermaßen den Status erfragen&lt;br /&gt;
 (alles|das haus) (zu|abgeschlossen) = (&lt;br /&gt;
   answer =&amp;gt; &#039;(Value(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;d_schliessung&amp;lt;/span&amp;gt;&amp;quot;) eq &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;zu&amp;lt;/span&amp;gt;&amp;quot;) &lt;br /&gt;
   ? &amp;quot;Es ist alles zu&amp;quot; &lt;br /&gt;
   : &amp;quot;Nein, offen sind: &amp;quot;.ReadingsVal(&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;d_schliessung&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;text&amp;lt;/span&amp;gt;&amp;quot;,&amp;quot;&amp;quot;)&#039;&lt;br /&gt;
&lt;br /&gt;
==== Zustandsabfrage anhand des Aliasnamen ====&lt;br /&gt;
Möchte man alle Geräte anhand seines Attribut &amp;quot;alias&amp;quot; ansprechen, um dessen Status zu erfragen, könnte das so erfolgen.&lt;br /&gt;
&amp;lt;br&amp;gt;&#039;&#039;&#039;Definition&#039;&#039;&#039; &lt;br /&gt;
 (zustand|status) (\S+)* (\S+) = (answer=&amp;gt;&#039;my $s=Value((grep { &amp;quot;$3&amp;quot; =~ /$attr{$_}{&amp;lt;span style=&#039;color:red&#039;&amp;gt;alias&amp;lt;/span&amp;gt;}/i } (keys %attr))[0]);; &amp;quot;Der Status ist &amp;quot;.$s if $s&#039;)&lt;br /&gt;
&#039;&#039;&#039;Beispielsätze&#039;&#039;&#039;&lt;br /&gt;
 Wie ist der Zustand der Lüftung&lt;br /&gt;
 sag mir den Status der Haustür&lt;br /&gt;
Es ist auch möglich ein eigenes Attribut zu kreieren, und dieses als Klarnamenattribut zu verwenden. Hierzu einfach im Device global ein userattr hinzufügen. z.B.&lt;br /&gt;
 attr global userattr T2F_alias&lt;br /&gt;
Jetzt stehen in allen Devices das Attribut T2F_alias zur Verfügung. Vorteil ist das dann auch wieder RegExp verwendet werden können. Im oberen Beispiel müsste dann dass rot markierte &amp;quot;alias&amp;quot; durch &amp;quot;T2F_alias&amp;quot; ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration innerhalb der Geräte ===&lt;br /&gt;
Neben der Identifikation der Geräte über die vorhandenen FHEM-Attribute (z.B. room, alias, ...) kann eine alternative Konfiguration auch über eigens für Talk2Fhem angelegte Attribute erfolgen. Die hierfür notwendigen Grundlagen und einige Beispiele sollen im Folgenden beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Grundlagen / Voraussetzungen ====&lt;br /&gt;
1. Anlegen der notwendigen userattr am global-Device:&lt;br /&gt;
&lt;br /&gt;
Erweiterung des Attributes userattr des Gerätes global um folgende Einträge:&lt;br /&gt;
  T2F_places:textField-long T2F_properties:textField-long T2F_rooms:textField-long T2F_types_color:textField-long T2F_types_heating:textField-long T2F_types_info:textField-long T2F_types_switch:textField-long&lt;br /&gt;
&lt;br /&gt;
2. Optional: Hilfsfunktionen für das automatische Füllen der T2F_keywordlist im talk-Device bei Änderung eines T2F-Attributes eines Gerätes&lt;br /&gt;
&lt;br /&gt;
2a. erstellen einer sub in der 99_myUtils.pm:&lt;br /&gt;
&lt;br /&gt;
  sub fill_T2F_keywordlist&lt;br /&gt;
  {&lt;br /&gt;
    my ($name, $t2f_device) = @_;&lt;br /&gt;
    $name =~ s/T2F_//g;&lt;br /&gt;
    if ($name eq &#039;userattr&#039;)&lt;br /&gt;
    {&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    Log 0, &amp;quot;List: &amp;quot;.$name;&lt;br /&gt;
    my $currentAttr = AttrVal($t2f_device,&amp;quot;T2F_keywordlist&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    my @currentAttrParts = split(/$name = /, $currentAttr);&lt;br /&gt;
    my $currentAttrBeg = @currentAttrParts[0];&lt;br /&gt;
    $currentAttrBeg = substr($currentAttrBeg, 0, -1);&lt;br /&gt;
    my @currentAttrEnd = split(/\n/, @currentAttrParts[1], 2);&lt;br /&gt;
    my @array = devspec2array(&#039;a:T2F_&#039;.$name.&#039;=.+&#039;);&lt;br /&gt;
    my @attributes = ();&lt;br /&gt;
    if (@array &amp;gt; 0 and defined($defs{$array[0]}))&lt;br /&gt;
    {&lt;br /&gt;
      foreach (@array){&lt;br /&gt;
      my @attrVals = split(/\n/,AttrVal($_, &#039;T2F_&#039;.$name, &#039;&#039;));&lt;br /&gt;
      foreach (@attrVals){&lt;br /&gt;
          my $attrVal = $_;&lt;br /&gt;
          $attrVal =~ s/  / /g;&lt;br /&gt;
          $attrVal =~ s/ =&amp;gt; /=&amp;gt;/g;&lt;br /&gt;
          my @attrValParts = split(/=&amp;gt;/,$attrVal);&lt;br /&gt;
          $attrVal = @attrValParts[0];&lt;br /&gt;
          $attrVal =~ s/!//g;&lt;br /&gt;
          $attrVal =~ s/, /,/g;&lt;br /&gt;
          my @attr = split(/,/, $attrVal);&lt;br /&gt;
          push(@attributes, @attr);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    my %hash   = map { $_ =&amp;gt; 1 } @attributes;&lt;br /&gt;
    my @unique = keys %hash;&lt;br /&gt;
    my $result = $currentAttrBeg.&amp;quot;\n&amp;quot;.$name.&amp;quot; = &amp;quot;.join(&amp;quot;, &amp;quot;, @unique).&amp;quot;\n&amp;quot;.@currentAttrEnd[1];&lt;br /&gt;
    $result =~ s/\n\n/\n/g;&lt;br /&gt;
    $result =~ s/  / /g;&lt;br /&gt;
    fhem(&#039;attr &#039;.$t2f_device.&#039; T2F_keywordlist &#039;.$result);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
2b. Erstellen eines DOIFs zum Aufruf der sub:&lt;br /&gt;
&lt;br /&gt;
  defmod talk.DI.fillAttr DOIF ([global:&amp;quot;^ATTR.*T2F_.*&amp;quot;]) ({my $val = ReadingsVal(&amp;quot;$SELF&amp;quot;, &amp;quot;e_global_events&amp;quot;, &amp;quot;&amp;quot;); $val =~ m/(\S*) (\S*) (\S*) (.*)/; if ($2 ne &#039;&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;&#039; &amp;amp;&amp;amp; $2 ne &#039;global&#039;) { fill_T2F_keywordlist(&amp;quot;$3&amp;quot;, &amp;quot;&amp;lt;span style=&#039;color:red&#039;&amp;gt;talk&amp;lt;/span&amp;gt;&amp;quot;);}})&lt;br /&gt;
  attr talk.DI.fillAttr do always&lt;br /&gt;
&lt;br /&gt;
3. Optional: Erlauben von Umlauten in den T2F-Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_disableumlautescaping 1  &lt;br /&gt;
  &lt;br /&gt;
Nun können die T2F-Attribute pro FHEM-Device definiert und dann in den Talk2Fhem-Befehlen benutzt werden. Wurde der Punkt 2 abgearbeitet, so werden mit dem Füllen der Attribute am Geräte auch die Keywordlisten am talk-Device gefüllt. Wie diese dann verwendet werden können, sollen die folgenden Beispiele zeigen.&lt;br /&gt;
&lt;br /&gt;
==== Schalten von Geräten ====&lt;br /&gt;
&lt;br /&gt;
Ausgangssituation: Es gibt drei Lampen Lampe1, Lampe2, Lampe3 und ein Nachtlicht mit einer Eule mit folgenden Attributen:&lt;br /&gt;
&lt;br /&gt;
  attr Lampe1 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe1 T2F_rooms Haus, Obergeschoss, !Esszimmer&lt;br /&gt;
  attr Lampe1 T2F_places Decke, Tür&lt;br /&gt;
  attr Lampe1 T2F_properties hell,!&lt;br /&gt;
&lt;br /&gt;
  attr Lampe2 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe2 T2F_rooms Haus, Obergeschoss, !Esszimmer&lt;br /&gt;
  attr Lampe2 T2F_places Tisch, Esstisch&lt;br /&gt;
  attr Lampe2 T2F_properties dunkel,schwach,!&lt;br /&gt;
&lt;br /&gt;
  attr Lampe3 T2F_types_switch Lampe, !Licht&lt;br /&gt;
  attr Lampe3 T2F_rooms Haus, Obergeschoss, !Küche&lt;br /&gt;
  attr Lampe3 T2F_places Besenschrank&lt;br /&gt;
  &lt;br /&gt;
  attr Nachtlicht T2F_types_switch Lampe, !Licht, Eule, Nachtlicht&lt;br /&gt;
  attr Nachtlicht T2F_rooms Haus, Obergeschoss, !Kinderschlafzimmer&lt;br /&gt;
  attr Nachtlicht T2F_places Steckdose&lt;br /&gt;
&lt;br /&gt;
Durch die in Punkt 2 der Voraussetzungen genannten Funktionen wurden folgende T2F-keywordlisten automatisch angelegt:&lt;br /&gt;
&lt;br /&gt;
  attr talk T2F_keywordlist rooms = Kinderschlafzimmer, Haus, Küche, Obergeschoss, Esszimmer &lt;br /&gt;
                            places = Tür, Steckdose, Tisch, Decke, Esstisch&lt;br /&gt;
                            properties = hell, dunkel, schwach&lt;br /&gt;
                            types_switch = Lampe, Licht, Eule&lt;br /&gt;
&lt;br /&gt;
Die Definition für das T2F-Device lautet dann wie folgt:&lt;br /&gt;
&lt;br /&gt;
  #   1              2                 3                4            5          6          7      &lt;br /&gt;
  ?(bitte) &amp;amp;&amp;amp; ?(@properties) &amp;amp;&amp;amp; (@types_switch) &amp;amp;&amp;amp; ?(@rooms) &amp;amp;&amp;amp; ?(@places) &amp;amp;&amp;amp; (\S+)(schalten|machen)?$ =&lt;br /&gt;
  (cmd=&amp;gt;&#039;set T2F_types_switch=.*$3@.*:FILTER=T2F_rooms=.*$4@.*:FILTER=T2F_properties=.*$2@.*:FILTER=T2F_places=.*$5@.* $6{true=&amp;gt;on, false=&amp;gt;off}&#039;,&lt;br /&gt;
  answer=&amp;gt;&#039;&amp;quot;$AGAIN&amp;quot; ? &amp;quot;dann $DATE wieder $6{true=&amp;gt;ein, false=&amp;gt;aus}&amp;quot; : &amp;quot;$1{/bitte/=&amp;gt;Gern, else=&amp;gt;Das heißt Bitte}, ich schalte $1{/bitte/=&amp;gt;, else=&amp;gt;trotzdem} folgende Geräte $6{true=&amp;gt;ein, false=&amp;gt;aus}: &amp;quot;.T2F_answer(&amp;quot;T2F_types_switch=.*$3@.*:FILTER=T2F_rooms=.*$4@.*:FILTER=T2F_properties=.*$2@.*:FILTER=T2F_places=.*$5@.*&amp;quot;,&amp;quot;T2F_types_switch&amp;quot;)&#039;)&lt;br /&gt;
                            &lt;br /&gt;
Damit sind dann die folgenden Sprachbefehle möglich:&lt;br /&gt;
&lt;br /&gt;
  Schalte das Licht in der Küche ein                      =&amp;gt; schaltet Lampe3 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte die helle Lampe im Esszimmer an                 =&amp;gt; schaltet Lampe1 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht im Esszimmer über dem Esstisch ein    =&amp;gt; schaltet Lampe2 ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte die Eule ein                                    =&amp;gt; schaltet Nachtlicht ein&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht im Esszimmer aus}                     =&amp;gt; schaltet Lampe1 und Lampe2 aus&lt;br /&gt;
  &lt;br /&gt;
  Schalte das Licht aus                                   =&amp;gt; schaltet alle vier Lichter aus&lt;br /&gt;
&lt;br /&gt;
Um in der Antwort die Liste der geschalteten Geräte genannt zu bekommen, wird die sub T2F_answer aus der 99_myUtils aufgerufen:&lt;br /&gt;
&lt;br /&gt;
  sub T2F_answer&lt;br /&gt;
  {&lt;br /&gt;
    my ($filter, $type) = @_;&lt;br /&gt;
    my $answer;&lt;br /&gt;
    my @devices = devspec2array($filter);&lt;br /&gt;
    if (@devices &amp;gt; 0 and defined($defs{$devices[0]}))&lt;br /&gt;
    {&lt;br /&gt;
      #$answer = &amp;quot;Ich habe folgende Geräte &amp;quot;.$command.&amp;quot;: &amp;quot;;&lt;br /&gt;
      foreach (@devices){&lt;br /&gt;
        $answer = $answer.&amp;quot;\n&amp;quot;;&lt;br /&gt;
        my $devAttr = AttrVal($_, $type, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        $devAttr = AttrVal($_, &#039;T2F_properties&#039;, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        $devAttr = AttrVal($_, &#039;T2F_rooms&#039;, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        $devAttr = AttrVal($_, &#039;T2F_places&#039;, &#039;&#039;);&lt;br /&gt;
        if (substr($devAttr,-1) ne &amp;quot;!&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          my @entries = split(/!/, $devAttr);&lt;br /&gt;
          if (@entries &amp;lt; 2)&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[0]);&lt;br /&gt;
          }&lt;br /&gt;
          else&lt;br /&gt;
          {&lt;br /&gt;
            @entries = split(/,/, $entries[1]);&lt;br /&gt;
          }&lt;br /&gt;
          if (@entries[0] ne &amp;quot;&amp;quot;)&lt;br /&gt;
          {&lt;br /&gt;
            $answer = $answer.@entries[0].&amp;quot; &amp;quot;;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    return $answer.&amp;quot;\n&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Die Benennung der Geräte erfolgt auf Basis derer T2F-Attribute: Typ, Eigenschaft, Raum, Ort. Ist das jeweilige Attribut leer, ist es auch in der Antwort leer. Enthält die jeweilige Attributliste ein Ausrufezeichen (!), so wird der Eintrag nach dem Ausrufezeichen für die Antwort verwendet (z.B. Esszimmer als Raum). Steht das Ausrufezeichen am Ende, so wird der Eintrag in der Antwort leer gelassen (z.B. die Eigenschaft bei Lampe1). Ist kein Ausrufezeichen vorhanden, so wird der erste Eintrag verwendet.&lt;br /&gt;
&lt;br /&gt;
==== Einstellen der Heizung ====&lt;br /&gt;
  &lt;br /&gt;
==== Einstellen der Farbe von Farbwechsellampen (Philips Hue, Wifilight, ...) ====&lt;br /&gt;
&lt;br /&gt;
==== Abfragen beliebiger Geräteinformationen ====&lt;br /&gt;
&lt;br /&gt;
== Häufig verwendete RegExp ==&lt;br /&gt;
Perl Regular Expression, also ein regulärer Ausdruck der Programmiersprache Perl, ist eine Werkzeug um Zeichenketten zu beschreiben. Hier wird ein kurzer Einblick auf die im Artikel häufig genutzten RegExp zu geben.&lt;br /&gt;
&lt;br /&gt;
Eine Auflistung der Syntax kann hier eingesehen werden. [http://jkorpela.fi/perl/regexp.html]&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! RegExp !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| \S* || Beliebig viele (*) nicht Leerzeichen (\S). Für unbekannten und unwichtigen Wortendungen&amp;lt;br&amp;gt;z.b. garage\S* ist bei Garage, Garagentor oder Garagentür erfolgreich&lt;br /&gt;
|-&lt;br /&gt;
| \S+ || Mehr als ein Zeichen (+) welches kein Leerzeichen ist (\S)&lt;br /&gt;
|-&lt;br /&gt;
| \S\S? || Ein oder zwei Zeichen die keine Leerzeichen sind. Das &amp;quot;?&amp;quot; wirkt hier nur auf das angrenzende &amp;quot;\S&amp;quot;.&amp;lt;br&amp;gt;Sollte für Umlaute verwendet werden, da bei manchen Eingabemethoden Probleme mit Umlauten auftreten können.&lt;br /&gt;
|-&lt;br /&gt;
| (wort )?  || Ein bestimmtes Wort oder nicht.&lt;br /&gt;
|-&lt;br /&gt;
| (wort1&amp;amp;#124;wort2) || Entweder wort1 oder Wort2&lt;br /&gt;
|-&lt;br /&gt;
| wort$ || Nur wenn das Wort am ende der Zeichenkette steht.&lt;br /&gt;
|-&lt;br /&gt;
| (\S+){0,2} || Keins, eins oder zwei Wörter. Kann für Artikel wie z.B. &amp;quot;(in der&amp;amp;#124;in dem&amp;amp;#124;im&amp;amp;#124;auf der&amp;amp;#124;...)?&amp;quot; eingesetzt werden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Eingabemethoden ==&lt;br /&gt;
Die Herkunft der Sprachbefehle für das Modul sind vielfältig. Hier werden einige Methoden beschrieben wie der Sprachbefehl in das Modul gelangen kann.&lt;br /&gt;
=== Messenger Telegram ===&lt;br /&gt;
Ist ein [[TelegramBot]] telbot definiert, reicht ein einfaches &amp;quot;notify&amp;quot; um die Nachrichten an FHEM an Talk2Fhem weiterzuleiten.&lt;br /&gt;
 define &amp;lt;span style=&#039;color:red&#039;&amp;gt;n_telbot&amp;lt;/span&amp;gt; notify &amp;lt;span style=&#039;color:red&#039;&amp;gt;telbot&amp;lt;/span&amp;gt;:msgText.* set talk $EVENT&lt;br /&gt;
Schon kann mit FHEM gechattet werden... ;)&lt;br /&gt;
&lt;br /&gt;
=== Google Home Geräte ===&lt;br /&gt;
Momentan ist es leider noch notwendig über einen Umweg die Sprache von einem GoogleHome in FHEM zu bringen. Hierzu ist es notwendig einen funktionierenden DNS Service am laufen zu haben. Damit FHEM per Webadresse im Internet erreichbar ist.&lt;br /&gt;
&lt;br /&gt;
*Ein FHEMWEB Device anlegen&lt;br /&gt;
 define api FHEMWEB 8087 global&lt;br /&gt;
 attr api HTTPS 1&lt;br /&gt;
 attr api allowfrom  1&lt;br /&gt;
 attr api csrfToken  None&lt;br /&gt;
*Ein allowed Device anlegen&lt;br /&gt;
 define allowed_api allowed api&lt;br /&gt;
 attr allowed_api allowedCommands set&lt;br /&gt;
 attr allowed_api allowedDevices talk&lt;br /&gt;
 attr allowed_api basicAuth  {&amp;quot;$user:$password&amp;quot; eq &#039;user:passwort&#039;}&lt;br /&gt;
 attr allowed_api validFor   api&lt;br /&gt;
*Mit Googlekono bei IFTTT.com anmelden&lt;br /&gt;
*New Applet&lt;br /&gt;
*+this GoogleAssistant -&amp;gt; Say a phrase with a text ingredient&lt;br /&gt;
* Die drei Triggertexte wählen z.b.&lt;br /&gt;
**das Haus $&lt;br /&gt;
**sag dem Haus $&lt;br /&gt;
**frag das Haus $&lt;br /&gt;
***Problem bei zu kurzen Texten hat GoogleHome keine anderen Anfragen mehr angenommen.&lt;br /&gt;
*Einen Antworttext überlegen z.B. OK und in &amp;quot;What do you want the Assistant to say in response?&amp;quot; eintragen&lt;br /&gt;
*Language Deutsch&lt;br /&gt;
*+that Webhooks&lt;br /&gt;
*URL wählen&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;https://user:password@dnsservice:54387/fhem?cmd.talk=set talk {{TextField}}&amp;amp;XHR=1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
*Fertig&lt;br /&gt;
&lt;br /&gt;
Jetzt wird der gesamte Text bei dem genannten Triggerworten an FHEM weitergeleitet.&lt;br /&gt;
&lt;br /&gt;
== Ausgabemethoden ==&lt;br /&gt;
&lt;br /&gt;
Siehe hierzu [[Modul_Talk2Fhem#Beispiel|Anwendungsbeispiel]]&lt;/div&gt;</summary>
		<author><name>RoBra81</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=TALKTOME_%26_TALKTOUSER_-_Sprachverarbeitung_f%C3%BCr_Nutzerinteraktionen&amp;diff=15799</id>
		<title>TALKTOME &amp; TALKTOUSER - Sprachverarbeitung für Nutzerinteraktionen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=TALKTOME_%26_TALKTOUSER_-_Sprachverarbeitung_f%C3%BCr_Nutzerinteraktionen&amp;diff=15799"/>
		<updated>2016-07-06T06:41:10Z</updated>

		<summary type="html">&lt;p&gt;RoBra81: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;float:right&amp;quot;&amp;gt;{{Infobox Modul&lt;br /&gt;
|ModType=h&lt;br /&gt;
|ModPurpose=Anbindung von RiveScript an FHEM&lt;br /&gt;
&amp;lt;!-- |ModCategory= (noch?) nicht verwendet --&amp;gt;&lt;br /&gt;
|ModCmdRef=TALKTOME&lt;br /&gt;
|ModForumArea=Automatisierung&lt;br /&gt;
|ModTechName=42_TALKTOME.pm&lt;br /&gt;
|ModOwner=SirUli&lt;br /&gt;
}}&lt;br /&gt;
{{Infobox Modul&lt;br /&gt;
|Name=TALKTOUSER&lt;br /&gt;
|ModType=h&lt;br /&gt;
|ModPurpose=Nutzerverbindung zu TALKTOME&lt;br /&gt;
&amp;lt;!-- |ModCategory= (noch?) nicht verwendet --&amp;gt;&lt;br /&gt;
|ModCmdRef=TALKTOUSER&lt;br /&gt;
|ModForumArea=Automatisierung&lt;br /&gt;
|ModTechName=42_TALKTOUSER.pm&lt;br /&gt;
|ModOwner=SirUli&lt;br /&gt;
}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Module TALKTOME &amp;amp; TALKTOUSER und der Sprache RiveScript ist es möglich, Chatbots - bekannt von Webseiten wie IKEA und co - für FHEM einzusetzen, um Frage-Antwort-Dialoge zu bauen.&lt;br /&gt;
&lt;br /&gt;
== Features / Funktionen ==&lt;br /&gt;
Die Haupteigenschaften von XYZ sind&lt;br /&gt;
* Anbindung von RiveScript an fhem&lt;br /&gt;
* Abruf von Readings, ReadingTimestamps, Attributen&lt;br /&gt;
* Absetzen von fhem Befehlen oder Aufruf von perl Funktionen&lt;br /&gt;
&lt;br /&gt;
== Hinweise zum Betrieb mit FHEM ==&lt;br /&gt;
=== Voraussetzungen ===&lt;br /&gt;
Die Einrichtung von msg - das macht mir das Antworten in die diversen Kanäle sehr viel einfacher.&lt;br /&gt;
&lt;br /&gt;
Installation von RiveScript in der Version 2.0.1 (oder neuer, falls eine erscheinen sollte) via CPAN. ACHTUNG nicht via apt-get installieren, da die Version zu alt ist.&lt;br /&gt;
&lt;br /&gt;
==== msg ====&lt;br /&gt;
Bei der ersten Verwendung des Befehls &amp;quot;msg&amp;quot; wird ein Device namens globalMsg angelegt, was man aber dem Modul vorweg nehmen kann:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define globalMsg msgConfig&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit sind die Voraussetzungen schon geschaffen&lt;br /&gt;
&lt;br /&gt;
==== Installation von RiveScript ====&lt;br /&gt;
Rufe cpan auf:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cpan&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das sieht dann etwa so aus:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo cpan&lt;br /&gt;
Loading internal null logger. Install Log::Log4perl for logging messages&lt;br /&gt;
Terminal does not support AddHistory.&lt;br /&gt;
&lt;br /&gt;
cpan shell -- CPAN exploration and modules installation (v2.10)&lt;br /&gt;
Enter &#039;h&#039; for help.&lt;br /&gt;
&lt;br /&gt;
cpan[1]&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installiere dann Rivescript mit Hilfe des folgenden Kommandos:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
install RiveScript&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls Fragen aufkommen, ob man Abhängigkeiten folgen soll, dann bitte richtig beantworten (yes) ;)&lt;br /&gt;
&lt;br /&gt;
=== Installation der Module ===&lt;br /&gt;
Geht wie immer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
update all https://raw.githubusercontent.com/SirUli/FHEM-TALKTO/master/controls_talkto.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anschließend sollte man im Ordner FHEM drei zusätzliche Files (42_TALKTOME.pm, 42_TALKTOUSER.pm sowie TALKTOME.rive.template) finden. Letzteres benennt man nun um in TALKTOME.rive. An dieser Stelle darf man das File natürlich auch schon editieren - wenn man möchte und Rivescript versteht.&lt;br /&gt;
&lt;br /&gt;
==== Definition ====&lt;br /&gt;
Dann geht es los mit der Definition des Chatbots an sich:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define FHEMTALKTOME TALKTOME&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FHEMTALKTOME ist sozusagen nun der Bot, welcher zu Beginn noch deaktiviert ist. Bevor man diesen aktiviert, muss man den Pfad zum TALKTOME.rive File setzen. Ist dieses file im Ordner FHEM (sozusagen also wie Auslieferungszustand und oben beschrieben), so setzt man folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attr FHEMTALKTOME rsbrainfile ./FHEM/TALKTOME.rive&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann man das Attribut &amp;quot;disable&amp;quot; entfernen. Für die Nutzerinteraktion kann man noch weitere Details eines Nutzer anlegen (derzeit nur den &amp;quot;richtigen&amp;quot; Namen), daher brauchen wir ein Benutzermodul, also z.B. für mich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define TALKTOUSER_ULI TALKTOUSER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bitte noch nicht wundern - derzeit ist das noch nicht voll ausgebaut, besser ihr legt erstmal nur ein Benutzergerät an.&lt;br /&gt;
&lt;br /&gt;
Nun kommt der wichtigste Teil - die Einbindung einer Quelle. Bei mir ist das nun Telegram, welches nun zwei zusätzliche Attribute via userAttr bekommen muss:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
talktouserMonitorReading talktouserModSourceDev&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Was heissen die Attribute?&lt;br /&gt;
&lt;br /&gt;
talktouserMonitorReading: Bezeichnet das Reading welches überwacht werden soll, im falle von Telegram ist dies auf &amp;quot;msgText&amp;quot; zu setzen&lt;br /&gt;
talktouserModSourceDev: Lässt eine Änderung des Quell Devices zu. So muss beispielsweise für Telegram, damit eine Antwort machbar ist, das Quelldevice verändert werden. Lokale Readings (also vom Quellverzeichnis) werden mit %%readingname%% angegeben, das device selbst ist %DEVICE%. Für Telegram muss beispielsweise %DEVICE%:@%%msgPeerId%% gesetzt werden, damit die Antworten ankommen&lt;br /&gt;
&lt;br /&gt;
=== Wie legt man nun Dialoge an? ===&lt;br /&gt;
Dazu empfehle ich einmal durch das Tutorial ab den &amp;quot;First Steps&amp;quot; zu gehen und sich die Beispieldatei FHEM/TALKTOME.rive.template zu Gemüte zu führen. Diese bietet schon so kleinigkeiten wie &amp;quot;Wie heisst du&amp;quot; als Fragen oder die Frage nach dem Wetter (Geräte eben entsprechend austauschen!) oder den Raumtemperaturen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich:&lt;br /&gt;
Readings lassen sich per &amp;lt;pre&amp;gt;&amp;lt;call&amp;gt;readingsval BK_Wetter fc1_low_c Error&amp;lt;/call&amp;gt;&amp;lt;/pre&amp;gt; auslesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Readings Timestamps lassen sich per &amp;lt;pre&amp;gt;&amp;lt;call&amp;gt;readingstimestamp LR_Wandthermostat temperature Error&amp;lt;/call&amp;gt;&amp;lt;/pre&amp;gt; auslesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Attribute lassen sich per &amp;lt;pre&amp;gt;&amp;lt;call&amp;gt;attrval BK_Wetter fc1_low_c Error&amp;lt;/call&amp;gt;&amp;lt;/pre&amp;gt; auslesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
FHEM Kommandos kann man so ausführen:&amp;lt;pre&amp;gt; &amp;lt;call&amp;gt;fhem set KU_SWITCH_COFFEE_Sw on&amp;lt;/call&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Perl Methoden/Funktionen kann man so ausführen: &amp;lt;pre&amp;gt;&amp;lt;call&amp;gt;perl chatbot_beispielfunktion&amp;lt;/call&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Was ist derzeit noch ToDo? ===&lt;br /&gt;
* Unterscheidung von Messages aus verschiedenen Quellen mit den entsprechenden Usern (siehe oben) - derzeit geht alles über ein TALKTOUSER Gerät&lt;br /&gt;
* evtl. Integration mit ROOMMATE&lt;br /&gt;
* Überarbeitung der Dokumentation&lt;br /&gt;
* Unterstützung von audio als Rückkanal&lt;br /&gt;
* Angabe von Verzeichnissen anstelle einzelner rive-Datei&lt;br /&gt;
&lt;br /&gt;
=== Umgesetzte Projekte ===&lt;br /&gt;
&lt;br /&gt;
==== Beleuchtungssteuerung mit Telegram ====&lt;br /&gt;
&lt;br /&gt;
===== Ziel =====&lt;br /&gt;
&lt;br /&gt;
Über Telegram soll es möglich sein, die Beleuchtung im Haus ein und auszuschalten.&lt;br /&gt;
&lt;br /&gt;
===== Ausgangssituation =====&lt;br /&gt;
&lt;br /&gt;
Bei mir haben die meisten Geräte im FHEM das Namensschema&lt;br /&gt;
&lt;br /&gt;
ET.ra.FU.Beschreibung&lt;br /&gt;
&lt;br /&gt;
wobei&lt;br /&gt;
&lt;br /&gt;
ET = Kürzel für Etage&lt;br /&gt;
ra = Kürzel für Raum&lt;br /&gt;
FU = Kürzel für Funktion&lt;br /&gt;
&lt;br /&gt;
So ist zum Beispiel die Lampe im Esszimmer über dem Esstisch OG.ez.LI.Esstisch.&lt;br /&gt;
&lt;br /&gt;
===== Umsetzung =====&lt;br /&gt;
&lt;br /&gt;
Zunächst wird ein Menü gebaut, welches als Antwort auf die Nachricht &amp;quot;Hauptmenü&amp;quot; über Telegram gesendet wird:&lt;br /&gt;
&lt;br /&gt;
.rive-Datei:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
! sub hauptmenü = hauptmenue&lt;br /&gt;
&lt;br /&gt;
+ [*] (abbrechen|hauptmenue) [*]&lt;br /&gt;
- Hauptmenü:&lt;br /&gt;
^ /Licht_Aus&lt;br /&gt;
^ /Licht_An&lt;br /&gt;
&lt;br /&gt;
+ leave&lt;br /&gt;
- Untermenü verlassen \n \s \n {@ hauptmenue}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;/&amp;quot; vor den einzelnen Menüpunkten sorgen dafür, dass diese im Telegram direkt anklickbar sind.&lt;br /&gt;
&lt;br /&gt;
Als nächstes werden zwei subs in der myUtils benötigt, um alle ein- bzw. ausgeschalteten Lampen zu ermitteln und als Antwort für Telegram zu formatieren:&lt;br /&gt;
&lt;br /&gt;
99_myUtils.pm:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
sub&lt;br /&gt;
chatBot_getLightsOn&lt;br /&gt;
{&lt;br /&gt;
  my @lights = devspec2array(&#039;.*\.LI\..*:FILTER=state!=off:FILTER=TYPE!=DOIF:FILTER=TYPE!=notify:FILTER=TYPE!=readingsProxy&#039;);;&lt;br /&gt;
  my $msg = &amp;quot;Es sind folgende Lichter eingeschaltet:\n \n&amp;quot;;;&lt;br /&gt;
  my $room = &amp;quot;&amp;quot;;&lt;br /&gt;
  &lt;br /&gt;
  if (@lights &amp;gt; 0 and defined($defs{$lights[0]})){&lt;br /&gt;
    foreach (@lights){&lt;br /&gt;
      if ($room ne AttrVal($_, &amp;quot;room&amp;quot;, $_))&lt;br /&gt;
      {&lt;br /&gt;
        if ($room ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $msg .= &amp;quot; \n/&amp;quot;.$room.&amp;quot;_Aus \n&amp;quot;; &lt;br /&gt;
        }&lt;br /&gt;
        $room = AttrVal($_, &amp;quot;room&amp;quot;, $_);&lt;br /&gt;
        $msg .= &amp;quot; \n&amp;quot;.$room.&amp;quot;: \n&amp;quot;; &lt;br /&gt;
      }&lt;br /&gt;
      $_ =~ s/\./__/g;&lt;br /&gt;
      $msg .= &amp;quot;/&amp;quot;.$_.&amp;quot; \n&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    if ($room ne &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
      $msg .= &amp;quot; \n/&amp;quot;.$room.&amp;quot;_Aus \n&amp;quot;; &lt;br /&gt;
    }&lt;br /&gt;
    $msg .= &amp;quot; \n/Alle_Aus&lt;br /&gt;
             \n \n/Hauptmenue&lt;br /&gt;
            &amp;quot;;;&lt;br /&gt;
  }else{&lt;br /&gt;
    $msg = &amp;quot;Es sind alle Lichter ausgeschaltet.&amp;quot;;;&lt;br /&gt;
    $msg .= &amp;quot;\n/Hauptmenue&lt;br /&gt;
            &amp;quot;;;&lt;br /&gt;
  }&lt;br /&gt;
  return $msg;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sub&lt;br /&gt;
chatBot_getLightsOff&lt;br /&gt;
{&lt;br /&gt;
  my @lights = devspec2array(&#039;.*\.LI\..*:FILTER=state!=on:FILTER=TYPE!=DOIF:FILTER=TYPE!=notify:FILTER=TYPE!=readingsProxy&#039;);;&lt;br /&gt;
  my $msg = &amp;quot;Es sind folgende Lichter ausgeschaltet:\n \n&amp;quot;;;&lt;br /&gt;
  my $room = &amp;quot;&amp;quot;;&lt;br /&gt;
  &lt;br /&gt;
  if (@lights &amp;gt; 0 and defined($defs{$lights[0]})){&lt;br /&gt;
    foreach (@lights){&lt;br /&gt;
      if ($room ne AttrVal($_, &amp;quot;room&amp;quot;, $_))&lt;br /&gt;
      {&lt;br /&gt;
        if ($room ne &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
          $msg .= &amp;quot; \n/&amp;quot;.$room.&amp;quot;_Ein \n&amp;quot;; &lt;br /&gt;
        }&lt;br /&gt;
        $room = AttrVal($_, &amp;quot;room&amp;quot;, $_);&lt;br /&gt;
        $msg .= &amp;quot; \n&amp;quot;.$room.&amp;quot;: \n&amp;quot;; &lt;br /&gt;
      }&lt;br /&gt;
      $_ =~ s/\./__/g;&lt;br /&gt;
      $msg .= &amp;quot;/&amp;quot;.$_.&amp;quot; \n&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    if ($room ne &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
      $msg .= &amp;quot; \n/&amp;quot;.$room.&amp;quot;_Ein \n&amp;quot;; &lt;br /&gt;
    }&lt;br /&gt;
    $msg .= &amp;quot; \n/Alle_Ein&lt;br /&gt;
             \n \n/Hauptmenue&lt;br /&gt;
            &amp;quot;;;&lt;br /&gt;
  }else{&lt;br /&gt;
    $msg = &amp;quot;Es sind alle Lichter eingeschaltet.&amp;quot;;;&lt;br /&gt;
    $msg .= &amp;quot;\n/Hauptmenue&lt;br /&gt;
            &amp;quot;;;&lt;br /&gt;
  }&lt;br /&gt;
  return $msg;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Formatierung für Telegram erfolgt, indem die . durch __ ersetzt werden und ein / vorangestellt wird, damit es im Telegram anklickbar wird.&lt;br /&gt;
&lt;br /&gt;
Nun folge die Logik für RiveScript. Zunächst die Abfrage für die Auflistung der ein- bzw. ausgeschalteten Lampen (inklusive notwendiger Definitionen):&lt;br /&gt;
&lt;br /&gt;
.rive-Datei:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
! array levels  = eg og dg au&lt;br /&gt;
! array rooms   = ku ez ba fk sp ks wz bu sz&lt;br /&gt;
! array spacer  = __ _&lt;br /&gt;
&lt;br /&gt;
+ licht(@spacer)aus&lt;br /&gt;
- &amp;lt;call&amp;gt;perl chatBot_getLightsOn&amp;lt;/call&amp;gt;{topic=licht_aus}&lt;br /&gt;
&lt;br /&gt;
+ licht(@spacer)an&lt;br /&gt;
- &amp;lt;call&amp;gt;perl chatBot_getLightsOff&amp;lt;/call&amp;gt;{topic=licht_an}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anschließend die Schaltfunktionen:&lt;br /&gt;
&lt;br /&gt;
.rive-Datei:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt; topic licht_aus&lt;br /&gt;
&lt;br /&gt;
  + [*] (abbrechen|hauptmenue) [*]&lt;br /&gt;
  - {topic=random} {@ leave}&lt;br /&gt;
&lt;br /&gt;
  + (@levels)(@spacer)(@rooms)(@spacer)li(@spacer)(*)(@spacer)(*) &lt;br /&gt;
  - &amp;lt;set licht={uppercase}&amp;lt;star1&amp;gt;{/uppercase}.&amp;lt;star3&amp;gt;.LI.{formal}&amp;lt;star6&amp;gt;{/formal}_{formal}&amp;lt;star9&amp;gt;{/formal}&amp;gt;&lt;br /&gt;
  ^ Schalte Licht &amp;lt;get licht&amp;gt; aus \n &lt;br /&gt;
  ^ /Hauptmenue&lt;br /&gt;
  ^ &amp;lt;call&amp;gt;fhem set &amp;lt;get licht&amp;gt; off&amp;lt;/call&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  + (@levels)(@spacer)(@rooms)(@spacer)li(@spacer)(*) &lt;br /&gt;
  - &amp;lt;set licht={uppercase}&amp;lt;star1&amp;gt;{/uppercase}.&amp;lt;star3&amp;gt;.LI.{formal}&amp;lt;star6&amp;gt;{/formal}&amp;gt;&lt;br /&gt;
  ^ Schalte Licht &amp;lt;get licht&amp;gt; aus \n &lt;br /&gt;
  ^ /Hauptmenue&lt;br /&gt;
  ^ &amp;lt;call&amp;gt;fhem set &amp;lt;get licht&amp;gt; off&amp;lt;/call&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  + alle(@spacer)aus&lt;br /&gt;
  - Schalte alle Lichter aus \n&lt;br /&gt;
  ^ /Hauptmenue &lt;br /&gt;
  ^ &amp;lt;call&amp;gt;fhem set .*\.LI\..*:FILTER=state!=off:FILTER=TYPE!=DOIF:FILTER=TYPE!=notify:FILTER=TYPE!=readingsProxy off&amp;lt;/call&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  + (*)(@spacer)(*)(@spacer)aus&lt;br /&gt;
  - &amp;lt;set room={formal}&amp;lt;star1&amp;gt;{/formal}_{formal}&amp;lt;star4&amp;gt;{/formal}&amp;gt;&lt;br /&gt;
  ^ Schalte Licht in &amp;lt;get room&amp;gt; aus \n &lt;br /&gt;
  ^ /Hauptmenue&lt;br /&gt;
  ^ &amp;lt;call&amp;gt;fhem set .*\.LI\..*:FILTER=state!=off:FILTER=TYPE!=DOIF:FILTER=TYPE!=notify:FILTER=TYPE!=readingsProxy:FILTER=room=&amp;lt;get room&amp;gt; off&amp;lt;/call&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  + (*)(@spacer)aus&lt;br /&gt;
  - &amp;lt;set room={formal}&amp;lt;star1&amp;gt;{/formal}&amp;gt;&lt;br /&gt;
  ^ Schalte Licht in &amp;lt;get room&amp;gt; aus \n &lt;br /&gt;
  ^ /Hauptmenue&lt;br /&gt;
  ^ &amp;lt;call&amp;gt;fhem set .*\.LI\..*:FILTER=state!=off:FILTER=TYPE!=DOIF:FILTER=TYPE!=notify:FILTER=TYPE!=readingsProxy:FILTER=room=&amp;lt;get room&amp;gt; off&amp;lt;/call&amp;gt;  &lt;br /&gt;
  &lt;br /&gt;
&amp;lt; topic&lt;br /&gt;
&lt;br /&gt;
&amp;gt; topic licht_an&lt;br /&gt;
&lt;br /&gt;
  + [*] (abbrechen|hauptmenue) [*]&lt;br /&gt;
  - {topic=random} {@ leave}&lt;br /&gt;
&lt;br /&gt;
  + (@levels)(@spacer)(@rooms)(@spacer)li(@spacer)(*)(@spacer)(*) &lt;br /&gt;
  - &amp;lt;set licht={uppercase}&amp;lt;star1&amp;gt;{/uppercase}.&amp;lt;star3&amp;gt;.LI.{formal}&amp;lt;star6&amp;gt;{/formal}_{formal}&amp;lt;star9&amp;gt;{/formal}&amp;gt;&lt;br /&gt;
  ^ Schalte Licht &amp;lt;get licht&amp;gt; ein \n&lt;br /&gt;
  ^ /Hauptmenue&lt;br /&gt;
  ^ &amp;lt;call&amp;gt;fhem set &amp;lt;get licht&amp;gt; on&amp;lt;/call&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  + (@levels)(@spacer)(@rooms)(@spacer)li(@spacer)(*) &lt;br /&gt;
  - &amp;lt;set licht={uppercase}&amp;lt;star1&amp;gt;{/uppercase}.&amp;lt;star3&amp;gt;.LI.{formal}&amp;lt;star6&amp;gt;{/formal}&amp;gt;&lt;br /&gt;
  ^ Schalte Licht &amp;lt;get licht&amp;gt; ein \n&lt;br /&gt;
  ^ /Hauptmenue&lt;br /&gt;
  ^ &amp;lt;call&amp;gt;fhem set &amp;lt;get licht&amp;gt; on&amp;lt;/call&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  + alle(@spacer)ein&lt;br /&gt;
  - Schalte alle Lichter ein \n&lt;br /&gt;
  ^ /Hauptmenue &lt;br /&gt;
  ^ &amp;lt;call&amp;gt;fhem set .*\.LI\..*:FILTER=state!=on:FILTER=TYPE!=DOIF:FILTER=TYPE!=notify:FILTER=TYPE!=readingsProxy on&amp;lt;/call&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  + (*)(@spacer)(*)(@spacer)ein&lt;br /&gt;
  - &amp;lt;set room={formal}&amp;lt;star1&amp;gt;{/formal}_{formal}&amp;lt;star4&amp;gt;{/formal}&amp;gt;&lt;br /&gt;
  ^ Schalte Licht in &amp;lt;get room&amp;gt; ein \n&lt;br /&gt;
  ^ /Hauptmenue &lt;br /&gt;
  ^ &amp;lt;call&amp;gt;fhem set .*\.LI\..*:FILTER=state!=on:FILTER=TYPE!=DOIF:FILTER=TYPE!=notify:FILTER=TYPE!=readingsProxy:FILTER=room=&amp;lt;get room&amp;gt; on&amp;lt;/call&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  + (*)(@spacer)ein&lt;br /&gt;
  - &amp;lt;set room={formal}&amp;lt;star1&amp;gt;{/formal}&amp;gt;&lt;br /&gt;
  ^ Schalte Licht in &amp;lt;get room&amp;gt; ein \n&lt;br /&gt;
  ^ /Hauptmenue &lt;br /&gt;
  ^ &amp;lt;call&amp;gt;fhem set .*\.LI\..*:FILTER=state!=on:FILTER=TYPE!=DOIF:FILTER=TYPE!=notify:FILTER=TYPE!=readingsProxy:FILTER=room=&amp;lt;get room&amp;gt; on&amp;lt;/call&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&amp;lt; topic&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein möglicher Dialog mit FHEM sähe dann wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
Benutzer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hauptmenü&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FHEM:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hauptmenü:&lt;br /&gt;
/Licht_Aus&lt;br /&gt;
/Licht_An&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/Licht_An&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FHEM:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Es sind folgende Lichter ausgeschaltet:&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Aussenwelt: &lt;br /&gt;
/AU__ho__LI__Markise &lt;br /&gt;
/AU__ho__LI__Terrasse &lt;br /&gt;
 &lt;br /&gt;
/Aussenwelt_Ein &lt;br /&gt;
 &lt;br /&gt;
Buero: &lt;br /&gt;
/DG__bu__LI__Flur &lt;br /&gt;
/DG__bu__LI__Schornstein &lt;br /&gt;
/DG__bu__LI__Schreibtisch &lt;br /&gt;
 &lt;br /&gt;
/Buero_Ein &lt;br /&gt;
 &lt;br /&gt;
Schlafzimmer: &lt;br /&gt;
/DG__sz__LI__Hinten_Halogen &lt;br /&gt;
/DG__sz__LI__Hinten_Led &lt;br /&gt;
/DG__sz__LI__Kleiderschrank &lt;br /&gt;
/DG__sz__LI__Vorn &lt;br /&gt;
 &lt;br /&gt;
/Schlafzimmer_Ein &lt;br /&gt;
 &lt;br /&gt;
Wohnzimmer: &lt;br /&gt;
/DG__wz__LI__Allgemein &lt;br /&gt;
 &lt;br /&gt;
/Wohnzimmer_Ein &lt;br /&gt;
 &lt;br /&gt;
Esszimmer: &lt;br /&gt;
/OG__ez__LI__Allgemein &lt;br /&gt;
/OG__ez__LI__Bogen &lt;br /&gt;
/OG__ez__LI__Esstisch &lt;br /&gt;
/OG__ez__LI__Vitrine &lt;br /&gt;
 &lt;br /&gt;
/Esszimmer_Ein &lt;br /&gt;
 &lt;br /&gt;
Flur_Kinder: &lt;br /&gt;
/OG__fk__LI__Allgemein &lt;br /&gt;
 &lt;br /&gt;
/Flur_Kinder_Ein &lt;br /&gt;
 &lt;br /&gt;
Hausflur: &lt;br /&gt;
/OG__hf__LI__Schuhschrank &lt;br /&gt;
/OG__hf__LI__Treppe &lt;br /&gt;
 &lt;br /&gt;
/Hausflur_Ein &lt;br /&gt;
 &lt;br /&gt;
Kinderschlafzimmer: &lt;br /&gt;
/OG__ks__LI__Allgemein &lt;br /&gt;
/OG__ks__LI__Bett &lt;br /&gt;
/OG__ks__LI__Sterne &lt;br /&gt;
 &lt;br /&gt;
/Kinderschlafzimmer_Ein &lt;br /&gt;
 &lt;br /&gt;
Kueche: &lt;br /&gt;
/OG__ku__LI__Besenschrank &lt;br /&gt;
/OG__ku__LI__Kuechenzeile &lt;br /&gt;
/OG__ku__LI__Kuehlschrank &lt;br /&gt;
/OG__ku__LI__Theke &lt;br /&gt;
 &lt;br /&gt;
/Kueche_Ein &lt;br /&gt;
 &lt;br /&gt;
Spielzimmer_Kinder: &lt;br /&gt;
/OG__sp__LI__Baggerheck_Schreibtisch &lt;br /&gt;
/OG__sp__LI__Baggerschaufel_Podest &lt;br /&gt;
 &lt;br /&gt;
/Spielzimmer_Kinder_Ein &lt;br /&gt;
 &lt;br /&gt;
Treppe: &lt;br /&gt;
/OG__tr__LI__Handlauf_Fenster &lt;br /&gt;
 &lt;br /&gt;
/Treppe_Ein &lt;br /&gt;
 &lt;br /&gt;
/Alle_Ein&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
/Hauptmenue&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/OG__ku__LI__Kuechenzeile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FHEM:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Schalte Licht OG.ku.LI.Kuechenzeile ein&lt;br /&gt;
/Hauptmenue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/OG__ku__LI__Kuechenschrank&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FHEM:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Schalte Licht OG.ku.LI.Kuechenschrank ein &lt;br /&gt;
/Hauptmenue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/Hauptmenue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FHEM:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Untermenü verlassen &lt;br /&gt;
 &lt;br /&gt;
 Hauptmenü:&lt;br /&gt;
/Licht_Aus&lt;br /&gt;
/Licht_An&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/Licht_Aus&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FHEM:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Es sind folgende Lichter eingeschaltet:&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Kueche: &lt;br /&gt;
/OG__ku__LI__Kuechenschrank &lt;br /&gt;
/OG__ku__LI__Kuechenzeile &lt;br /&gt;
 &lt;br /&gt;
/Kueche_Aus &lt;br /&gt;
&lt;br /&gt;
/Alle_Aus&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
/Hauptmenue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Benutzer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/Kueche_Aus&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FHEM:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Schalte Licht in Kueche aus &lt;br /&gt;
 /Hauptmenue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Beleuchtungssteuerung über Sprache ====&lt;br /&gt;
&lt;br /&gt;
Die Module können nicht nur eingesetzt werden, um mittels Telegram zu kommunizieren. Ein weiteres Beispiel ist der Einsatz als Spracherkennung für gesprochene Befehle über z.B. [[AMAD]]. Hier ist allerdings zum jetzigen Zeitpunkt noch keine gesprochene Antwort möglich und das Zieldevice für die Antwort kann nur hardcodiert hinterlegt werden.&lt;br /&gt;
&lt;br /&gt;
Zunächst müssen in der AMADCommBridge die notwendigen Attribute gesetzt werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attr AMADCommBridge userattr talktouserMonitorReading talktouserModSourceDev &lt;br /&gt;
attr AMADCommBridge talktouserModSourceDev HandyRonny &lt;br /&gt;
attr AMADCommBridge talktouserMonitorReading receiveVoiceCommand &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun muss noch die Logik für RiveScript hinterlegt werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Aus den gesprochenen Räumen werden die Kürzel ermittelt&lt;br /&gt;
! person badezimmer = OG.ba.&lt;br /&gt;
! person buero = DG.bu.&lt;br /&gt;
! person esszimmer = OG.ez.&lt;br /&gt;
! person flur_kinder = OG.fk.&lt;br /&gt;
! person hausflur = OG.hf.&lt;br /&gt;
! person kinderschlafzimmer = OG.ks.&lt;br /&gt;
! person kueche = OG.ku.&lt;br /&gt;
! person schlafzimmer = DG.sz.&lt;br /&gt;
! person spielzimmer_kinder = OG.sp.&lt;br /&gt;
! person treppe = OG.tr.&lt;br /&gt;
! person unten_kueche = EG.uk.&lt;br /&gt;
! person unten_stube = EG.st.&lt;br /&gt;
! person waschhaus = EG.wh.&lt;br /&gt;
! person wohnzimmer = DG.wz.&lt;br /&gt;
&lt;br /&gt;
// Aus den gesprochenen Befehlen werden die FHEM Befehle ermittelt&lt;br /&gt;
! person ein = on&lt;br /&gt;
! person an = on&lt;br /&gt;
! person aus = off&lt;br /&gt;
&lt;br /&gt;
// einige Ersetzungen, um nicht immer den konkreten Begriff verwenden zu müssen&lt;br /&gt;
! sub büro = buero&lt;br /&gt;
! sub küche = kueche&lt;br /&gt;
! sub bad = badezimmer&lt;br /&gt;
! sub flur kinder = flur_kinder&lt;br /&gt;
! sub kinderflur = flur_kinder&lt;br /&gt;
! sub spielzimmer kinder = spielzimmer_kinder&lt;br /&gt;
! sub spielzimmer = spielzimmer_kinder&lt;br /&gt;
! sub kinderspielzimmer = spielzimmer_kinder&lt;br /&gt;
! sub kinderzimmer = spielzimmer_kinder&lt;br /&gt;
! sub kueche unten = unten_kueche&lt;br /&gt;
// Die Deckenlampe heißt meistens Allgemein&lt;br /&gt;
! sub decke = allgemein&lt;br /&gt;
&lt;br /&gt;
// Ersetzungen, um einen anderen Satzbau zu erlauben&lt;br /&gt;
! sub einschalten = ein&lt;br /&gt;
! sub anschalten = an&lt;br /&gt;
! sub anmachen = an&lt;br /&gt;
! sub ausmachen = aus&lt;br /&gt;
! sub ausschalten = aus&lt;br /&gt;
&lt;br /&gt;
/*****************************************************************************\&lt;br /&gt;
 * Lichtsteuerung per Sprache                                                *&lt;br /&gt;
\*****************************************************************************/&lt;br /&gt;
! array schaltenaliaseinschalten		= an|ein&lt;br /&gt;
! array schaltenaliasausschalten		= aus&lt;br /&gt;
! array schaltenaliashandlung   		= an|ein|aus&lt;br /&gt;
! array schaltenaliasartikel			  = der|die|das&lt;br /&gt;
! array schaltenaliasfuellwoerter		= schalte|mach&lt;br /&gt;
! array schaltenaliasorte				    = in|am|auf|an|im|auf dem&lt;br /&gt;
! array schaltenaliashoeflich 	    = bitte&lt;br /&gt;
! array roomsfull                   = badezimmer|buero|esszimmer|flur_kinder|hausflur|kinderschlafzimmer|kueche|schlafzimmer|spielzimmer_kinder|treppe|unten_kueche|unten_stube|waschhaus|wohnzimmer&lt;br /&gt;
&lt;br /&gt;
// einzelnes Licht ein- bzw. ausschalten&lt;br /&gt;
// Bsp: [Bitte] schalte das Licht im Wohnzimmer an der Decke (ein|aus)&lt;br /&gt;
+ [@schaltenaliashoeflich] [@schaltenaliasfuellwoerter] [@schaltenaliashoeflich] [@schaltenaliasartikel] licht [@schaltenaliasorte] [@schaltenaliasartikel] (@roomsfull) [@schaltenaliasorte] [@schaltenaliasartikel] _ (@schaltenaliashandlung)&lt;br /&gt;
- &amp;lt;set lightroom={person}&amp;lt;star1&amp;gt;{/person}LI.&amp;gt;&lt;br /&gt;
^ &amp;lt;set lightname={formal}&amp;lt;star2&amp;gt;{/formal}&amp;gt;&lt;br /&gt;
^ Licht &amp;lt;get lightroom&amp;gt;&amp;lt;get lightname&amp;gt; wird &amp;lt;star3&amp;gt;geschaltet&lt;br /&gt;
^ &amp;lt;call&amp;gt;fhem set &amp;lt;get lightroom&amp;gt;.*&amp;lt;get lightname&amp;gt;.* {person}&amp;lt;star3&amp;gt;{/person}&amp;lt;/call&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// einzelnes Licht ein- bzw. ausschalten - anderer Satzbau&lt;br /&gt;
// Bsp: [Bitte] schalte das Licht an der Decke im Wohnzimmer (ein|aus)&lt;br /&gt;
+ [@schaltenaliashoeflich] [@schaltenaliasfuellwoerter] [@schaltenaliashoeflich] [@schaltenaliasartikel] licht [@schaltenaliasorte] [@schaltenaliasartikel] _ [@schaltenaliasorte] (@roomsfull) (@schaltenaliashandlung)&lt;br /&gt;
- &amp;lt;set lightroom={person}&amp;lt;star2&amp;gt;{/person}LI.&amp;gt;&lt;br /&gt;
^ &amp;lt;set lightname={formal}&amp;lt;star1&amp;gt;{/formal}&amp;gt;&lt;br /&gt;
^ Licht &amp;lt;get lightroom&amp;gt;&amp;lt;get lightname&amp;gt; wird &amp;lt;star3&amp;gt;geschaltet&lt;br /&gt;
^ &amp;lt;call&amp;gt;fhem set &amp;lt;get lightroom&amp;gt;.*&amp;lt;get lightname&amp;gt;.* {person}&amp;lt;star3&amp;gt;{/person}&amp;lt;/call&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// einzelnes Licht mit zweiteiligem Namen ein- bzw. ausschalten&lt;br /&gt;
// Bsp: [Bitte] schalte das Licht im Schlafzimmer hinten halogen (ein|aus)&lt;br /&gt;
+ [@schaltenaliashoeflich] [@schaltenaliasfuellwoerter] [@schaltenaliashoeflich] [@schaltenaliasartikel] licht [@schaltenaliasorte] [@schaltenaliasartikel] zwei worte _ _ [@schaltenaliasorte] (@roomsfull) (@schaltenaliashandlung)&lt;br /&gt;
- &amp;lt;set lightroom={person}&amp;lt;star3&amp;gt;{/person}LI.&amp;gt;&lt;br /&gt;
^ &amp;lt;set lightname={formal}&amp;lt;star1&amp;gt;{/formal}_{formal}&amp;lt;star2&amp;gt;{/formal}&amp;gt;&lt;br /&gt;
^ Licht &amp;lt;get lightroom&amp;gt;&amp;lt;get lightname&amp;gt; wird &amp;lt;star4&amp;gt;geschaltet&lt;br /&gt;
^ &amp;lt;call&amp;gt;fhem set &amp;lt;get lightroom&amp;gt;.*&amp;lt;get lightname&amp;gt;.* {person}&amp;lt;star4&amp;gt;{/person}&amp;lt;/call&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Licht in einem Zimmer ein- bzw. ausschalten&lt;br /&gt;
// Bsp: [Bitte] schalte das Licht im Schlafzimmer (ein|aus)&lt;br /&gt;
+ [@schaltenaliashoeflich] [@schaltenaliasfuellwoerter] [@schaltenaliashoeflich] [@schaltenaliasartikel] licht [@schaltenaliasorte] [@schaltenaliasartikel] (@roomsfull) (@schaltenaliashandlung)&lt;br /&gt;
- &amp;lt;set light={person}&amp;lt;star1&amp;gt;{/person}LI.&amp;gt;&lt;br /&gt;
^ Licht {formal}&amp;lt;star1&amp;gt;{/formal} wird &amp;lt;star2&amp;gt;geschaltet&lt;br /&gt;
^ &amp;lt;call&amp;gt;fhem set &amp;lt;get light&amp;gt;.* {person}&amp;lt;star2&amp;gt;{/person}&amp;lt;/call&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kann sind zum Beispiel für die Lampe am Küchenschrank folgende Sprachbefehle möglich (Begriffe in eckigen Klammen, wie z.B. [bitte] sind optional; durch | getrennte Begriffe in Klammern stellen Alternativen dar):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[bitte] [schalte|mache] [das] Licht [in] [der] Küche [am] Küchenschrank (an|ein|aus)&lt;br /&gt;
[schalte|mache] [bitte] [das] Licht [in] [der] Küche [am] Küchenschrank (an|ein|aus)&lt;br /&gt;
[bitte] [schalte|mache] [das] Licht [am] Küchenschrank [in] [der] Küche (an|ein|aus)&lt;br /&gt;
[schalte|mache] [bitte] [das] Licht [am] Küchenschrank [in] [der] Küche (an|ein|aus)&lt;br /&gt;
[bitte] [das] Licht [am] Küchenschrank [in] [der] Küche (an|ein|aus)[schalten|machen]&lt;br /&gt;
[bitte] [das] Licht [in] [der] Küche [am] Küchenschrank (an|ein|aus)[schalten|machen]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wird die konkrete Lampe weggelassen, so wird das Licht im gesamten Raum ein-/ausgeschaltet:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[bitte] [schalte|mache] [das] Licht [in] [der] Küche (an|ein|aus)&lt;br /&gt;
[schalte|mache] [bitte] [das] Licht [in] [der] Küche (an|ein|aus)&lt;br /&gt;
[bitte] [das] Licht [in] [der] Küche (an|ein|aus)[schalten|machen]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da ich auch Lampen habe, deren Beschreibung aus zwei durch _ getrennten Begriffen besteht (z.B. OG.sp.LI.Baggerschaufel_Podest ist die vordere Glühbirne einer Baggerlampe, welche ein Podest beleuchtet), habe ich zwei Möglichkeiten eingebaut, diese zu schalten:&lt;br /&gt;
&lt;br /&gt;
1. Ankündigung, dass es sich um einen Begriff mit zwei Worten handelt:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[bitte] [schalte|mache] [das] Licht [im] Küche [an] [der] zwei Worte Baggerschaufel Podest (an|ein|aus)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(weitere Alternativen zum Satzbau wie oben)&lt;br /&gt;
&lt;br /&gt;
2. Die Beschreibung wird beim schalten generell zwischen zwei &amp;quot;.*&amp;quot; gesetzt, so dass alle Devices geschaltet werden, auf welche die Beschreibung zutrifft. Dadurch führen auch die folgenden Befehle (in allen oben beschriebenen Satzbauvarianten) zum Erfolg:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[bitte] [schalte|mache] [das] Licht [im] Küche [am] Podest (an|ein|aus)&lt;br /&gt;
[bitte] [schalte|mache] [das] Licht [im] Küche [an] [der] Baggerschaufel (an|ein|aus)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch ist zu beachten, dass z.B. bei den beiden Lampen DG.sz.LI.Hinten_Led und DG.sz.LI.Hinten_Halogen mit&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[bitte] [schalte|mache] [das] Licht [im] Schlafzimmer hinten (an|ein|aus)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
beide Lampen geschaltet werden und mit&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[bitte] [schalte|mache] [das] Licht [im] Schlafzimmer Halogen (an|ein|aus)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
nur eine der beiden.&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* Forumsartikel [https://forum.fhem.de/index.php/topic,54863.0.html Module: TALKTOME &amp;amp; TALKTOUSER - Sprachverarbeitung für Nutzerinteraktionen]&lt;br /&gt;
* Forumsartikel [https://forum.fhem.de/index.php/topic,39983.0.html Neuer FHEM Befehl &amp;quot;msg&amp;quot; für Benachrichtigungen]&lt;br /&gt;
* RiveScript [https://www.rivescript.com/docs/tutorial#first-steps First steps]&lt;br /&gt;
* Modul [[AMAD]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Examples]]&lt;br /&gt;
[[Category:HOWTOS]]&lt;br /&gt;
[[Category:Code Snippets]]&lt;br /&gt;
[[Categorie:Interfaces]]&lt;/div&gt;</summary>
		<author><name>RoBra81</name></author>
	</entry>
	<entry>
		<id>http://wiki.fhem.de/w/index.php?title=TALKTOME_%26_TALKTOUSER_-_Sprachverarbeitung_f%C3%BCr_Nutzerinteraktionen&amp;diff=15793</id>
		<title>TALKTOME &amp; TALKTOUSER - Sprachverarbeitung für Nutzerinteraktionen</title>
		<link rel="alternate" type="text/html" href="http://wiki.fhem.de/w/index.php?title=TALKTOME_%26_TALKTOUSER_-_Sprachverarbeitung_f%C3%BCr_Nutzerinteraktionen&amp;diff=15793"/>
		<updated>2016-07-05T13:57:23Z</updated>

		<summary type="html">&lt;p&gt;RoBra81: Die Seite wurde neu angelegt: „{{Infobox Modul|...}} Mit Hilfe der Module TALKTOME &amp;amp; TALKTOUSER und der Sprache RiveScript ist es möglich, Chatbots - bekannt von Webseiten wie IKEA und co -…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Modul|...}}&lt;br /&gt;
Mit Hilfe der Module TALKTOME &amp;amp; TALKTOUSER und der Sprache RiveScript ist es möglich, Chatbots - bekannt von Webseiten wie IKEA und co - für FHEM einzusetzen, um Frage-Antwort-Dialoge zu bauen.&lt;br /&gt;
&lt;br /&gt;
== Features / Funktionen ==&lt;br /&gt;
Die Haupteigenschaften von XYZ sind&lt;br /&gt;
* Anbindung von RiveScript an fhem&lt;br /&gt;
* Abruf von Readings, ReadingTimestamps, Attributen&lt;br /&gt;
* Absetzen von fhem Befehlen oder Aufruf von perl Funktionen&lt;br /&gt;
&lt;br /&gt;
== Hinweise zum Betrieb mit FHEM ==&lt;br /&gt;
=== Voraussetzungen ===&lt;br /&gt;
Die Einrichtung von msg - das macht mir das Antworten in die diversen Kanäle sehr viel einfacher.&lt;br /&gt;
&lt;br /&gt;
Installation von RiveScript in der Version 2.0.1 (oder neuer, falls eine erscheinen sollte) via CPAN. ACHTUNG nicht via apt-get installieren, da die Version zu alt ist.&lt;br /&gt;
&lt;br /&gt;
==== msg ====&lt;br /&gt;
Bei der ersten Verwendung des Befehls &amp;quot;msg&amp;quot; wird ein Device namens globalMsg angelegt, was man aber dem Modul vorweg nehmen kann:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define globalMsg msgConfig&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit sind die Voraussetzungen schon geschaffen&lt;br /&gt;
&lt;br /&gt;
==== Installation von RiveScript ====&lt;br /&gt;
Rufe cpan auf:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cpan&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das sieht dann etwa so aus:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo cpan&lt;br /&gt;
Loading internal null logger. Install Log::Log4perl for logging messages&lt;br /&gt;
Terminal does not support AddHistory.&lt;br /&gt;
&lt;br /&gt;
cpan shell -- CPAN exploration and modules installation (v2.10)&lt;br /&gt;
Enter &#039;h&#039; for help.&lt;br /&gt;
&lt;br /&gt;
cpan[1]&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installiere dann Rivescript mit Hilfe des folgenden Kommandos:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
install RiveScript&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls Fragen aufkommen, ob man Abhängigkeiten folgen soll, dann bitte richtig beantworten (yes) ;)&lt;br /&gt;
&lt;br /&gt;
=== Installation der Module ===&lt;br /&gt;
Geht wie immer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
update all https://raw.githubusercontent.com/SirUli/FHEM-TALKTO/master/controls_talkto.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anschließend sollte man im Ordner FHEM drei zusätzliche Files (42_TALKTOME.pm, 42_TALKTOUSER.pm sowie TALKTOME.rive.template) finden. Letzteres benennt man nun um in TALKTOME.rive. An dieser Stelle darf man das File natürlich auch schon editieren - wenn man möchte und Rivescript versteht.&lt;br /&gt;
&lt;br /&gt;
==== Definition ====&lt;br /&gt;
Dann geht es los mit der Definition des Chatbots an sich:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define FHEMTALKTOME TALKTOME&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FHEMTALKTOME ist sozusagen nun der Bot, welcher zu Beginn noch deaktiviert ist. Bevor man diesen aktiviert, muss man den Pfad zum TALKTOME.rive File setzen. Ist dieses file im Ordner FHEM (sozusagen also wie Auslieferungszustand und oben beschrieben), so setzt man folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
attr FHEMTALKTOME rsbrainfile ./FHEM/TALKTOME.rive&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann kann man das Attribut &amp;quot;disable&amp;quot; entfernen. Für die Nutzerinteraktion kann man noch weitere Details eines Nutzer anlegen (derzeit nur den &amp;quot;richtigen&amp;quot; Namen), daher brauchen wir ein Benutzermodul, also z.B. für mich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define TALKTOUSER_ULI TALKTOUSER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bitte noch nicht wundern - derzeit ist das noch nicht voll ausgebaut, besser ihr legt erstmal nur ein Benutzergerät an.&lt;br /&gt;
&lt;br /&gt;
Nun kommt der wichtigste Teil - die Einbindung einer Quelle. Bei mir ist das nun Telegram, welches nun zwei zusätzliche Attribute via userAttr bekommen muss:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
talktouserMonitorReading talktouserModSourceDev&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Was heissen die Attribute?&lt;br /&gt;
&lt;br /&gt;
talktouserMonitorReading: Bezeichnet das Reading welches überwacht werden soll, im falle von Telegram ist dies auf &amp;quot;msgText&amp;quot; zu setzen&lt;br /&gt;
talktouserModSourceDev: Lässt eine Änderung des Quell Devices zu. So muss beispielsweise für Telegram, damit eine Antwort machbar ist, das Quelldevice verändert werden. Lokale Readings (also vom Quellverzeichnis) werden mit %%readingname%% angegeben, das device selbst ist %DEVICE%. Für Telegram muss beispielsweise %DEVICE%:@%%msgPeerId%% gesetzt werden, damit die Antworten ankommen&lt;br /&gt;
&lt;br /&gt;
=== Wie legt man nun Dialoge an? ===&lt;br /&gt;
Dazu empfehle ich einmal durch das Tutorial ab den &amp;quot;First Steps&amp;quot; zu gehen und sich die Beispieldatei FHEM/TALKTOME.rive.template zu Gemüte zu führen. Diese bietet schon so kleinigkeiten wie &amp;quot;Wie heisst du&amp;quot; als Fragen oder die Frage nach dem Wetter (Geräte eben entsprechend austauschen!) oder den Raumtemperaturen.&amp;lt;br&amp;gt;&lt;br /&gt;
Zusätzlich:&lt;br /&gt;
Readings lassen sich per &amp;lt;pre&amp;gt;&amp;lt;call&amp;gt;readingsval BK_Wetter fc1_low_c Error&amp;lt;/call&amp;gt;&amp;lt;/pre&amp;gt; auslesen&amp;lt;br&amp;gt;&lt;br /&gt;
Readings Timestamps lassen sich per &amp;lt;pre&amp;gt;&amp;lt;call&amp;gt;readingstimestamp LR_Wandthermostat temperature Error&amp;lt;/call&amp;gt;&amp;lt;/pre&amp;gt; auslesen&amp;lt;br&amp;gt;&lt;br /&gt;
Attribute lassen sich per &amp;lt;pre&amp;gt;&amp;lt;call&amp;gt;attrval BK_Wetter fc1_low_c Error&amp;lt;/call&amp;gt;&amp;lt;/pre&amp;gt; auslesen&amp;lt;br&amp;gt;&lt;br /&gt;
FHEM Kommandos kann man so ausführen:&amp;lt;pre&amp;gt; &amp;lt;call&amp;gt;fhem set KU_SWITCH_COFFEE_Sw on&amp;lt;/call&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Perl Methoden/Funktionen kann man so ausführen: &amp;lt;pre&amp;gt;&amp;lt;call&amp;gt;perl chatbot_beispielfunktion&amp;lt;/call&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Was ist derzeit noch ToDo? ===&lt;br /&gt;
Unterscheidung von Messages aus verschiedenen Quellen mit den entsprechenden Usern (siehe oben) - derzeit geht alles über ein TALKTOUSER Gerät&lt;br /&gt;
evtl. Integration mit ROOMMATE&lt;br /&gt;
Überarbeitung der Dokumentation&lt;br /&gt;
&lt;br /&gt;
=== Umgesetzte Projekte ===&lt;br /&gt;
Folgen zeitnah&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* Forumsartikel [https://forum.fhem.de/index.php/topic,54863.0.html Module: TALKTOME &amp;amp; TALKTOUSER - Sprachverarbeitung für Nutzerinteraktionen]&lt;br /&gt;
* Forumsartikel [https://forum.fhem.de/index.php/topic,39983.0.html Neuer FHEM Befehl &amp;quot;msg&amp;quot; für Benachrichtigungen]&lt;br /&gt;
* RiveScript [https://www.rivescript.com/docs/tutorial#first-steps First steps]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:XYZ Gerät]]&lt;/div&gt;</summary>
		<author><name>RoBra81</name></author>
	</entry>
</feed>