76_msgDialog.pm 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292
  1. # Id ##########################################################################
  2. # $Id: 76_msgDialog.pm 16814 2018-06-04 03:30:08Z igami $
  3. # copyright ###################################################################
  4. #
  5. # 76_msgDialog.pm
  6. #
  7. # Copyright by igami
  8. #
  9. # This file is part of FHEM.
  10. #
  11. # FHEM is free software: you can redistribute it and/or modify
  12. # it under the terms of the GNU General Public License as published by
  13. # the Free Software Foundation, either version 2 of the License, or
  14. # (at your option) any later version.
  15. #
  16. # FHEM is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. # GNU General Public License for more details.
  20. #
  21. # You should have received a copy of the GNU General Public License
  22. # along with FHEM. If not, see <http://www.gnu.org/licenses/>.
  23. # packages ####################################################################
  24. package main;
  25. use strict;
  26. use warnings;
  27. # variables ###################################################################
  28. my $msgDialog_devspec = "TYPE=(ROOMMATE|GUEST):FILTER=msgContactPush=.+";
  29. # forward declarations ########################################################
  30. sub msgDialog_Initialize($);
  31. sub msgDialog_Define($$);
  32. sub msgDialog_Set($@);
  33. sub msgDialog_Get($@);
  34. sub msgDialog_Notify($$);
  35. sub msgDialog_progress($$$;$);
  36. sub msgDialog_reset($);
  37. sub msgDialog_evalSpecials($$);
  38. sub msgDialog_updateAllowed;
  39. # initialize ##################################################################
  40. sub msgDialog_Initialize($) {
  41. my ($hash) = @_;
  42. my $TYPE = "msgDialog";
  43. $hash->{DefFn} = "$TYPE\_Define";
  44. $hash->{SetFn} = "$TYPE\_Set";
  45. $hash->{GetFn} = "$TYPE\_Get";
  46. $hash->{AttrFn} = "$TYPE\_Attr";
  47. $hash->{NotifyFn} = "$TYPE\_Notify";
  48. $hash->{AttrList} =
  49. "allowed:multiple-strict,everyone ".
  50. "disable:0,1 ".
  51. "disabledForIntervals ".
  52. "evalSpecials:textField-long ".
  53. "msgCommand ".
  54. $readingFnAttributes
  55. ;
  56. }
  57. # regular Fn ##################################################################
  58. sub msgDialog_Define($$) {
  59. my ($hash, $def) = @_;
  60. my ($SELF, $TYPE, $DEF) = split(/[\s]+/, $def, 3);
  61. my $rc = eval{
  62. require JSON;
  63. JSON->import();
  64. 1;
  65. };
  66. return(
  67. "Error loading JSON. Maybe this module is not installed? ".
  68. "\nUnder debian (based) system it can be installed using ".
  69. "\"apt-get install libjson-perl\""
  70. ) unless($rc);
  71. return(
  72. "No global configuration device defined: ".
  73. "Please define a msgConfig device first"
  74. ) unless($modules{msgConfig}{defptr});
  75. my $msgConfig = $modules{msgConfig}{defptr}{NAME};
  76. addToDevAttrList($msgConfig, "$TYPE\_evalSpecials:textField-long ");
  77. addToDevAttrList($msgConfig, "$TYPE\_msgCommand:textField ");
  78. $DEF = msgDialog_evalSpecials($hash, $DEF);
  79. $DEF = eval{JSON->new->decode($DEF)};
  80. if($@){
  81. Log3($SELF, 2, "$TYPE ($SELF) - DEF is not a valid JSON: $@");
  82. return("Usage: define <name> $TYPE {JSON}\n\n$@");
  83. }
  84. my @TRIGGER;
  85. foreach (keys(%{$DEF})){
  86. next if(defined($DEF->{$_}{setOnly}));
  87. push(@TRIGGER, $_);
  88. }
  89. $hash->{TRIGGER} = join(",", @TRIGGER);
  90. $hash->{NOTIFYDEV} = "TYPE=(ROOMMATE|GUEST)";
  91. msgDialog_update_msgCommand($hash);
  92. msgDialog_reset($hash);
  93. msgDialog_updateAllowed();
  94. return;
  95. }
  96. sub msgDialog_Set($@) {
  97. my ($hash, @a) = @_;
  98. my $TYPE = $hash->{TYPE};
  99. return "\"set $TYPE\" needs at least one argument" if(@a < 2);
  100. my $SELF = shift @a;
  101. my $argument = shift @a;
  102. my $value = join(" ", @a) if (@a);
  103. my %sets = (
  104. "reset" => "reset:noArg",
  105. "say" => "say:textField",
  106. "updateAllowed" => "updateAllowed:noArg"
  107. );
  108. Log3($SELF, 5, "$TYPE ($SELF) - entering msgDialog_Set");
  109. return(
  110. "Unknown argument $argument, choose one of ".join(" ", values %sets)
  111. ) unless(exists($sets{$argument}));
  112. if($argument eq "reset"){
  113. msgDialog_reset($hash);
  114. }
  115. elsif($argument eq "updateAllowed"){
  116. msgDialog_updateAllowed();
  117. }
  118. return if(IsDisabled($SELF));
  119. if($argument eq "say" && $value){
  120. my $recipients = join(",", ($value =~ m/@(\S+)\s+/g));
  121. $recipients = AttrVal($SELF, "allowed", "") unless($recipients);
  122. my (undef, $say) = ($value =~ m/(^|\s)([^@].+)/g);
  123. return unless($recipients || $say);
  124. msgDialog_progress($hash, $recipients, $say, 1);
  125. }
  126. return;
  127. }
  128. sub msgDialog_Get($@) {
  129. my ($hash, @a) = @_;
  130. my $TYPE = $hash->{TYPE};
  131. return "\"get $TYPE\" needs at least one argument" if(@a < 2);
  132. my $SELF = shift @a;
  133. my $argument = shift @a;
  134. my $value = join(" ", @a) if (@a);
  135. my %gets = (
  136. "trigger" => "trigger:noArg"
  137. );
  138. Log3($SELF, 5, "$TYPE ($SELF) - entering msgDialog_Get");
  139. return(
  140. "Unknown argument $argument, choose one of ".join(" ", values %gets)
  141. ) unless(exists($gets{$argument}));
  142. return if(IsDisabled($SELF));
  143. if($argument eq "trigger"){
  144. return(join("\n", split(",", InternalVal($SELF, "TRIGGER", undef))));
  145. }
  146. return;
  147. }
  148. sub msgDialog_Attr(@) {
  149. my ($cmd, $SELF, $attribute, $value) = @_;
  150. my ($hash) = $defs{$SELF};
  151. my $TYPE = $hash->{TYPE};
  152. Log3($SELF, 5, "$TYPE ($SELF) - entering msgDialog_Attr");
  153. if($attribute eq "disable"){
  154. if($cmd eq "set" and $value == 1){
  155. readingsSingleUpdate($hash, "state", "Initialized", 1);
  156. }
  157. else{
  158. readingsSingleUpdate($hash, "state", "disabled", 1);
  159. }
  160. }
  161. elsif($attribute eq "msgCommand"){
  162. if($cmd eq "set"){
  163. $attr{$SELF}{$attribute} = $value;
  164. }
  165. else{
  166. delete($attr{$SELF}{$attribute});
  167. }
  168. msgDialog_update_msgCommand($hash);
  169. }
  170. return;
  171. }
  172. sub msgDialog_Notify($$) {
  173. my ($hash, $dev_hash) = @_;
  174. my $SELF = $hash->{NAME};
  175. my $TYPE = $hash->{TYPE};
  176. my $device = $dev_hash->{NAME};
  177. Log3($SELF, 5, "$TYPE ($SELF) - entering msgDialog_Notify");
  178. return if(IsDisabled($SELF));
  179. my @events = @{deviceEvents($dev_hash, 1)};
  180. return unless(
  181. @events && AttrVal($SELF, "allowed", "") =~ m/(^|,)($device|everyone)(,|$)/
  182. );
  183. foreach my $event (@events){
  184. next unless($event =~ m/(fhemMsgPushReceived|fhemMsgRcvPush): (.+)/);
  185. Log3($SELF, 4 , "$TYPE ($SELF) triggered by \"$device $event\"");
  186. msgDialog_progress($hash, $device, $2);
  187. }
  188. return;
  189. }
  190. # module Fn ###################################################################
  191. sub msgDialog_evalSpecials($$) {
  192. my ($hash, $string) = @_;
  193. my $SELF = $hash->{NAME};
  194. my $TYPE = $hash->{TYPE};
  195. Log3($SELF, 5, "$TYPE ($SELF) - entering msgDialog_evalSpecials");
  196. my $msgConfig = $modules{msgConfig}{defptr}{NAME}
  197. if($modules{msgConfig}{defptr});
  198. $string =~ s/\$SELF/$SELF/g;
  199. my $evalSpecials =
  200. AttrVal($msgConfig, "$TYPE\_evalSpecials", "").
  201. " ".
  202. AttrVal($SELF, "evalSpecials", "")
  203. ;
  204. return($string) if($evalSpecials eq " ");
  205. (undef, $evalSpecials) = parseParams($evalSpecials, "\\s", " ");
  206. return($string) unless($evalSpecials);
  207. foreach(keys(%{$evalSpecials})){
  208. $evalSpecials->{$_} = eval $evalSpecials->{$_}
  209. if($evalSpecials->{$_} =~ m/^{.*}$/);
  210. }
  211. my $specials = join("|", keys(%{$evalSpecials}));
  212. $string =~ s/%($specials)%/$evalSpecials->{$1}/g;
  213. return($string);
  214. }
  215. sub msgDialog_progress($$$;$) {
  216. my ($hash, $recipients, $message, $force) = @_;
  217. my $SELF = $hash->{NAME};
  218. my $TYPE = $hash->{TYPE};
  219. $recipients = join(",", devspec2array($msgDialog_devspec))
  220. if($recipients eq "everyone");
  221. return unless($recipients);
  222. Log3(
  223. $SELF, 5 , "$TYPE ($SELF)"
  224. . "\n entering msgDialog_progress"
  225. . "\n recipients: $recipients"
  226. . "\n message: $message"
  227. . "\n force: ".($force ? $force : 0)
  228. );
  229. my @oldHistory;
  230. @oldHistory = split("\\|", ReadingsVal($SELF, "$recipients\_history", ""))
  231. unless($force);
  232. push(@oldHistory, split("\\|", $message));
  233. my (@history);
  234. my $dialog =$hash->{DEF};
  235. $dialog = msgDialog_evalSpecials($hash, $dialog);
  236. $dialog =~ s/\$recipient/$recipients/g;
  237. $dialog = eval{JSON->new->decode($dialog)};
  238. foreach (@oldHistory){
  239. $message = $_;
  240. if(defined($dialog->{$message})){
  241. $dialog = $dialog->{$message};
  242. push(@history, $message);
  243. }
  244. else{
  245. foreach (keys(%{$dialog})){
  246. next unless(
  247. $dialog->{$_} =~ m/HASH/ &&
  248. defined($dialog->{$_}{match}) &&
  249. $message =~ m/^$dialog->{$_}{match}$/
  250. );
  251. $dialog = $dialog->{$_};
  252. push(@history, $_);
  253. last;
  254. }
  255. }
  256. }
  257. return if(@history != @oldHistory || !$force && $dialog->{setOnly});
  258. $dialog = eval{JSON->new->encode($dialog)};
  259. $dialog =~ s/\$message/$message/g;
  260. $dialog = eval{JSON->new->decode($dialog)};
  261. my $history = "";
  262. foreach (keys(%{$dialog})){
  263. if($_ !~ m/(setOnly|match|commands|message)/){
  264. $history = join("|", @history);
  265. last;
  266. }
  267. }
  268. readingsBeginUpdate($hash);
  269. readingsBulkUpdate($hash, $_."_history", $history)
  270. foreach (split(",", $recipients));
  271. readingsBulkUpdate($hash, "state", "$recipients: $message");
  272. readingsEndUpdate($hash, 1);
  273. if($dialog->{commands}){
  274. my @commands =
  275. $dialog->{commands} =~ m/ARRAY/ ?
  276. @{$dialog->{commands}}
  277. : $dialog->{commands}
  278. ;
  279. foreach (@commands){
  280. $_ =~ s/;/;;/g if($_ =~ m/^{.*}$/s);
  281. my $ret = AnalyzeCommandChain(undef, $_);
  282. Log3($SELF, 4, "$TYPE ($SELF) - return from command \"$_\": $ret")
  283. if($ret);
  284. }
  285. }
  286. if($dialog->{message}){
  287. my @message =
  288. $dialog->{message} =~ m/ARRAY/ ?
  289. @{$dialog->{message}}
  290. : $dialog->{message}
  291. ;
  292. foreach (@message){
  293. if($_ =~ m/^{.*}$/s){
  294. $_ =~ s/;/;;/g;
  295. $_ = AnalyzePerlCommand(undef, $_);
  296. }
  297. }
  298. my $message = join("\n", @message);
  299. my $msgCommand = '"'.InternalVal($SELF, "MSGCOMMAND", "").'"';
  300. $msgCommand = eval($msgCommand);
  301. fhem($msgCommand);
  302. }
  303. return;
  304. }
  305. sub msgDialog_reset($) {
  306. my ($hash) = @_;
  307. my $SELF = $hash->{NAME};
  308. my $TYPE = $hash->{TYPE};
  309. Log3($SELF, 5, "$TYPE ($SELF) - entering msgDialog_reset");
  310. delete($hash->{READINGS});
  311. readingsSingleUpdate($hash, "state", "Initialized", 1)
  312. unless(IsDisabled($SELF));
  313. return;
  314. }
  315. sub msgDialog_updateAllowed {
  316. Log(5, "msgDialog - entering msgDialog_updateAllowed");
  317. my $allowed = join(",", sort(devspec2array($msgDialog_devspec)));
  318. $modules{msgDialog}{AttrList} =~
  319. s/allowed:multiple-strict,\S*/allowed:multiple-strict,everyone,$allowed/;
  320. }
  321. sub msgDialog_update_msgCommand($) {
  322. my ($hash) = @_;
  323. my $SELF = $hash->{NAME};
  324. my $TYPE = $hash->{TYPE};
  325. my $msgConfig = $modules{msgConfig}{defptr}{NAME};
  326. Log3($SELF, 5, "$TYPE ($SELF) - entering msgDialog_update_msgCommand");
  327. $hash->{MSGCOMMAND} =
  328. AttrVal($SELF, "msgCommand",
  329. AttrVal($msgConfig, "$TYPE\_msgCommand",
  330. 'msg push \@$recipients $message'
  331. )
  332. )
  333. ;
  334. return;
  335. }
  336. 1;
  337. # commandref ##################################################################
  338. =pod
  339. =item helper
  340. =item summary dialogs for instant messaging
  341. =item summary_DE Dialoge f&uuml;r Sofortnachrichten
  342. =begin html
  343. <a name="msgDialog"></a>
  344. <h3>msgDialog</h3>
  345. <ul>
  346. With msgDialog you can define dialogs for instant messages via TelegramBot, Jabber and yowsup (WhatsApp).<br>
  347. The communication uses the msg command. Therefore, a device of type msgConfig must be defined first.<br>
  348. For each dialog you can define which person is authorized to do so. Devices of the type ROOMMATE or GUEST with a defined msgContactPush attribute are required for this. Make sure that the reading fhemMsgRcvPush generates an event.<br>
  349. <br>
  350. Prerequisites:
  351. <ul>
  352. The Perl module "JSON" is required.<br>
  353. Under Debian (based) system, this can be installed using
  354. <code>"apt-get install libjson-perl"</code>.
  355. </ul>
  356. <br>
  357. <a name="msgDialogdefine"></a>
  358. <b>Define</b>
  359. <ul>
  360. <code>define &lt;name&gt; msgDialog &lt;JSON&gt;</code><br>
  361. Because of the complexity, it is easiest to define an empty dialog first.
  362. <code>define &lt;name&gt; msgDialog {}</code>
  363. Then edit the DEF in the detail view.
  364. <PRE>
  365. {
  366. "&lt;TRIGGER&gt;": {
  367. "match": "&lt;regex&gt;",
  368. "setOnly": (true|false),
  369. "commands": "(fhem command|{perl code})",
  370. "message": [
  371. "{perl code}",
  372. "text"
  373. ],
  374. "&lt;NEXT TRIGGER 1&gt;": {
  375. ...
  376. },
  377. "&lt;NEXT TRIGGER 2&gt;": {
  378. ...
  379. }
  380. }
  381. }
  382. </PRE>
  383. <li>
  384. <code>TRIGGER</code><br>
  385. Can be any text. The device checks whether the incoming message equals it. If so, the dialogue will be continued at this point.
  386. </li>
  387. <br>
  388. <li>
  389. <code>match</code><br>
  390. If you do not want to allow only one message, you can specify a regex. The regex must apply to the whole incoming message.
  391. </li>
  392. <br>
  393. <li>
  394. <code>setOnly</code><br>
  395. Can be optionally set to true or false. In both cases, the TRIGGER will
  396. not be returned at "get &lt;name&gt; trigger".<br>
  397. If setOnly is set to true, the dialog at this point cannot be triggered
  398. by incoming messages, but only by using "set &lt;name&gt; say
  399. TRIGGER".<br>
  400. This can be used to initiate a dialog from FHEM.
  401. </li>
  402. <br>
  403. <li>
  404. <code>commands</code><br>
  405. Can contain a single or multiple commands:
  406. <PRE>
  407. "commands": "single command"
  408. "commands": [
  409. "command 1",
  410. "command 2",
  411. "{perl command}"
  412. ]
  413. </PRE>
  414. </li>
  415. <li>
  416. <code>message</code><br>
  417. Can contain a single or multiple text that is connected by a line break:
  418. <PRE>
  419. "message": "text"
  420. "message": [
  421. "text 1",
  422. "text 2",
  423. "{return from perl command}"
  424. ]
  425. </PRE>
  426. </li>
  427. For multi-level dialogs, this structure is specified nested.<br>
  428. <br>
  429. Variables and placeholders defined under the attribute evalSpecials are
  430. evaluated.<br>
  431. Variables:
  432. <li>
  433. <code>$SELF</code><br>
  434. name of the msgDialog
  435. </li>
  436. <br>
  437. <li>
  438. <code>$message</code><br>
  439. received message
  440. </li>
  441. <br>
  442. <li>
  443. <code>$recipient</code><br>
  444. Name of the dialog partner
  445. </li>
  446. </ul>
  447. <br>
  448. <a name="msgDialogset"></a>
  449. <b>Set</b>
  450. <ul>
  451. <li>
  452. <code>reset</code><br>
  453. Resets the dialog for all users.
  454. </li>
  455. <br>
  456. <li>
  457. <code>
  458. say [@&lt;recipient1&gt;[,&lt;recipient2&gt;,...]]
  459. &lt;TRIGGER&gt;[|&lt;NEXT TRIGGER&gt;|...]
  460. </code><br>
  461. The dialog is continued for all specified recipients at the specified
  462. position.<br>
  463. If no recipients are specified, the dialog is continued for all
  464. recipients specified under the allowed attribute.
  465. </li>
  466. <br>
  467. <li>
  468. <code>updateAllowed</code><br>
  469. Updates the selection for the allowed attribute.
  470. </li>
  471. </ul>
  472. <br>
  473. <a name="msgDialogget"></a>
  474. <b>Get</b>
  475. <ul>
  476. <li>
  477. <code>trigger</code><br>
  478. Lists all TRIGGERs of the first level where setOnly is not specified.
  479. </li>
  480. </ul>
  481. <br>
  482. <a name="msgDialogattr"></a>
  483. <b>Attribute</b>
  484. <ul>
  485. <li>
  486. <code>allowed</code><br>
  487. List with all RESIDENTS and ROOMMATE that are authorized for this dialog.
  488. </li>
  489. <br>
  490. <li>
  491. <code>disable 1</code><br>
  492. Dialog is deactivated.
  493. </li>
  494. <br>
  495. <li>
  496. <a href="#disabledForIntervals">
  497. <u><code>disabledForIntervals HH:MM-HH:MM HH:MM-HH-MM ...</code></u>
  498. </a>
  499. </li>
  500. <br>
  501. <li>
  502. <code>evalSpecials key1=value1 key2=value2 ...</code><br>
  503. Space Separate list of name=value pairs.<br>
  504. Value may contain spaces if included in "" or {}.<br>
  505. Value is evaluated as a perl expression if it is included in {}.<br>
  506. In the DEF, %Name% strings are replaced by the corresponding value.<br>
  507. This attribute is available as "msgDialog_evalSpecials" in the msgConfig
  508. device.<br>
  509. If the same name was defined in the msgConfig and msgDialog, the value
  510. from msgDialog is used.
  511. </li>
  512. <br>
  513. <li>
  514. <code>msgCommand &lt;command&gt;</code><br>
  515. Command used to send a message.<br>
  516. The default is
  517. <code>"msg push \@$recipients $message"</code>.<br>
  518. This attribute is available as "msgDialog_msgCommand" in the msgConfig device.
  519. </li>
  520. </ul>
  521. <br>
  522. <a name="msgDialogreadings"></a>
  523. <b>Reading</b>
  524. <ul>
  525. <li>
  526. <code>$recipient_history</code><br>
  527. | separated list of TRIGGERS to save the current state of the dialog.<br>
  528. A readings is created for each dialog partner. When the dialog is
  529. finished, the reading will be cleared.
  530. </li>
  531. </ul>
  532. <br>
  533. <a name="msgDialogTelegramBot"></a>
  534. <b>Notes for use with TelegramBot:</b>
  535. <ul>
  536. It may be necessary to set the attribute "utf8specials" to 1 in the
  537. TelegramBot, for messages with special characters to be sent.<br>
  538. <br>
  539. The msg command supports the TelegramBot_MTYPE. The default is message. The
  540. queryInline value can be used to create an inline keyboard.
  541. </ul>
  542. <br>
  543. <a name="msgDialogJabber"></a>
  544. <b>Notes for use with Jabber:</b>
  545. <ul>
  546. The msg command supports the TelegramBot_MTYPE. The default is empty. The
  547. value otr can be used to send an OTR message.
  548. </ul>
  549. <br>
  550. <a name="msgDialogyowsub"></a>
  551. <b>Notes for use with yowsub (WhatsApp):</b>
  552. <ul>
  553. No experiences so far.
  554. </ul>
  555. <br>
  556. <a name="msgDialogexamples"></a>
  557. <b>Examples:</b>
  558. <ul>
  559. <a href="https://wiki.fhem.de/wiki/Import_von_Code_Snippets">
  560. <u>
  561. The following example codes can be imported by "Raw defnition".
  562. </u>
  563. </a>
  564. <br>
  565. <br>
  566. All examples are designed for communication via the TelegramBot. When using
  567. Jabber or yowsup, they may need to be adjusted.<br>
  568. It is assumed that the msgConfig device contains the evalSpecials "me" with
  569. a name which is used to call the bot.<br>
  570. <br>
  571. <b>Meta dialog for listing all authorized dialogs:</b>
  572. <ul>
  573. <PRE>
  574. defmod meta_Dialog msgDialog {\
  575. "%me%": {\
  576. "match": "\/?(start|%me%)",\
  577. "commands": "deletereading TYPE=msgDialog $recipient_history",\
  578. "message": [\
  579. "{return('(' . join(') (', sort(split('\n', fhem('get TYPE=msgDialog:FILTER=NAME!=$SELF:FILTER=allowed=.*($recipient|everyone).* trigger'))), 'abbrechen') . ') ')}",\
  580. "Ich kann folgendes f&uuml;r dich tun:"\
  581. ]\
  582. },\
  583. "zur&uuml;ck": {\
  584. "commands": "set $recipient_history=.+|.+ say @$recipient {(ReadingsVal($DEV, '$recipient_history', '') =~ m/(.+)\\|.+$/;; return $2 ? $2 : $1;;)}"\
  585. },\
  586. "abbrechen": {\
  587. "match": "\/?abbrechen",\
  588. "commands": "deletereading TYPE=msgDialog $recipient_history",\
  589. "message": [\
  590. "TelegramBot_MTYPE=queryInline (%me%) ",\
  591. "Dialog abgebrochen."\
  592. ]\
  593. },\
  594. "beenden": {\
  595. "match": "\/?beenden",\
  596. "commands": "deletereading TYPE=msgDialog $recipient_history",\
  597. "message": [\
  598. "TelegramBot_MTYPE=queryInline (%me%) ",\
  599. "Dialog beendet."\
  600. ]\
  601. }\
  602. }
  603. attr meta_Dialog allowed everyone
  604. </PRE>
  605. </ul>
  606. <b>Request of current fuel prices</b>
  607. <ul>
  608. <PRE>
  609. defmod Tankstelle_Dialog msgDialog {\
  610. "Tankstelle": {\
  611. "message": [\
  612. "TelegramBot_MTYPE=queryInline (%me%) ",\
  613. "Die Krafstoffpreise der betragen aktuell folgende Werte:",\
  614. "",\
  615. "AIVA",\
  616. "",\
  617. "[%AIVA%:Diesel] €/l Diesel",\
  618. "[%AIVA%:Super] €/l Super",\
  619. "[%AIVA%:E10] €/l E10",\
  620. "[%AIVA%:Autogas] €/l Autogas"\
  621. ]\
  622. }\
  623. }
  624. attr Tankstelle_Dialog evalSpecials AIVA=AIVA_petrolStation
  625. </PRE>
  626. </ul>
  627. <b>Programming of the washing machine</b>
  628. <ul>
  629. <PRE>
  630. defmod Waschmaschine_Dialog msgDialog { "Waschmaschine": {\
  631. "message": [\
  632. "{return('(Zeitprogramm stoppen) ') if(ReadingsVal('%controlUnit%', 'controlMode', '') eq 'auto')}",\
  633. "{return('(programmieren) ') if(ReadingsVal('%actor%', 'state', '') ne 'on')}",\
  634. "{return('(einschalten) ') if(ReadingsVal('%actor%', 'state', '') ne 'on')}",\
  635. "(Verlaufsdiagramm) ",\
  636. "(abbrechen) ",\
  637. "{return('Waschmaschine: ' . (ReadingsVal('%actor%', 'state', '') eq 'on' ? 'eingeschaltet' : 'ausgeschaltet'))}",\
  638. "{return('Modus: ' . (ReadingsVal('%controlUnit%', 'controlMode', '') eq 'auto' ? 'Automatik' : 'Manuell (' . ReadingsVal('%controlUnit%', 'time', '') . ')'))}"\
  639. ],\
  640. "Zeitprogramm stoppen": {\
  641. "commands": "set %controlUnit% controlMode manual",\
  642. "message": [\
  643. "TelegramBot_MTYPE=queryInline (%me%) ",\
  644. "Das Zeitprogramm wurde gestoppt."\
  645. ]\
  646. },\
  647. "programmieren": {\
  648. "message": [\
  649. "(best&auml;tigen|zur&uuml;ck|abbrechen) ",\
  650. "( 00:00 | 00:15 | 00:30 | 00:45 ) ",\
  651. "( 01:00 | 01:15 | 01:30 | 01:45 ) ",\
  652. "( 02:00 | 02:15 | 02:30 | 02:45 ) ",\
  653. "( 03:00 | 03:15 | 03:30 | 03:45 ) ",\
  654. "( 04:00 | 04:15 | 04:30 | 04:45 ) ",\
  655. "( 05:00 | 05:15 | 05:30 | 05:45 ) ",\
  656. "( 06:00 | 06:15 | 06:30 | 06:45 ) ",\
  657. "( 07:00 | 07:15 | 07:30 | 07:45 ) ",\
  658. "( 08:00 | 08:15 | 08:30 | 08:45 ) ",\
  659. "( 09:00 | 09:15 | 09:30 | 09:45 ) ",\
  660. "( 10:00 | 10:15 | 10:30 | 10:45 ) ",\
  661. "( 11:00 | 11:15 | 11:30 | 11:45 ) ",\
  662. "( 12:00 | 12:15 | 12:30 | 12:45 ) ",\
  663. "( 13:00 | 13:15 | 13:30 | 13:45 ) ",\
  664. "( 14:00 | 14:15 | 14:30 | 14:45 ) ",\
  665. "( 15:00 | 15:15 | 15:30 | 15:45 ) ",\
  666. "( 16:00 | 16:15 | 16:30 | 16:45 ) ",\
  667. "( 17:00 | 17:15 | 17:30 | 17:45 ) ",\
  668. "( 18:00 | 18:15 | 18:30 | 18:45 ) ",\
  669. "( 19:00 | 19:15 | 19:30 | 19:45 ) ",\
  670. "( 20:00 | 20:15 | 20:30 | 20:45 ) ",\
  671. "( 21:00 | 21:15 | 21:30 | 21:45 ) ",\
  672. "( 22:00 | 22:15 | 22:30 | 22:45 ) ",\
  673. "( 23:00 | 23:15 | 23:30 | 23:45 ) ",\
  674. "Wann soll die W&auml;sche fertig sein?",\
  675. "Bitte Uhrzeit in HH:MM angeben.",\
  676. "Aktuell ist [%controlUnit%:time] Uhr eingestellt."\
  677. ],\
  678. "Uhrzeit": {\
  679. "match": " ?([0-1][0-9]|2[0-3]):[0-5][0-9] ?",\
  680. "commands": [\
  681. "set %controlUnit% time $message",\
  682. "set $SELF say @$recipient Waschmaschine|programmieren|best&auml;tigen"\
  683. ]\
  684. },\
  685. "best&auml;tigen": {\
  686. "commands": "set %controlUnit% controlMode auto",\
  687. "message": [\
  688. "TelegramBot_MTYPE=queryInline (%me%) ",\
  689. "Das Zeitprogramm wurde eingestellt.",\
  690. "Die W&auml;sche wird voraussichtlich um [%controlUnit%:time] Uhr fertig sein.",\
  691. "Bitte die Waschmaschine vorbereiten."\
  692. ]\
  693. }\
  694. },\
  695. "einschalten": {\
  696. "commands": [\
  697. "set %controlUnit% controlMode manual",\
  698. "set %actor% on"\
  699. ]\
  700. },\
  701. "Verlaufsdiagramm": {\
  702. "commands": "set %TelegramBot% cmdSend {plotAsPng('%plot%')}",\
  703. "message": "TelegramBot_MTYPE=queryInline (%me%) $message"\
  704. }\
  705. },\
  706. "auto": {\
  707. "setOnly": true,\
  708. "commands": [\
  709. "set %actor% on",\
  710. "set %controlUnit% controlMode manual"\
  711. ],\
  712. "message": [\
  713. "TelegramBot_MTYPE=queryInline (%me%) ",\
  714. "Die Wachmaschine wurde automatisch eingeschaltet."\
  715. ]\
  716. },\
  717. "manual": {\
  718. "setOnly": true,\
  719. "message": [\
  720. "TelegramBot_MTYPE=queryInline (%me%) ",\
  721. "Die Wachmaschine wurde manuell eingeschaltet."\
  722. ]\
  723. },\
  724. "done": {\
  725. "setOnly": true,\
  726. "commands": "set %actor% off",\
  727. "message": [\
  728. "TelegramBot_MTYPE=queryInline (%me%) ",\
  729. "Die Wachmaschine ist fertig."\
  730. ]\
  731. }\
  732. }
  733. attr Waschmaschine_Dialog evalSpecials actor=HM_2C10D8_Sw\
  734. controlUnit=Waschkeller_washer_controlUnit\
  735. plot=Waschkeller_washer_SVG
  736. </PRE>
  737. </ul>
  738. </ul>
  739. </ul>
  740. =end html
  741. =begin html_DE
  742. <a name="msgDialog"></a>
  743. <h3>msgDialog</h3>
  744. <ul>
  745. Mit msgDialog k&ouml;nnen Dialoge f&uuml;r Sofortnachrichten &uuml;ber
  746. TelegramBot, Jabber und yowsup (WhatsApp) definiert werden.<br>
  747. Die Kommunikation erfolgt &uuml;ber den msg Befehl. Daher muss ein Ger&auml;t
  748. vom Typ msgConfig zuerst definiert werden.<br>
  749. F&uuml;r jeden Dialog kann festgelegt werden welche Person dazu berechtigt
  750. ist. Dazu sind Ger&auml;te vom Typ ROOMMATE oder GUEST mit definiertem
  751. msgContactPush Attribut erforderlich. Es ist darauf zu achten, dass das
  752. Reading fhemMsgRcvPush ein Event erzeugt.<br>
  753. <br>
  754. Vorraussetzungen:
  755. <ul>
  756. Das Perl-Modul "JSON" wird ben&ouml;tigt.<br>
  757. Unter Debian (basierten) System, kann dies mittels
  758. <code>"apt-get install libjson-perl"</code> installiert werden.
  759. </ul>
  760. <br>
  761. <a name="msgDialogdefine"></a>
  762. <b>Define</b>
  763. <ul>
  764. <code>define &lt;name&gt; msgDialog &lt;JSON&gt;</code><br>
  765. Aufgrunder komplexit&auml;t ist es am einfachsten erst einen leeren Dialog
  766. zu definieren.
  767. <code>define &lt;name&gt; msgDialog {}</code>
  768. Anschließend die DEF dann in der Detail-Ansicht bearbeiten.
  769. <PRE>
  770. {
  771. "&lt;TRIGGER&gt;": {
  772. "match": "&lt;regex&gt;",
  773. "setOnly": (true|false),
  774. "commands": "(fhem command|{perl code})",
  775. "message": [
  776. "{perl code}",
  777. "text"
  778. ],
  779. "&lt;NEXT TRIGGER 1&gt;": {
  780. ...
  781. },
  782. "&lt;NEXT TRIGGER 2&gt;": {
  783. ...
  784. }
  785. }
  786. }
  787. </PRE>
  788. <li>
  789. <code>TRIGGER</code><br>
  790. Kann ein beliebiger Text sein. Es wird gepr&uuml;ft ob die eingehende
  791. Nachricht damit &uuml;bereinstimmt. Falls ja, wird der Dialog an dieser
  792. Stelle fortgesetzt.
  793. </li>
  794. <br>
  795. <li>
  796. <code>match</code><br>
  797. Wenn nicht nur genau eine Nachricht zugelassen werden soll, kann noch
  798. eine regex angegeben werden. Die regex muss auf die gesamte eingehnde
  799. Nachricht zutreffen.
  800. </li>
  801. <br>
  802. <li>
  803. <code>setOnly</code><br>
  804. Kann optional auf true oder false gestellt werden. In beiden
  805. f&auml;llen wird der TRIGGER dann nicht bei "get &lt;name&gt; trigger"
  806. zur&uuml;ck gegeben.<br>
  807. Wenn setOnly auf true gestellt wird kann der Dialog an dieser Stelle
  808. nicht durch eingehnde Nachrichten ausgel&ouml;st werden, sondern nur
  809. &uuml;ber "set &lt;name&gt; say TRIGGER".<br>
  810. Dies kann dazu genutzt werden um einen Dialog von FHEM zu aus zu
  811. initieren.
  812. </li>
  813. <br>
  814. <li>
  815. <code>commands</code><br>
  816. Kann einen einzelnen oder mehrere Befehle enthalten:
  817. <PRE>
  818. "commands": "single command"
  819. "commands": [
  820. "command 1",
  821. "command 2",
  822. "{perl command}"
  823. ]
  824. </PRE>
  825. </li>
  826. <li>
  827. <code>message</code><br>
  828. Kann einen einzelnen oder mehrere Textte enthalten die mit einen
  829. Zeilenumbruch verbunden werden:
  830. <PRE>
  831. "message": "text"
  832. "message": [
  833. "text 1",
  834. "text 2",
  835. "{return from perl command}"
  836. ]
  837. </PRE>
  838. </li>
  839. Bei mehrstufigen Dialogen wird diese Struktur ineinander verschachtelt
  840. angegeben.<br>
  841. <br>
  842. Es werden Variablen und unter dem Attribut evalSpecials definierte
  843. Platzhalter ausgewertet.<br>
  844. Variablen:
  845. <li>
  846. <code>$SELF</code><br>
  847. Eigenname des msgDialog
  848. </li>
  849. <br>
  850. <li>
  851. <code>$message</code><br>
  852. eingegangene Nachricht
  853. </li>
  854. <br>
  855. <li>
  856. <code>$recipient</code><br>
  857. Name des Dialogpartners
  858. </li>
  859. </ul>
  860. <br>
  861. <a name="msgDialogset"></a>
  862. <b>Set</b>
  863. <ul>
  864. <li>
  865. <code>reset</code><br>
  866. Setzt den Dialog f&uuml;r alle Benutzer zur&uuml;ck.
  867. </li>
  868. <br>
  869. <li>
  870. <code>
  871. say [@&lt;recipient1&gt;[,&lt;recipient2&gt;,...]]
  872. &lt;TRIGGER&gt;[|&lt;NEXT TRIGGER&gt;|...]
  873. </code><br>
  874. Der Dialog wird f&uuml;r alle angegeben Emp&auml;nger an der angegeben
  875. Stelle fortgef&uuml;hrt.<br>
  876. Sind keine Empf&auml;nger angegeben wird der Dialog f&uuml;r alle unter
  877. dem Attribut allowed angegebenen Empf&auml;nger fortgef&uuml;hrt.
  878. </li>
  879. <br>
  880. <li>
  881. <code>updateAllowed</code><br>
  882. Aktualisiert die Auswahl f&uuml;r das Attribut allowed.
  883. </li>
  884. </ul>
  885. <br>
  886. <a name="msgDialogget"></a>
  887. <b>Get</b>
  888. <ul>
  889. <li>
  890. <code>trigger</code><br>
  891. Listet alle TRIGGER der ersten Ebene auf bei denen nicht setOnly
  892. angegeben ist.
  893. </li>
  894. </ul>
  895. <br>
  896. <a name="msgDialogattr"></a>
  897. <b>Attribute</b>
  898. <ul>
  899. <li>
  900. <code>allowed</code><br>
  901. Liste mit allen RESIDENTS und ROOMMATE die f&uuml;r diesen Dialog
  902. berechtigt sind.
  903. </li>
  904. <br>
  905. <li>
  906. <code>disable 1</code><br>
  907. Dialog ist deaktiviert.
  908. </li>
  909. <br>
  910. <li>
  911. <a href="#disabledForIntervals">
  912. <u><code>disabledForIntervals HH:MM-HH:MM HH:MM-HH-MM ...</code></u>
  913. </a>
  914. </li>
  915. <br>
  916. <li>
  917. <code>evalSpecials key1=value1 key2=value2 ...</code><br>
  918. Leerzeichen getrennte Liste von Name=Wert Paaren.<br>
  919. Wert kann Leerzeichen enthalten, falls es in "" oder {} eingeschlossen
  920. ist.<br>
  921. Wert wird als
  922. perl-Ausdruck ausgewertet, falls es in {} eingeschlossen ist.<br>
  923. In der DEF werden %Name% Zeichenketten durch den zugeh&ouml;rigen Wert
  924. ersetzt.<br>
  925. Dieses Attribut ist als "msgDialog_evalSpecials" im msgConfig Gerät
  926. vorhanden.<br>
  927. Wenn der selbe Name im msgConfig und msgDialog definiert wurde, wird der
  928. Wert aus msgDialog verwendet.
  929. </li>
  930. <br>
  931. <li>
  932. <code>msgCommand &lt;command&gt;</code><br>
  933. Befehl der zum Versenden einer Nachricht verwendet wird.<br>
  934. Die Vorgabe ist
  935. <code>"msg push \@$recipients $message"</code><br>
  936. Dieses Attribut ist als "msgDialog_msgCommand" im msgConfig Gerät
  937. vorhanden.
  938. </li>
  939. </ul>
  940. <br>
  941. <a name="msgDialogreadings"></a>
  942. <b>Reading</b>
  943. <ul>
  944. <li>
  945. <code>$recipient_history</code><br>
  946. Durch | getrennte Liste von TRIGGERN um den aktuellen Zustand des Dialogs
  947. zu sichern.<br>
  948. F&uuml;r jeden Dialogpartner wird ein Readings angelegt. Wenn der Dialog
  949. beendet ist wird das Reading zur&uuml;ckgesetzt.
  950. </li>
  951. </ul>
  952. <br>
  953. <a name="msgDialogTelegramBot"></a>
  954. <b>Hinweise zur Benutzung mit Telegram:</b>
  955. <ul>
  956. Es kann notwendig sein, dass im TelegramBot das Attribut "utf8specials" auf
  957. 1 gesetzt wird, damit Nachrichten mit Umlauten gesendert werden.<br>
  958. <br>
  959. Bei dem msg Befehl kann der TelegramBot_MTYPE angegeben werden. Die Vorgabe
  960. ist message. Durch den Wert queryInline lässt sich ein inline Keyboard
  961. erzeugen.
  962. </ul>
  963. <br>
  964. <a name="msgDialogJabber"></a>
  965. <b>Hinweise zur Benutzung mit Jabber:</b>
  966. <ul>
  967. Bei dem msg Befehl kann der Jabber_MTYPE angegeben werden. Die Vorgabe ist
  968. leer. Durch den Wert otr lässt sich eine OTR Nachricht versenden.
  969. </ul>
  970. <br>
  971. <a name="msgDialogyowsub"></a>
  972. <b>Hinweise zur Benutzung mit yowsub (WhatsApp):</b>
  973. <ul>
  974. Bisher noch keine Erfahungen.
  975. </ul>
  976. <br>
  977. <a name="msgDialogexamples"></a>
  978. <b>Beispiele:</b>
  979. <ul>
  980. <a href="https://wiki.fhem.de/wiki/Import_von_Code_Snippets">
  981. <u>
  982. Die folgenden beispiel Codes k&ouml;nnen nur per "Raw defnition"
  983. importiert werden.
  984. </u>
  985. </a>
  986. <br>
  987. <br>
  988. Alle Beispiele sind f&uuml;r die Kommunikation &uuml;ber den TelegramBot
  989. ausgelegt. Bei der Verwendung von Jabber oder yowsup m&uuml;ssen diese
  990. gegebenenfalls angepasst werden.<br>
  991. Es wird davon ausgegangen, dass im msgConfig Ger&auml;t das evalSpecials
  992. "me" mit einem Namen gepflegt ist, &uuml;ber welchen der Bot angesprochen
  993. wird.<br>
  994. <br>
  995. <b>Meta Dialog zur auflistung aller Berechtigten Dialoge:</b>
  996. <ul>
  997. <PRE>
  998. defmod meta_Dialog msgDialog {\
  999. "%me%": {\
  1000. "match": "\/?(start|%me%)",\
  1001. "commands": "deletereading TYPE=msgDialog $recipient_history",\
  1002. "message": [\
  1003. "{return('(' . join(') (', sort(split('\n', fhem('get TYPE=msgDialog:FILTER=NAME!=$SELF:FILTER=allowed=.*($recipient|everyone).* trigger'))), 'abbrechen') . ') ')}",\
  1004. "Ich kann folgendes f&uuml;r dich tun:"\
  1005. ]\
  1006. },\
  1007. "zur&uuml;ck": {\
  1008. "commands": "set $recipient_history=.+|.+ say @$recipient {(ReadingsVal($DEV, '$recipient_history', '') =~ m/(.+)\\|.+$/;; return $2 ? $2 : $1;;)}"\
  1009. },\
  1010. "abbrechen": {\
  1011. "match": "\/?abbrechen",\
  1012. "commands": "deletereading TYPE=msgDialog $recipient_history",\
  1013. "message": [\
  1014. "TelegramBot_MTYPE=queryInline (%me%) ",\
  1015. "Dialog abgebrochen."\
  1016. ]\
  1017. },\
  1018. "beenden": {\
  1019. "match": "\/?beenden",\
  1020. "commands": "deletereading TYPE=msgDialog $recipient_history",\
  1021. "message": [\
  1022. "TelegramBot_MTYPE=queryInline (%me%) ",\
  1023. "Dialog beendet."\
  1024. ]\
  1025. }\
  1026. }
  1027. attr meta_Dialog allowed everyone
  1028. </PRE>
  1029. </ul>
  1030. <b>Abfrage der aktuellen Krafstoffpreise</b>
  1031. <ul>
  1032. <PRE>
  1033. defmod Tankstelle_Dialog msgDialog {\
  1034. "Tankstelle": {\
  1035. "message": [\
  1036. "TelegramBot_MTYPE=queryInline (%me%) ",\
  1037. "Die Krafstoffpreise der betragen aktuell folgende Werte:",\
  1038. "",\
  1039. "AIVA",\
  1040. "",\
  1041. "[%AIVA%:Diesel] €/l Diesel",\
  1042. "[%AIVA%:Super] €/l Super",\
  1043. "[%AIVA%:E10] €/l E10",\
  1044. "[%AIVA%:Autogas] €/l Autogas"\
  1045. ]\
  1046. }\
  1047. }
  1048. attr Tankstelle_Dialog evalSpecials AIVA=AIVA_petrolStation
  1049. </PRE>
  1050. </ul>
  1051. <b>Programmierung der Waschmaschine</b>
  1052. <ul>
  1053. <PRE>
  1054. defmod Waschmaschine_Dialog msgDialog { "Waschmaschine": {\
  1055. "message": [\
  1056. "{return('(Zeitprogramm stoppen) ') if(ReadingsVal('%controlUnit%', 'controlMode', '') eq 'auto')}",\
  1057. "{return('(programmieren) ') if(ReadingsVal('%actor%', 'state', '') ne 'on')}",\
  1058. "{return('(einschalten) ') if(ReadingsVal('%actor%', 'state', '') ne 'on')}",\
  1059. "(Verlaufsdiagramm) ",\
  1060. "(abbrechen) ",\
  1061. "{return('Waschmaschine: ' . (ReadingsVal('%actor%', 'state', '') eq 'on' ? 'eingeschaltet' : 'ausgeschaltet'))}",\
  1062. "{return('Modus: ' . (ReadingsVal('%controlUnit%', 'controlMode', '') eq 'auto' ? 'Automatik' : 'Manuell (' . ReadingsVal('%controlUnit%', 'time', '') . ')'))}"\
  1063. ],\
  1064. "Zeitprogramm stoppen": {\
  1065. "commands": "set %controlUnit% controlMode manual",\
  1066. "message": [\
  1067. "TelegramBot_MTYPE=queryInline (%me%) ",\
  1068. "Das Zeitprogramm wurde gestoppt."\
  1069. ]\
  1070. },\
  1071. "programmieren": {\
  1072. "message": [\
  1073. "(best&auml;tigen|zur&uuml;ck|abbrechen) ",\
  1074. "( 00:00 | 00:15 | 00:30 | 00:45 ) ",\
  1075. "( 01:00 | 01:15 | 01:30 | 01:45 ) ",\
  1076. "( 02:00 | 02:15 | 02:30 | 02:45 ) ",\
  1077. "( 03:00 | 03:15 | 03:30 | 03:45 ) ",\
  1078. "( 04:00 | 04:15 | 04:30 | 04:45 ) ",\
  1079. "( 05:00 | 05:15 | 05:30 | 05:45 ) ",\
  1080. "( 06:00 | 06:15 | 06:30 | 06:45 ) ",\
  1081. "( 07:00 | 07:15 | 07:30 | 07:45 ) ",\
  1082. "( 08:00 | 08:15 | 08:30 | 08:45 ) ",\
  1083. "( 09:00 | 09:15 | 09:30 | 09:45 ) ",\
  1084. "( 10:00 | 10:15 | 10:30 | 10:45 ) ",\
  1085. "( 11:00 | 11:15 | 11:30 | 11:45 ) ",\
  1086. "( 12:00 | 12:15 | 12:30 | 12:45 ) ",\
  1087. "( 13:00 | 13:15 | 13:30 | 13:45 ) ",\
  1088. "( 14:00 | 14:15 | 14:30 | 14:45 ) ",\
  1089. "( 15:00 | 15:15 | 15:30 | 15:45 ) ",\
  1090. "( 16:00 | 16:15 | 16:30 | 16:45 ) ",\
  1091. "( 17:00 | 17:15 | 17:30 | 17:45 ) ",\
  1092. "( 18:00 | 18:15 | 18:30 | 18:45 ) ",\
  1093. "( 19:00 | 19:15 | 19:30 | 19:45 ) ",\
  1094. "( 20:00 | 20:15 | 20:30 | 20:45 ) ",\
  1095. "( 21:00 | 21:15 | 21:30 | 21:45 ) ",\
  1096. "( 22:00 | 22:15 | 22:30 | 22:45 ) ",\
  1097. "( 23:00 | 23:15 | 23:30 | 23:45 ) ",\
  1098. "Wann soll die W&auml;sche fertig sein?",\
  1099. "Bitte Uhrzeit in HH:MM angeben.",\
  1100. "Aktuell ist [%controlUnit%:time] Uhr eingestellt."\
  1101. ],\
  1102. "Uhrzeit": {\
  1103. "match": " ?([0-1][0-9]|2[0-3]):[0-5][0-9] ?",\
  1104. "commands": [\
  1105. "set %controlUnit% time $message",\
  1106. "set $SELF say @$recipient Waschmaschine|programmieren|best&auml;tigen"\
  1107. ]\
  1108. },\
  1109. "best&auml;tigen": {\
  1110. "commands": "set %controlUnit% controlMode auto",\
  1111. "message": [\
  1112. "TelegramBot_MTYPE=queryInline (%me%) ",\
  1113. "Das Zeitprogramm wurde eingestellt.",\
  1114. "Die W&auml;sche wird voraussichtlich um [%controlUnit%:time] Uhr fertig sein.",\
  1115. "Bitte die Waschmaschine vorbereiten."\
  1116. ]\
  1117. }\
  1118. },\
  1119. "einschalten": {\
  1120. "commands": [\
  1121. "set %controlUnit% controlMode manual",\
  1122. "set %actor% on"\
  1123. ]\
  1124. },\
  1125. "Verlaufsdiagramm": {\
  1126. "commands": "set %TelegramBot% cmdSend {plotAsPng('%plot%')}",\
  1127. "message": "TelegramBot_MTYPE=queryInline (%me%) $message"\
  1128. }\
  1129. },\
  1130. "auto": {\
  1131. "setOnly": true,\
  1132. "commands": [\
  1133. "set %actor% on",\
  1134. "set %controlUnit% controlMode manual"\
  1135. ],\
  1136. "message": [\
  1137. "TelegramBot_MTYPE=queryInline (%me%) ",\
  1138. "Die Wachmaschine wurde automatisch eingeschaltet."\
  1139. ]\
  1140. },\
  1141. "manual": {\
  1142. "setOnly": true,\
  1143. "message": [\
  1144. "TelegramBot_MTYPE=queryInline (%me%) ",\
  1145. "Die Wachmaschine wurde manuell eingeschaltet."\
  1146. ]\
  1147. },\
  1148. "done": {\
  1149. "setOnly": true,\
  1150. "commands": "set %actor% off",\
  1151. "message": [\
  1152. "TelegramBot_MTYPE=queryInline (%me%) ",\
  1153. "Die Wachmaschine ist fertig."\
  1154. ]\
  1155. }\
  1156. }
  1157. attr Waschmaschine_Dialog evalSpecials actor=HM_2C10D8_Sw\
  1158. controlUnit=Waschkeller_washer_controlUnit\
  1159. plot=Waschkeller_washer_SVG
  1160. </PRE>
  1161. </ul>
  1162. </ul>
  1163. </ul>
  1164. =end html_DE
  1165. =cut