91_notify.pm 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. ##############################################
  2. # $Id: 91_notify.pm 14888 2017-08-13 12:07:12Z rudolfkoenig $
  3. package main;
  4. use strict;
  5. use warnings;
  6. use vars qw($FW_ME); # webname (default is fhem)
  7. #####################################
  8. sub
  9. notify_Initialize($)
  10. {
  11. my ($hash) = @_;
  12. $hash->{DefFn} = "notify_Define";
  13. $hash->{NotifyFn} = "notify_Exec";
  14. $hash->{AttrFn} = "notify_Attr";
  15. $hash->{AttrList} ="disable:1,0 disabledForIntervals forwardReturnValue:1,0 ".
  16. "readLog:1,0 showtime:1,0 addStateEvent:1,0";
  17. $hash->{SetFn} = "notify_Set";
  18. $hash->{StateFn} = "notify_State";
  19. $hash->{FW_detailFn} = "notify_fhemwebFn";
  20. }
  21. #####################################
  22. sub
  23. notify_Define($$)
  24. {
  25. my ($hash, $def) = @_;
  26. my ($name, $type, $re, $command) = split("[ \t\n]+", $def, 4);
  27. if(!$command) {
  28. if($hash->{OLDDEF}) { # Called from modify, where command is optional
  29. (undef, $command) = split("[ \t]+", $hash->{OLDDEF}, 2);
  30. $hash->{DEF} = "$re $command";
  31. } else {
  32. return "Usage: define <name> notify <regexp> <command>";
  33. }
  34. }
  35. # Checking for misleading regexps
  36. return "Bad regexp: starting with *" if($re =~ m/^\*/);
  37. eval { "Hallo" =~ m/^$re$/ };
  38. return "Bad regexp: $@" if($@);
  39. $hash->{REGEXP} = $re;
  40. my %specials= (
  41. "%NAME" => $name,
  42. "%TYPE" => $name,
  43. "%EVENT" => "1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0",
  44. "%SELF" => $name,
  45. );
  46. my $err = perlSyntaxCheck($command, %specials);
  47. return $err if($err);
  48. $hash->{".COMMAND"} = $command;
  49. my $doTrigger = ($name !~ m/^$re$/); # Forum #34516
  50. readingsSingleUpdate($hash, "state", "active", $doTrigger);
  51. InternalTimer(0, sub(){ notifyRegexpChanged($hash, $re); }, $hash);
  52. return undef;
  53. }
  54. #####################################
  55. sub
  56. notify_Exec($$)
  57. {
  58. my ($ntfy, $dev) = @_;
  59. my $ln = $ntfy->{NAME};
  60. return "" if(IsDisabled($ln));
  61. my $n = $dev->{NAME};
  62. my $re = $ntfy->{REGEXP};
  63. my $events = deviceEvents($dev, AttrVal($ln, "addStateEvent", 0));
  64. return if(!$events); # Some previous notify deleted the array.
  65. my $max = int(@{$events});
  66. my $t = $dev->{TYPE};
  67. my $ret = "";
  68. for (my $i = 0; $i < $max; $i++) {
  69. my $s = $events->[$i];
  70. $s = "" if(!defined($s));
  71. my $found = ($n =~ m/^$re$/ || "$n:$s" =~ m/^$re$/);
  72. if(!$found && AttrVal($n, "eventMap", undef)) {
  73. my @res = ReplaceEventMap($n, [$n,$s], 0);
  74. shift @res;
  75. $s = join(" ", @res);
  76. $found = ("$n:$s" =~ m/^$re$/);
  77. }
  78. if($found) {
  79. Log3 $ln, 5, "Triggering $ln";
  80. my %specials= (
  81. "%NAME" => $n,
  82. "%TYPE" => $t,
  83. "%EVENT" => $s,
  84. "%SELF" => $ln
  85. );
  86. my $exec = EvalSpecials($ntfy->{".COMMAND"}, %specials);
  87. Log3 $ln, 4, "$ln exec $exec";
  88. my $r = AnalyzeCommandChain(undef, $exec);
  89. Log3 $ln, 3, "$ln return value: $r" if($r);
  90. $ret .= " $r" if($r);
  91. $ntfy->{STATE} =
  92. AttrVal($ln,'showtime',1) ? $dev->{NTFY_TRIGGERTIME} : 'active';
  93. }
  94. }
  95. return $ret if(AttrVal($ln, "forwardReturnValue", 0));
  96. return undef;
  97. }
  98. sub
  99. notify_Attr(@)
  100. {
  101. my @a = @_;
  102. my $do = 0;
  103. my $hash = $defs{$a[1]};
  104. if($a[0] eq "set" && $a[2] eq "readLog") {
  105. if(!defined($a[3]) || $a[3]) {
  106. $logInform{$a[1]} = sub($$){
  107. my ($me, $msg) = @_;
  108. return if(defined($hash->{CHANGED}));
  109. $hash->{CHANGED}[0] = $msg;
  110. notify_Exec($hash, $hash);
  111. delete($hash->{CHANGED});
  112. }
  113. } else {
  114. delete $logInform{$a[1]};
  115. }
  116. return;
  117. }
  118. if($a[0] eq "set" && $a[2] eq "disable") {
  119. $do = (!defined($a[3]) || $a[3]) ? 1 : 2;
  120. }
  121. $do = 2 if($a[0] eq "del" && (!$a[2] || $a[2] eq "disable"));
  122. return if(!$do);
  123. readingsSingleUpdate($hash, "state", $do==1 ? "disabled":"active", 1);
  124. return undef;
  125. }
  126. ###################################
  127. sub
  128. notify_Set($@)
  129. {
  130. my ($hash, @a) = @_;
  131. my $me = $hash->{NAME};
  132. return "no set argument specified" if(int(@a) < 2);
  133. my %sets = (addRegexpPart=>2, removeRegexpPart=>1, inactive=>0, active=>0);
  134. my $cmd = $a[1];
  135. if(!defined($sets{$cmd})) {
  136. my $ret ="Unknown argument $cmd, choose one of ".join(" ", sort keys %sets);
  137. $ret =~ s/active/active:noArg/g;
  138. return $ret;
  139. }
  140. return "$cmd needs $sets{$cmd} parameter(s)" if(@a-$sets{$cmd} != 2);
  141. if($cmd eq "addRegexpPart") {
  142. my %h;
  143. my $re = "$a[2]:$a[3]";
  144. map { $h{$_} = 1 } split(/\|/, $hash->{REGEXP});
  145. $h{$re} = 1;
  146. $re = join("|", sort keys %h);
  147. return "Bad regexp: starting with *" if($re =~ m/^\*/);
  148. eval { "Hallo" =~ m/^$re$/ };
  149. return "Bad regexp: $@" if($@);
  150. $hash->{REGEXP} = $re;
  151. $hash->{DEF} = "$re ".$hash->{".COMMAND"};
  152. notifyRegexpChanged($hash, $re);
  153. } elsif($cmd eq "removeRegexpPart") {
  154. my %h;
  155. map { $h{$_} = 1 } split(/\|/, $hash->{REGEXP});
  156. return "Cannot remove regexp part: not found" if(!$h{$a[2]});
  157. return "Cannot remove last regexp part" if(int(keys(%h)) == 1);
  158. delete $h{$a[2]};
  159. my $re = join("|", sort keys %h);
  160. return "Bad regexp: starting with *" if($re =~ m/^\*/);
  161. eval { "Hallo" =~ m/^$re$/ };
  162. return "Bad regexp: $@" if($@);
  163. $hash->{REGEXP} = $re;
  164. $hash->{DEF} = "$re ".$hash->{".COMMAND"};
  165. notifyRegexpChanged($hash, $re);
  166. } elsif($cmd eq "inactive") {
  167. readingsSingleUpdate($hash, "state", "inactive", 1);
  168. }
  169. elsif($cmd eq "active") {
  170. readingsSingleUpdate($hash, "state", "active", 1)
  171. if(!AttrVal($me, "disable", undef));
  172. }
  173. return undef;
  174. }
  175. #############
  176. sub
  177. notify_State($$$$)
  178. {
  179. my ($hash, $tim, $vt, $val) = @_;
  180. return undef if($vt ne "state" || $val ne "inactive");
  181. readingsSingleUpdate($hash, "state", "inactive", 1);
  182. return undef;
  183. }
  184. #########################
  185. sub
  186. notify_fhemwebFn($$$$)
  187. {
  188. my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn.
  189. my $hash = $defs{$d};
  190. my $ret .= "Change wizard<br><table class='block wide'>";
  191. my $row = 0;
  192. my @ra = split(/\|/, $hash->{REGEXP});
  193. $ret .= "<tr class='".(($row++&1)?"odd":"even").
  194. "'><td colspan='2'>Change the condition:</td></tr>";
  195. if(@ra > 1) {
  196. foreach my $r (@ra) {
  197. $ret .= "<tr class='".(($row++&1)?"odd":"even")."'>";
  198. my $cmd = "cmd.X= set $d removeRegexpPart&val.X=$r"; # =.set: avoid JS
  199. $ret .= "<td>$r</td>";
  200. $ret .= FW_pH("$cmd&detail=$d", "removeRegexpPart", 1,undef,1);
  201. $ret .= "</tr>";
  202. }
  203. }
  204. my @et = devspec2array("TYPE=eventTypes");
  205. if(!@et) {
  206. $ret .= "<tr class='".(($row++&1)?"odd":"even")."'>";
  207. $ret .= FW_pH("$FW_ME/docs/commandref.html#eventTypes",
  208. "To add a regexp an eventTypes definition is needed",
  209. 1, undef, 1)."</tr>";
  210. } else {
  211. my %dh;
  212. my $etList = AnalyzeCommand(undef, "get $et[0] list");
  213. $etList = "" if(!$etList);
  214. foreach my $l (split("\n", $etList)) {
  215. my @a = split(/[ \r\n]/, $l);
  216. $a[1] = "" if(!defined($a[1]));
  217. $a[1] =~ s/\.\*//g;
  218. $a[1] =~ s/,.*//g;
  219. next if(@a < 2);
  220. $dh{$a[0]}{".*"} = 1;
  221. $dh{$a[0]}{$a[1].".*"} = 1;
  222. }
  223. my $list = "";
  224. foreach my $dev (sort keys %dh) {
  225. $list .= " $dev:" . join(",", sort keys %{$dh{$dev}});
  226. }
  227. $list =~ s/(['"])/./g;
  228. $ret .= "<tr class=\"".(($row++&1)?"odd":"even")."\">";
  229. $ret .= '<td colspan="2">';
  230. $ret .= FW_detailSelect($d, "set", $list, "addRegexpPart");
  231. $ret .= "</td></tr>";
  232. }
  233. my ($tr, $js) = notfy_addFWCmd($d, $hash->{REGEXP}, $row);
  234. return "$ret$tr</table><br>$js";
  235. }
  236. sub
  237. notfy_addFWCmd($$$)
  238. {
  239. my ($d, $param, $row) = @_;
  240. my $ret="";
  241. $ret .= "<tr class='".(($row++&1)?"odd":"even")."'><td colspan='2'>".
  242. "&nbsp;</td></tr>";
  243. $ret .= "<tr class='".(($row++&1)?"odd":"even")."'><td colspan='2'>".
  244. "Change the executed command:</td></tr>";
  245. $ret .= "<tr class='".(($row++&1)?"odd":"even")."'><td colspan='2'>";
  246. my @list = grep { !$defs{$_}{TEMPORARY} && $_ ne $d &&
  247. $modules{$defs{$_}{TYPE}}{SetFn} } sort keys %defs;
  248. $ret .= "<input class='set' id='modCmd' type='submit' value='modify' ".
  249. "data-d='$d' data-p='$param'>";
  250. $ret .= "<div class='set downText'>&nbsp;$d $param set </div>";
  251. $ret .= FW_select("modDev", "mod", \@list, undef, "set");
  252. $ret .= "<select class='set' id='modArg'></select>";
  253. $ret .= "<input type='text' name='modVal' size='10'/>";
  254. $ret .= "</td></tr>";
  255. my $js = << 'END';
  256. <script>
  257. var ntArr, ntDev;
  258. function
  259. ntfyCmd()
  260. {
  261. ntDev=$("#modDev").val();
  262. FW_cmd(FW_root+
  263. "?cmd="+addcsrf(encodeURIComponent("set "+ntDev+" ?"))+"&XHR=1",
  264. function(ret) {
  265. ret = ret.replace(/[\r\n]/g,'');
  266. ntArr=ret.substr(ret.indexOf("choose one of")+14,ret.length).split(" ");
  267. var str="";
  268. for(var i1=0; i1<ntArr.length; i1++) {
  269. var off = ntArr[i1].indexOf(":");
  270. str += "<option value="+i1+">"+
  271. (off==-1 ? ntArr[i1] : ntArr[i1].substr(0,off))+
  272. "</option>";
  273. }
  274. $("#modArg").html(str);
  275. ntfyArg();
  276. });
  277. }
  278. function
  279. ntfyArg()
  280. {
  281. var v=ntArr[$("#modArg").val()];
  282. var vArr = [];
  283. if(v.indexOf(":") > 0)
  284. vArr = v.substr(v.indexOf(":")+1).split(",");
  285. FW_replaceWidget($("#modArg").next(), ntDev, vArr);
  286. }
  287. function
  288. ntfyGo()
  289. {
  290. var d=$("#modCmd").attr("data-d");
  291. var p=$("#modCmd").attr("data-p");
  292. var cmd = "modify "+d+" "+p+" set "+$("#modDev").val()+" "+
  293. $("#modArg :selected").text()+" "+$("[name=modVal]").val();
  294. location=FW_root+"?cmd="+addcsrf(encodeURIComponent(cmd))+"&detail="+d;
  295. }
  296. $(document).ready(function(){
  297. $("#modDev").change(ntfyCmd);
  298. $("#modArg").change(ntfyArg);
  299. $("#modCmd").click(ntfyGo);
  300. $("#").change(ntfyArg);
  301. ntfyCmd();
  302. });
  303. </script>
  304. END
  305. return ($ret, $js);
  306. }
  307. 1;
  308. =pod
  309. =item helper
  310. =item summary execute a command upon receiving an event
  311. =item summary_DE f&uuml;hrt bei Events Anweisungen aus
  312. =begin html
  313. <a name="notify"></a>
  314. <h3>notify</h3>
  315. <ul>
  316. <br>
  317. <a name="notifydefine"></a>
  318. <b>Define</b>
  319. <ul>
  320. <code>define &lt;name&gt; notify &lt;pattern&gt; &lt;command&gt;</code>
  321. <br><br>
  322. Execute a command when received an event for the <a
  323. href="#define">definition</a> <code>&lt;pattern&gt;</code>. If
  324. &lt;command&gt; is enclosed in {}, then it is a perl expression, if it is
  325. enclosed in "", then it is a shell command, else it is a "plain" fhem.pl
  326. command (chain). See the <a href="#trigger">trigger</a> command for
  327. testing it.
  328. Examples:
  329. <ul>
  330. <code>define b3lampV1 notify btn3 set lamp $EVENT</code><br>
  331. <code>define b3lampV2 notify btn3 { fhem "set lamp $EVENT" }</code><br>
  332. <code>define b3lampV3 notify btn3 "/usr/local/bin/setlamp "$EVENT""</code><br>
  333. <code>define b3lampV3 notify btn3 set lamp1 $EVENT;;set lamp2 $EVENT</code><br>
  334. <code>define wzMessLg notify wz:measured.* "/usr/local/bin/logfht $NAME "$EVENT""</code><br>
  335. <code>define LogUndef notify global:UNDEFINED.* "send-me-mail.sh "$EVENT""</code><br>
  336. </ul>
  337. <br>
  338. Notes:
  339. <ul>
  340. <li><code>&lt;pattern&gt;</code> is either the name of the triggering
  341. device, or <code>devicename:event</code>.</li>
  342. <li><code>&lt;pattern&gt;</code> must completely (!)
  343. match either the device name, or the compound of the device name and
  344. the event. To identify the events use the inform command from the
  345. telnet prompt or the "Event Monitor" link in the browser
  346. (FHEMWEB), and wait for the event to be printed. See also the
  347. eventTypes device.</li>
  348. <li>in the command section you can access the event:
  349. <ul>
  350. <li>The variable $EVENT will contain the complete event, e.g.
  351. <code>measured-temp: 21.7 (Celsius)</code></li>
  352. <li>$EVTPART0,$EVTPART1,$EVTPART2,etc contain the space separated event
  353. parts (e.g. <code>$EVTPART0="measured-temp:", $EVTPART1="21.7",
  354. $EVTPART2="(Celsius)"</code>. This data is available as a local
  355. variable in perl, as environment variable for shell scripts, and will
  356. be textually replaced for FHEM commands.</li>
  357. <li>$NAME and $TYPE contain the name and type of the device triggering
  358. the event, e.g. myFht and FHT</li>
  359. </ul></li>
  360. <li>Note: the following is deprecated and will be removed in a future
  361. release. It is only active for featurelevel up to 5.6.
  362. The described replacement is attempted if none of the above
  363. variables ($NAME/$EVENT/etc) found in the command.
  364. <ul>
  365. <li>The character <code>%</code> will be replaced with the received
  366. event, e.g. with <code>on</code> or <code>off</code> or
  367. <code>measured-temp: 21.7 (Celsius)</code><br> It is advisable to put
  368. the <code>%</code> into double quotes, else the shell may get a syntax
  369. error.</li>
  370. <li>The character @ will be replaced with the device
  371. name.</li>
  372. <li>To use % or @ in the text itself, use the double mode (%% or
  373. @@).</li>
  374. <li>Instead of % and @, the parameters %EVENT (same as %), %NAME (same
  375. as @) and %TYPE (contains the device type,
  376. e.g. FHT) can be used. The space separated event "parts"
  377. are available as %EVTPART0, %EVTPART1, etc. A single %
  378. looses its special meaning if any of these parameters appears in the
  379. definition.</li>
  380. </ul></li>
  381. <li>Following special events will be generated for the device "global"
  382. <ul>
  383. <li>INITIALIZED after initialization is finished.</li>
  384. <li>REREADCFG after the configuration is reread.</li>
  385. <li>SAVE before the configuration is saved.</li>
  386. <li>SHUTDOWN before FHEM is shut down.</li>
  387. <li>DEFINED &lt;devname&gt; after a device is defined.</li>
  388. <li>DELETED &lt;devname&gt; after a device was deleted.</li>
  389. <li>RENAMED &lt;old&gt; &lt;new&gt; after a device was renamed.</li>
  390. <li>UNDEFINED &lt;defspec&gt; upon reception of a message for an
  391. undefined device.</li>
  392. </ul></li>
  393. <li>Notify can be used to store macros for manual execution. Use the <a
  394. href="#trigger">trigger</a> command to execute the macro.
  395. E.g.<br>
  396. <code>fhem> define MyMacro notify MyMacro { Log 1, "Hello"}</code><br>
  397. <code>fhem> trigger MyMacro</code><br>
  398. </li>
  399. </ul>
  400. </ul>
  401. <br>
  402. <a name="notifyset"></a>
  403. <b>Set </b>
  404. <ul>
  405. <li>addRegexpPart &lt;device&gt; &lt;regexp&gt;<br>
  406. add a regexp part, which is constructed as device:regexp. The parts
  407. are separated by |. Note: as the regexp parts are resorted, manually
  408. constructed regexps may become invalid. </li>
  409. <li>removeRegexpPart &lt;re&gt;<br>
  410. remove a regexp part. Note: as the regexp parts are resorted, manually
  411. constructed regexps may become invalid.<br>
  412. The inconsistency in addRegexpPart/removeRegexPart arguments originates
  413. from the reusage of javascript functions.</li>
  414. <li>inactive<br>
  415. Inactivates the current device. Note the slight difference to the
  416. disable attribute: using set inactive the state is automatically saved
  417. to the statefile on shutdown, there is no explicit save necesary.<br>
  418. This command is intended to be used by scripts to temporarily
  419. deactivate the notify.<br>
  420. The concurrent setting of the disable attribute is not recommended.</li>
  421. <li>active<br>
  422. Activates the current device (see inactive).</li>
  423. </ul>
  424. <br>
  425. <a name="notifyget"></a>
  426. <b>Get</b> <ul>N/A</ul><br>
  427. <a name="notifyattr"></a>
  428. <b>Attributes</b>
  429. <ul>
  430. <li><a href="#disable">disable</a></li>
  431. <li><a href="#disabledForIntervals">disabledForIntervals</a></li>
  432. <a name="addStateEvent"></a>
  433. <li>addStateEvent<br>
  434. The event associated with the state Reading is special, as the "state: "
  435. string is stripped, i.e $EVENT is not "state: on" but just "on". In some
  436. circumstances it is desireable to get the event without "state: "
  437. stripped. In such a case the addStateEvent attribute should be set to 1
  438. (default is 0, i.e. strip the "state: " string).<br>
  439. Note 1: you have to set this attribute for the event "receiver", i.e.
  440. notify, FileLog, etc.<br>
  441. Note 2: this attribute will only work for events generated by devices
  442. supporting the <a href="#readingFnAttributes">readingFnAttributes</a>.
  443. </li>
  444. <a name="forwardReturnValue"></a>
  445. <li>forwardReturnValue<br>
  446. Forward the return value of the executed command to the caller,
  447. default is disabled (0). If enabled (1), then e.g. a set command which
  448. triggers this notify will also return this value. This can cause e.g
  449. FHEMWEB to display this value, when clicking "on" or "off", which is
  450. often not intended.</li>
  451. <a name="readLog"></a>
  452. <li>readLog<br>
  453. Execute the notify for messages appearing in the FHEM Log. The device
  454. in this case is set to the notify itself, e.g. checking for the startup
  455. message looks like:
  456. <ul><code>
  457. define n notify n:.*Server.started.* { Log 1, "Really" }<br>
  458. attr n readLog
  459. </code></ul>
  460. </li>
  461. <a name="perlSyntaxCheck"></a>
  462. <li>perlSyntaxCheck<br>
  463. by setting the <b>global</b> attribute perlSyntaxCheck, a syntax check
  464. will be executed upon definition or modification, if the command is
  465. perl and FHEM is already started.
  466. </li>
  467. </ul>
  468. <br>
  469. </ul>
  470. =end html
  471. =begin html_DE
  472. <a name="notify"></a>
  473. <h3>notify</h3>
  474. <ul>
  475. <br>
  476. <a name="notifydefine"></a>
  477. <b>Define</b>
  478. <ul>
  479. <code>define &lt;name&gt; notify &lt;Suchmuster&gt; &lt;Anweisung&gt;</code>
  480. <br><br>
  481. F&uuml;hrt eine oder mehrere Anweisungen aus, wenn ein Event generiert
  482. wurde, was dem &lt;Suchmuster&gt; (Ger&auml;tename oder
  483. Ger&auml;tename:Event) entspricht.
  484. Die Anweisung ist einer der FHEM <a href="#command">Befehlstypen</a>.
  485. Zum Test dient das <a href="#trigger">trigger</a>-Kommando.
  486. <br><br>
  487. Beispiele:
  488. <ul>
  489. <code>define b3lampV1 notify btn3 set lamp $EVENT</code><br>
  490. <code>define b3lampV2 notify btn3 { fhem "set lamp $EVENT" }</code><br>
  491. <code>define b3lampV3 notify btn3 "/usr/local/bin/setlamp
  492. "$EVENT""</code><br>
  493. <code>define b3lampV3 notify btn3 set lamp1 $EVENT;;set lamp2
  494. $EVENT</code><br>
  495. <code>define wzMessLg notify wz:measured.* "/usr/local/bin/logfht $NAME
  496. "$EVENT""</code><br>
  497. <code>define LogUndef notify global:UNDEFINED.* "send-me-mail.sh
  498. "$EVENT""</code><br>
  499. </ul>
  500. <br>
  501. Hinweise:
  502. <ul>
  503. <li><code>&lt;Suchmuster&gt;</code> ist entweder der Name des
  504. ausl&ouml;senden ("triggernden") Ger&auml;tes oder die Kombination aus
  505. Ger&auml;t und ausl&ouml;sendem Ereignis (Event)
  506. <code>Ger&auml;tename:Event</code>.</li>
  507. <li>Das <code>&lt;Suchmuster&gt;</code> muss exakt (!)
  508. entweder dem Ger&auml;tenamen entsprechen oder der Zusammenf&uuml;gung
  509. aus Ger&auml;tename:Event. Events lassen sich mit "inform" in Telnet
  510. oder durch Beobachtung des "Event-Monitors" in FHEMWEB ermitteln.</li>
  511. <li>In der Anweisung von Notify kann das ausl&ouml;sende Ereignis (Event)
  512. genutzt werden:
  513. <ul>
  514. <li>Die Anweisung $EVENT wird das komplette Ereignis (Event)
  515. beinhalten, z.B. <code>measured-temp: 21.7 (Celsius)</code></li>
  516. <li>$EVTPART0,$EVTPART1,$EVTPART2,etc enthalten die durch Leerzeichen
  517. getrennten Teile des Events der Reihe nach (im Beispiel also
  518. <code>$EVTPART0="measured-temp:", $EVTPART1="21.7",
  519. $EVTPART2="(Celsius)"</code>.<br> Diese Daten sind verf&uuml;gbar
  520. als lokale Variablen in Perl, als Umgebungs-Variablen f&uuml;r
  521. Shell-Scripts, und werden als Text ausgetauscht in
  522. FHEM-Kommandos.</li>
  523. <li>$NAME und $TYPE enthalten den Namen bzw. Typ des Ereignis
  524. ausl&ouml;senden Ger&auml;tes, z.B. myFht und FHT</li>
  525. </ul></li>
  526. <li>Achtung: Folgende Vorgehensweise ist abgek&uuml;ndigt, funktioniert
  527. bis featurelevel 5.6 und wird in einem zuk&uuml;nftigen Release von
  528. FHEM nicht mehr unterst&uuml;tzt. Wenn keine der oben genannten
  529. Variablen ($NAME/$EVENT/usw.) in der Anweisung gefunden wird, werden
  530. Platzhalter ersetzt.
  531. <ul>
  532. <li>Das Zeichen % wird ersetzt mit dem empfangenen
  533. Ereignis (Event), z.B. mit on oder off oder
  534. <code>measured-temp: 21.7 (Celsius)</code>.
  535. </li>
  536. <li>Das Zeichen @ wird ersetzt durch den
  537. Ger&auml;tenamen.</li>
  538. <li>Um % oder @ im Text selbst benutzen zu k&ouml;nnen, m&uuml;ssen
  539. sie verdoppelt werden (%% oder @@).</li>
  540. <li>Anstelle von % und @, k&ouml;nnen die
  541. Parameter %EVENT (funktionsgleich mit %),
  542. %NAME (funktionsgleich mit @) und
  543. %TYPE (enth&auml;lt den Typ des Ger&auml;tes, z.B.
  544. FHT) benutzt werden. Die von Leerzeichen unterbrochenen
  545. Teile eines Ereignisses (Event) sind verf&uuml;gbar als %EVTPART0,
  546. %EVTPART1, usw. Ein einzeln stehendes % verliert seine
  547. oben beschriebene Bedeutung, falls auch nur einer dieser Parameter
  548. in der Definition auftaucht.</li>
  549. </ul></li>
  550. <li>Folgende spezielle Ereignisse werden f&uuml;r das Ger&auml;t "global"
  551. erzeugt:
  552. <ul>
  553. <li>INITIALIZED sobald die Initialization vollst&auml;ndig ist.</li>
  554. <li>REREADCFG nachdem die Konfiguration erneut eingelesen wurde.</li>
  555. <li>SAVE bevor die Konfiguration gespeichert wird.</li>
  556. <li>SHUTDOWN bevor FHEM heruntergefahren wird.</li>
  557. <li>DEFINED &lt;devname&gt; nach dem Definieren eines
  558. Ger&auml;tes.</li>
  559. <li>DELETED &lt;devname&gt; nach dem L&ouml;schen eines
  560. Ger&auml;tes.</li>
  561. <li>RENAMED &lt;old&gt; &lt;new&gt; nach dem Umbenennen eines
  562. Ger&auml;tes.</li>
  563. <li>UNDEFINED &lt;defspec&gt; beim Auftreten einer Nachricht f&uuml;r
  564. ein undefiniertes Ger&auml;t.</li>
  565. </ul></li>
  566. <li>Notify kann dazu benutzt werden, um Makros f&uuml;r eine manuelle
  567. Ausf&uuml;hrung zu speichern. Mit einem <a
  568. href="#trigger">trigger</a> Kommando k&ouml;nnen solche Makros dann
  569. ausgef&uuml;hrt werden. Z.B.<br> <code>fhem> define MyMacro notify
  570. MyMacro { Log 1, "Hello"}</code><br> <code>fhem> trigger
  571. MyMacro</code><br> </li>
  572. </ul>
  573. </ul>
  574. <br>
  575. <a name="notifyset"></a>
  576. <b>Set </b>
  577. <ul>
  578. <li>addRegexpPart &lt;device&gt; &lt;regexp&gt;<br>
  579. F&uuml;gt ein regexp Teil hinzu, der als device:regexp aufgebaut ist.
  580. Die Teile werden nach Regexp-Regeln mit | getrennt. Achtung: durch
  581. hinzuf&uuml;gen k&ouml;nnen manuell erzeugte Regexps ung&uuml;ltig
  582. werden.</li>
  583. <li>removeRegexpPart &lt;re&gt;<br>
  584. Entfernt ein regexp Teil. Die Inkonsistenz von addRegexpPart /
  585. removeRegexPart-Argumenten hat seinen Ursprung in der Wiederverwendung
  586. von Javascript-Funktionen.</li>
  587. <li>inactive<br>
  588. Deaktiviert das entsprechende Ger&auml;t. Beachte den leichten
  589. semantischen Unterschied zum disable Attribut: "set inactive"
  590. wird bei einem shutdown automatisch in fhem.state gespeichert, es ist
  591. kein save notwendig.<br>
  592. Der Einsatzzweck sind Skripte, um das notify tempor&auml;r zu
  593. deaktivieren.<br>
  594. Das gleichzeitige Verwenden des disable Attributes wird nicht empfohlen.
  595. </li>
  596. <li>active<br>
  597. Aktiviert das entsprechende Ger&auml;t, siehe inactive.
  598. </li>
  599. </ul>
  600. <br>
  601. <a name="notifyget"></a>
  602. <b>Get</b> <ul>N/A</ul><br>
  603. <a name="notifyattr"></a>
  604. <b>Attribute</b>
  605. <ul>
  606. <li><a href="#disable">disable</a></li>
  607. <li><a href="#disabledForIntervals">disabledForIntervals</a></li>
  608. <a name="addStateEvent"></a>
  609. <li>addStateEvent<br>
  610. Das mit dem state Reading verkn&uuml;pfte Event ist speziell, da das
  611. dazugeh&ouml;rige Prefix "state: " entfernt wird, d.h. $EVENT ist nicht
  612. "state: on", sondern nur "on". In manchen F&auml;llen ist es aber
  613. erw&uuml;nscht das unmodifizierte Event zu bekommen, d.h. wo "state: "
  614. nicht entfernt ist. F&uuml;r diese F&auml;lle sollte addStateEvent auf 1
  615. gesetzt werden, die Voreinstellung ist 0 (deaktiviert).<br>
  616. Achtung:
  617. <ul>
  618. <li>dieses Attribut muss beim Empf&auml;nger (notify, FileLog, etc)
  619. gesetzt werden.</li>
  620. <li>dieses Attribut zeigt nur f&uuml;r solche Ger&auml;te-Events eine
  621. Wirkung, die <a href="#readingFnAttributes">readingFnAttributes</a>
  622. unterst&uuml;tzen.</li>
  623. </ul>
  624. </li>
  625. <a name="forwardReturnValue"></a>
  626. <li>forwardReturnValue<br>
  627. R&uuml;ckgabe der Werte eines ausgef&uuml;hrten Kommandos an den
  628. Aufrufer. Die Voreinstellung ist 0 (ausgeschaltet), um weniger
  629. Meldungen im Log zu haben.
  630. </li>
  631. <a name="readLog"></a>
  632. <li>readLog<br>
  633. Das notify wird f&uuml;r Meldungen, die im FHEM-Log erscheinen,
  634. ausgegef&uuml;hrt. Das "Event-Generierende-Ger&auml;t" wird auf dem
  635. notify selbst gesetzt. Z.Bsp. kann man mit folgendem notify auf die
  636. Startup Meldung reagieren:
  637. <ul><code>
  638. define n notify n:.*Server.started.* { Log 1, "Wirklich" }<br>
  639. attr n readLog
  640. </code></ul>
  641. </li>
  642. <a name="perlSyntaxCheck"></a>
  643. <li>perlSyntaxCheck<br>
  644. nach setzen des <b>global</b> Attributes perlSyntaxCheck wird eine
  645. Syntax-Pr&uuml;fung der Anweisung durchgef&uuml;hrt bei jeder
  646. &Auml;nderung (define oder modify), falls die Anweisung Perl ist, und
  647. FHEM bereits gestartet ist. </li>
  648. </ul>
  649. <br>
  650. </ul>
  651. =end html_DE
  652. =cut