98_cmdalias.pm 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. ##############################################
  2. # $Id: 98_cmdalias.pm 16300 2018-03-01 08:48:21Z rudolfkoenig $
  3. # Avarage computing
  4. package main;
  5. use strict;
  6. use warnings;
  7. my %cmdalias;
  8. ##########################
  9. sub
  10. cmdalias_Initialize($)
  11. {
  12. my ($hash) = @_;
  13. $hash->{DefFn} = "cmdalias_Define";
  14. $hash->{UndefFn} = "cmdalias_Undefine";
  15. $hash->{AttrList} = "disable:0,1 disabledForIntervals";
  16. }
  17. ##########################
  18. sub
  19. cmdalias_Define($$$)
  20. {
  21. my ($hash, $def) = @_;
  22. if($def !~ m/^([^ ]*) cmdalias ([^ ]*)(.*) AS (.*)$/s) {
  23. my $msg =
  24. "wrong syntax: define <name> cmdalias <cmd> [parameter] AS command...";
  25. return $msg;
  26. }
  27. my ($name, $alias, $param, $newcmd) = ($1, $2, $3, $4);
  28. $param =~ s/^ *//;
  29. # Checking for misleading regexps
  30. return "Bad regexp: starting with *" if($param =~ m/^\*/);
  31. eval { qr/^$param$/ };
  32. return "$name: Bad regexp in $param: $@" if($@);
  33. $alias = lc($alias);
  34. $hash->{ALIAS} = $alias;
  35. $hash->{PARAM} = $param;
  36. $hash->{NEWCMD} = $newcmd;
  37. $hash->{STATE} = "defined";
  38. $cmdalias{$alias}{Alias}{$name} = $hash;
  39. $cmdalias{$alias}{OrigFn} = $cmds{$alias}{Fn}
  40. if($cmds{$alias} &&
  41. $cmds{$alias}{Fn} &&
  42. $cmds{$alias}{Fn} ne "CommandCmdAlias");
  43. $cmds{$alias}{Fn} = "CommandCmdAlias";
  44. return undef;
  45. }
  46. sub
  47. cmdalias_Undefine($$)
  48. {
  49. my ($hash, $arg) = @_;
  50. my $alias = $hash->{ALIAS};
  51. delete $cmdalias{$alias}{Alias}{$hash->{NAME}};
  52. if(! keys %{$cmdalias{$alias}{Alias}}) {
  53. if($cmdalias{$alias}{OrigFn}) {
  54. $cmds{$alias}{Fn} = $cmdalias{$alias}{OrigFn};
  55. } else {
  56. delete($cmds{$alias});
  57. }
  58. delete($cmdalias{$alias});
  59. }
  60. return undef;
  61. }
  62. sub
  63. CommandCmdAlias($$$)
  64. {
  65. my ($cl, $param, $alias) = @_;
  66. my $a = $cmdalias{lc($alias)};
  67. return "Unknown command $a, internal error" if(!$a);
  68. foreach my $n (sort keys %{$a->{Alias}}) {
  69. my $h = $a->{Alias}{$n};
  70. my $doesMatch = $param =~ m/^$h->{PARAM}$/s; # Match multiline, #77285
  71. if($h->{InExec} && $doesMatch) {
  72. Log3 $n, 3, "cmdalias $n called recursively, skipping execution";
  73. next;
  74. }
  75. if($doesMatch && !IsDisabled($h->{NAME})) {
  76. my %specials= ("%EVENT" => $param);
  77. my $exec = EvalSpecials($h->{NEWCMD}, %specials);
  78. $h->{InExec} = 1;
  79. my $r = AnalyzeCommandChain($cl, $exec);
  80. delete $h->{InExec};
  81. return $r;
  82. }
  83. }
  84. return undef if(!$a->{OrigFn});
  85. no strict "refs";
  86. return &{$a->{OrigFn} }($cl, $param, $alias);
  87. use strict "refs";
  88. }
  89. 1;
  90. =pod
  91. =item command
  92. =item summary create new FHEM commands or replace internal ones
  93. =item summary_DE neue FHEM Befehle definieren oder existierende &auml;ndern
  94. =begin html
  95. <a name="cmdalias"></a>
  96. <h3>cmdalias</h3>
  97. <ul>
  98. create new FHEM commands or replace internal ones.
  99. <br><br>
  100. <a name="cmdaliasdefine"></a>
  101. <b>Define</b>
  102. <ul>
  103. <code>define &lt;name&gt; cmdalias &lt;cmd_to_be_replaced or new_cmd&gt;
  104. [parameter] AS &lt;existing_cmd&gt;</code><br>
  105. <br>
  106. parameter is optional and is a regexp which must match the command
  107. entered.
  108. If it matches, then the specified &lt;existing_command&gt; will be
  109. executed, which is a FHEM command (see <a href="#command">FHEM command
  110. types</a> for details). Like in <a href="#notify">notify</a>, $EVENT or
  111. $EVTPART may be used, in this case representing the
  112. command arguments as whole or the unique words entered.<br>
  113. </ul>
  114. Notes:<ul>
  115. <li>recursion is not allowed.</li>
  116. <li>if there are multiple definitions, they are checked/executed in
  117. alphabetically sorted &lt;name&gt; oder.</li>
  118. </ul>
  119. Examples:
  120. <ul><code>
  121. define s1 cmdalias shutdown update AS save;;shutdown<br>
  122. define s2 cmdalias set lamp .* AS { Log 1, "$EVENT";; fhem("set $EVENT") }
  123. </code></ul>
  124. <a name="cmdaliasattr"></a>
  125. <b>Attribute</b>
  126. <ul>
  127. <li><a href="#disable">disable</a></li>
  128. <li><a href="#disabledForIntervals">disabledForIntervals</a></li>
  129. </ul>
  130. </ul>
  131. =end html
  132. =cut