mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-09 20:57:11 +00:00
98_template: new FHEM command template
git-svn-id: https://svn.fhem.de/fhem/trunk@13683 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
b6564cc7f7
commit
abe77cd44e
@ -1,5 +1,6 @@
|
||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||
# Do not insert empty lines here, update check depends on it.
|
||||
- feature: 98_template: new FHEM command template
|
||||
- feature: 70_MEDIAPORTAL: Plugins can be retreived and changed to
|
||||
- update: 00_SONOS: New version, see Wiki- or File-Changelog
|
||||
- update: 88_HMCCU: Code optimized. Fixed Windows process ID bug.
|
||||
|
218
fhem/FHEM/98_template.pm
Normal file
218
fhem/FHEM/98_template.pm
Normal file
@ -0,0 +1,218 @@
|
||||
# $Id$
|
||||
|
||||
package main;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub template_Initialize($$) {
|
||||
|
||||
$cmds{template} =
|
||||
{ Fn=>"CommandTemplate",
|
||||
Hlp=>"[use] <filename> [<param1>=<value1> [<param2>=<value2> [...]]],use a template" };
|
||||
}
|
||||
|
||||
sub EvaluateTemplate($$) {
|
||||
my ($filename, $args)= @_;
|
||||
|
||||
# load template from file
|
||||
my @result;
|
||||
if(open(TEMPLATE, $filename)) {
|
||||
@result= <TEMPLATE>;
|
||||
close(TEMPLATE);
|
||||
} else {
|
||||
return ("Cannot open $filename: $!", undef, undef, undef);
|
||||
}
|
||||
|
||||
# remove trailing newlines and empty/whitespace lines
|
||||
@result= grep /\S/, map { s/\r?\n$//; $_ } @result;
|
||||
|
||||
# we enumerate the parameters for the show command
|
||||
my %p;
|
||||
map { while(m/\%(\w+)%/g) { $p{$1}= 1 } } @result;
|
||||
my @params= keys %p;
|
||||
|
||||
# do parameter substition
|
||||
Log 5, "Using template from file $filename.";
|
||||
my ($valuesref,$kvref)= parseParams($args);
|
||||
my @values= @{$valuesref}; my %kv= %{$kvref};
|
||||
return "parameters must be of form <param>=<value>" unless($#values<0);
|
||||
foreach my $key (keys %kv) {
|
||||
my $value= $kv{$key};
|
||||
my $count= 0;
|
||||
map { $count += s/\%$key\%/$value/g } @result;
|
||||
Log 5, "Using $value for parameter %$key% in template $filename $count time(s).";
|
||||
}
|
||||
|
||||
# count and enumerate not substituted parameters
|
||||
my $count= 0; %p= ();
|
||||
map { while(m/\%(\w+)%/g) { $p{$1}= 1; $count++ } } @result;
|
||||
my $warn= "$count parameter(s) not substituted in template $filename: " .
|
||||
join(" ", keys %p) if($count);
|
||||
|
||||
# return the result
|
||||
return (undef, $warn, \@params, \@result);
|
||||
}
|
||||
|
||||
sub CommandTemplate($$) {
|
||||
my ($cl, $param) = @_;
|
||||
my $usage= "Usage: template [use|show] <filename> [<param1>=<value1> [<param2>=<value2> [...]]]";
|
||||
|
||||
# get the arguments and do first sanity checks
|
||||
my @args= split("[ \t]]*", $param);
|
||||
return $usage if($#args< 0);
|
||||
my $action= "use";
|
||||
$action= shift @args if($args[0] eq "use" || $args[0] eq "show");
|
||||
return $usage if($#args< 0);
|
||||
my $filename= shift @args;
|
||||
|
||||
# evaluate the template
|
||||
my ($error, $warn, $paramsref, $resultref)= EvaluateTemplate($filename, join(" ", @args));
|
||||
return $error if(defined($error));
|
||||
# we inform the user about missing substitutions but
|
||||
# we do not make this an error because the actual occurence %...% might be intentional
|
||||
Log 5, $warn if(defined($warn));
|
||||
|
||||
if($action eq "use") {
|
||||
my @ret;
|
||||
my $bigcmd = "";
|
||||
${main::rcvdquit} = 0;
|
||||
foreach my $l (@{$resultref}) {
|
||||
if($l =~ m/^(.*)\\ *$/) { # Multiline commands
|
||||
$bigcmd .= "$1\n";
|
||||
} else {
|
||||
my $tret = AnalyzeCommandChain($cl, $bigcmd . $l);
|
||||
push @ret, $tret if(defined($tret));
|
||||
$bigcmd = "";
|
||||
}
|
||||
last if(${main::rcvdquit});
|
||||
}
|
||||
return join("\n", @ret) if(@ret);
|
||||
return undef;
|
||||
} elsif($action eq "show") {
|
||||
return(
|
||||
"template: $filename" .
|
||||
"\nresult:\n" . join("\n", @{$resultref}) .
|
||||
"\nparameters: " . join(" ", @{$paramsref})
|
||||
);
|
||||
} else {
|
||||
return undef; # we never get here
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
=item command
|
||||
=item summary use a template for repetitive configurations and commands.
|
||||
=item summary_DE verwendet ein Template für wiederkehrende Konfigurationen und Kommandos.
|
||||
=begin html
|
||||
|
||||
<a name="template"></a>
|
||||
<h3>template</h3>
|
||||
<ul>
|
||||
<code>template [use|show] <filename> [<param1>=<value1> [<param2>=<value2> [...]]]</code>
|
||||
<br><br>
|
||||
Includes a file with parameter substitution, i.e. read the file and process every line as a FHEM command.
|
||||
For any given parameter/value pair <code><param>=<value></code> on the command line,
|
||||
a literal <code>%<param>%</code> in the file is replaced by <value> before executing the command.<br><br>
|
||||
|
||||
This can be used to to code recurring definitions of one or several devices only once and use it many times.
|
||||
<code>template show ..</code> shows what would be done, including a parameter listing, while
|
||||
<code>template use ...</code> actually does the job. The word <code>use</code> can be omitted.<br><br>
|
||||
|
||||
<b>Example</b><br><br>
|
||||
|
||||
File <i>H.templ</i>:<br><br>
|
||||
|
||||
<code>
|
||||
define %name% FHT %fhtcode%<br>
|
||||
attr %name% IODev CUN<br>
|
||||
attr %name% alias %alias%<br>
|
||||
attr %name% group %group%<br>
|
||||
attr %name% icon icoTempHeizung.png<br>
|
||||
attr %name% room %room%,Anlagen/Heizungen<br>
|
||||
<br>
|
||||
define watchdog.%name% watchdog %name% 00:15:00 SAME set %name% report2 255<br>
|
||||
attr watchdog.%name% group %group%<br>
|
||||
attr watchdog.%name% room Control/Heizungen<br>
|
||||
<br>
|
||||
define %name%.log FileLog /opt/fhem/log/%name%-%Y%m.log %name%:.*<br>
|
||||
attr %name%.log group %group%<br>
|
||||
attr %name%.log icon icoLog.png<br>
|
||||
attr %name%.log logtype fht<br>
|
||||
attr %name%.log room Control/Heizungen<br>
|
||||
<br>
|
||||
define %name%.weblink SVG %name%.log:%name%:CURRENT<br>
|
||||
attr %name%.weblink label sprintf("Temperatur: %.0f °C (%.0f °C .. %.0f °C) Aktor: %.0f %% (%.0f %% .. %.0f %%)", $data{currval1}, $data{min1}, $data{max1}, $data{currval2}, $data{min2}, $data{max2} )<br>
|
||||
attr %name%.weblink room %room%<br>
|
||||
attr %name%.weblink alias %alias%<br>
|
||||
</code><br><br>
|
||||
|
||||
Configuration:<br><br>
|
||||
|
||||
<code>te H.templ name=3.dz.hzg fhtcode=3f4a alias=Dachzimmerheizung group=Heizung room=Dachzimmer</code><br><br>
|
||||
|
||||
Please note that although %Y% in the FileLog definition looks like a parameter, it is not substituted since no parameter
|
||||
Y is given on the command line. You get detailed information at verbosity level 5 when you run the command.
|
||||
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
|
||||
=begin html_DE
|
||||
|
||||
<a name="template"></a>
|
||||
<h3>template</h3>
|
||||
<ul>
|
||||
<code>template [use|show] <filename> [<param1>=<value1> [<param2>=<value2> [...]]]</code>
|
||||
<br><br>
|
||||
Includes a file with parameter substitution, i.e. read the file and process every line as a FHEM command.
|
||||
For any given parameter/value pair <code><param>=<value></code> on the command line,
|
||||
a literal <code>%<param>%</code> in the file is replaced by <value> before executing the command.<br><br>
|
||||
|
||||
This can be used to to code recurring definitions of one or several devices only once and use it many times.
|
||||
<code>template show ..</code> shows what would be done, including a parameter listing, while
|
||||
<code>template use ...</code> actually does the job. The word <code>use</code> can be omitted.<br><br>
|
||||
|
||||
<b>Example</b><br><br>
|
||||
|
||||
File <i>H.templ</i>:<br><br>
|
||||
|
||||
<code>
|
||||
define %name% FHT %fhtcode%<br>
|
||||
attr %name% IODev CUN<br>
|
||||
attr %name% alias %alias%<br>
|
||||
attr %name% group %group%<br>
|
||||
attr %name% icon icoTempHeizung.png<br>
|
||||
attr %name% room %room%,Anlagen/Heizungen<br>
|
||||
<br>
|
||||
define watchdog.%name% watchdog %name% 00:15:00 SAME set %name% report2 255<br>
|
||||
attr watchdog.%name% group %group%<br>
|
||||
attr watchdog.%name% room Control/Heizungen<br>
|
||||
<br>
|
||||
define %name%.log FileLog /opt/fhem/log/%name%-%Y%m.log %name%:.*<br>
|
||||
attr %name%.log group %group%<br>
|
||||
attr %name%.log icon icoLog.png<br>
|
||||
attr %name%.log logtype fht<br>
|
||||
attr %name%.log room Control/Heizungen<br>
|
||||
<br>
|
||||
define %name%.weblink SVG %name%.log:%name%:CURRENT<br>
|
||||
attr %name%.weblink label sprintf("Temperatur: %.0f °C (%.0f °C .. %.0f °C) Aktor: %.0f %% (%.0f %% .. %.0f %%)", $data{currval1}, $data{min1}, $data{max1}, $data{currval2}, $data{min2}, $data{max2} )<br>
|
||||
attr %name%.weblink room %room%<br>
|
||||
attr %name%.weblink alias %alias%<br>
|
||||
</code><br><br>
|
||||
|
||||
Configuration:<br><br>
|
||||
|
||||
<code>te H.templ name=3.dz.hzg fhtcode=3f4a alias=Dachzimmerheizung group=Heizung room=Dachzimmer</code><br><br>
|
||||
|
||||
Please note that although %Y% in the FileLog definition looks like a parameter, it is not substituted since no parameter
|
||||
Y is given on the command line. You get detailed information at verbosity level 5 when you run the command.
|
||||
|
||||
</ul>
|
||||
|
||||
=end html_DE
|
||||
|
||||
=cut
|
Loading…
x
Reference in New Issue
Block a user