mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-18 05:56:03 +00:00
188 lines
4.8 KiB
Perl
188 lines
4.8 KiB
Perl
##############################################
|
|
# $Id$
|
|
package main;
|
|
|
|
my %templates;
|
|
my $initialized;
|
|
my %cachedUsage;
|
|
|
|
sub
|
|
AttrTemplate_Initialize()
|
|
{
|
|
my $me = "AttrTemplate_Initialize";
|
|
my $dir = $attr{global}{modpath}."/FHEM/lib/AttrTemplate";
|
|
if(!opendir(dh, $dir)) {
|
|
Log 1, "$me: cant open $dir: $!";
|
|
return;
|
|
}
|
|
|
|
my @files = grep /\.template$/, sort readdir dh;
|
|
closedir(dh);
|
|
|
|
%templates = ();
|
|
%cachedUsage = ();
|
|
for my $file (@files) {
|
|
if(!open(fh,"$dir/$file")) {
|
|
Log 1, "$me: cant open $dir/$file: $!";
|
|
next;
|
|
}
|
|
my ($name, %h, $lastComment);
|
|
while(my $line = <fh>) {
|
|
chomp($line);
|
|
next if($line =~ m/^$/);
|
|
|
|
if($line =~ m/^# *(.*)$/) { # just a replacement for missing desc
|
|
$lastComment = $1;
|
|
next;
|
|
|
|
} elsif($line =~ m/^name:(.*)/) {
|
|
$name = $1;
|
|
my (@p,@c);
|
|
$templates{$name}{pars} = \@p;
|
|
$templates{$name}{cmds} = \@c;
|
|
$templates{$name}{desc} = $lastComment if($lastComment);
|
|
$lastComment = "";
|
|
|
|
} elsif($line =~ m/^filter:(.*)=(.*)/) {
|
|
$templates{$name}{filterName} = $1;
|
|
$templates{$name}{filterVal} = $2;
|
|
|
|
} elsif($line =~ m/^par:(.*)/) {
|
|
push(@{$templates{$name}{pars}}, $1);
|
|
|
|
} elsif($line =~ m/^desc:(.*)/) {
|
|
$templates{$name}{desc} = $1;
|
|
|
|
} else {
|
|
push(@{$templates{$name}{cmds}}, $line);
|
|
|
|
}
|
|
}
|
|
close(fh);
|
|
}
|
|
my $nr = (int keys %templates);
|
|
$initialized = 1;
|
|
Log 2, "AttrTemplates: got $nr entries" if($nr);
|
|
}
|
|
|
|
sub
|
|
AttrTemplate_Set($$@)
|
|
{
|
|
my ($hash, $list, $name, $cmd, @a) = @_;
|
|
|
|
AttrTemplate_Initialize() if(!$initialized);
|
|
|
|
my $haveDesc;
|
|
if($cmd ne "attrTemplate") {
|
|
if(!$cachedUsage{$name}) {
|
|
my @list;
|
|
for my $k (sort keys %templates) {
|
|
my $h = $templates{$k};
|
|
if(!$h->{filterName} || $hash->{$h->{filterName}} eq $h->{filterVal}) {
|
|
push @list, $k;
|
|
$haveDesc = 1 if($h->{desc});
|
|
}
|
|
}
|
|
$cachedUsage{$name} = (@list ?
|
|
"attrTemplate:".($haveDesc ? "?,":"").join(",",@list) : "");
|
|
}
|
|
$list .= " " if($list ne "");
|
|
return "Unknown argument $cmd, choose one of $list$cachedUsage{$name}";
|
|
}
|
|
|
|
return "Missing template_entry_name parameter for attrTemplate" if(@a < 1);
|
|
my $entry = shift(@a);
|
|
|
|
if($entry eq "?") {
|
|
my @hlp;
|
|
for my $k (sort keys %templates) {
|
|
my $h = $templates{$k};
|
|
if(!$h->{filterName} || $hash->{$h->{filterName}} eq $h->{filterVal}) {
|
|
push @hlp, "$k: $h->{desc}" if($h->{desc});
|
|
}
|
|
}
|
|
return "no help available" if(!@hlp);
|
|
if($hash->{CL} && $hash->{CL}{TYPE} eq "FHEMWEB") {
|
|
return "<html><ul><li>".join("</li><br><li>",
|
|
map { $_=~s/:/<br>/; $_ } @hlp)."</li></ul></html>";
|
|
}
|
|
return join("\n", @hlp);
|
|
}
|
|
|
|
my $h = $templates{$entry};
|
|
return "Unknown template_entry_name $entry" if(!$h);
|
|
|
|
my (%repl, @mComm, @mList, $missing);
|
|
for my $k (@{$h->{pars}}) {
|
|
my ($parname, $comment, $perl_code) = split(";",$k,3);
|
|
|
|
if(@a) {
|
|
$repl{$parname} = $a[0];
|
|
push(@mList, $parname);
|
|
push(@mComm, "$parname: with the $comment");
|
|
shift(@a);
|
|
next;
|
|
}
|
|
|
|
if($perl_code) {
|
|
$perl_code =~ s/DEVICE/$name/g;
|
|
my $ret = eval $perl_code;
|
|
return "Error checking template regexp: $@" if($@);
|
|
if($ret) {
|
|
$repl{$parname} = $ret;
|
|
next;
|
|
}
|
|
}
|
|
|
|
push(@mList, $parname);
|
|
push(@mComm, "$parname: with the $comment");
|
|
$missing = 1;
|
|
}
|
|
|
|
if($missing) {
|
|
if($hash->{CL} && $hash->{CL}{TYPE} eq "FHEMWEB") {
|
|
return
|
|
"<html>".
|
|
"<input size='60' type='text' spellcheck='false' ".
|
|
"value='set $name attrTemplate $entry @mList'>".
|
|
"<br><br>Replace<br>".join("<br>",@mComm).
|
|
'<script>
|
|
setTimeout(function(){
|
|
// TODO: fix multiple dialog calls
|
|
$("#FW_okDialog").parent().find("button").css("display","block");
|
|
$("#FW_okDialog").parent().find(".ui-dialog-buttonpane button")
|
|
.unbind("click").click(function(){
|
|
var val = encodeURIComponent($("#FW_okDialog input").val());
|
|
FW_cmd(FW_root+"?cmd="+val+"&XHR=1",
|
|
function(){ location.reload() } );
|
|
$("#FW_okDialog").remove();
|
|
})}, 100);
|
|
</script>
|
|
</html>';
|
|
|
|
} else {
|
|
return "Usage: set $name attrTemplate $entry @mList\nReplace\n".
|
|
join("\n", @mComm);
|
|
|
|
}
|
|
}
|
|
|
|
my $cmdlist = join("\n",@{$h->{cmds}});
|
|
$repl{DEVICE} = $name;
|
|
map { $cmdlist =~ s/$_/$repl{$_}/g; } keys %repl;
|
|
my $cmd = "";
|
|
my @ret;
|
|
map {
|
|
if($_ =~ m/^(.*)\\$/) {
|
|
$cmd .= "$1\n";
|
|
} else {
|
|
my $r = AnalyzeCommand($hash->{CL}, $cmd.$_);
|
|
push(@ret, $r) if($r);
|
|
$cmd = "";
|
|
}
|
|
} split("\n", $cmdlist);
|
|
return @ret ? join("\n", @ret) : undef;
|
|
}
|
|
|
|
1;
|