mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +00:00
90_at.pm/91_notify.pm: add little FHEMWEB wizards
git-svn-id: https://svn.fhem.de/fhem/trunk@7000 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
49203c8074
commit
e51c143f4a
@ -18,6 +18,7 @@ at_Initialize($)
|
||||
$hash->{StateFn} = "at_State";
|
||||
$hash->{AttrList} = "disable:0,1 disabledForIntervals ".
|
||||
"skip_next:0,1 alignTime";
|
||||
$hash->{FW_detailFn} = "at_fhemwebFn";
|
||||
}
|
||||
|
||||
|
||||
@ -69,6 +70,10 @@ at_Define($$)
|
||||
$rel = "" if(!defined($rel));
|
||||
$rep = "" if(!defined($rep));
|
||||
$cnt = "" if(!defined($cnt));
|
||||
$hash->{RELATIVE} = ($rel ? "yes" : "no");
|
||||
$hash->{PERIODIC} = ($rep ? "yes" : "no");
|
||||
$hash->{TIMESPEC} = $tspec;
|
||||
$hash->{COMMAND} = $command;
|
||||
|
||||
my $ot = $data{AT_TRIGGERTIME} ? $data{AT_TRIGGERTIME} : gettimeofday();
|
||||
$ot = int($ot) if(!$rel); # No way to specify subseconds
|
||||
@ -132,8 +137,8 @@ at_Exec($)
|
||||
my $disable = IsDisabled($name);
|
||||
|
||||
delete $attr{$name}{skip_next} if($skip);
|
||||
my (undef, $command) = split("[ \t]+", $hash->{DEF}, 2);
|
||||
$command = SemicolonEscape($command);
|
||||
|
||||
my $command = SemicolonEscape($hash->{COMMAND});
|
||||
my $ret = AnalyzeCommandChain(undef, $command) if(!$skip && !$disable);
|
||||
Log3 $name, 3, "$name: $ret" if($ret);
|
||||
|
||||
@ -246,6 +251,74 @@ at_State($$$$)
|
||||
return undef;
|
||||
}
|
||||
|
||||
#########################
|
||||
sub
|
||||
at_fhemwebFn($$$$)
|
||||
{
|
||||
my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn.
|
||||
my $hash = $defs{$d};
|
||||
|
||||
my $ts = $hash->{TIMESPEC}; $ts =~ s/'/\\'/g;
|
||||
my $isPerl = ($ts =~ m/^{(.*)}/);
|
||||
$ts = $1 if($isPerl);
|
||||
|
||||
return "<br>Timespec wizard:".
|
||||
"<table id='atWizard' nm='$hash->{NAME}' ts='$ts' rl='$hash->{RELATIVE}' ".
|
||||
"pr='$hash->{PERIODIC}' ip='$isPerl' class='block wide'>".<<'EOF';
|
||||
<tr class="even">
|
||||
<td>Relative <input type="checkbox" id="aw_rl" value="yes"></td>
|
||||
<td>Periodic <input type="checkbox" id="aw_pr" value="yes"></td>
|
||||
</tr><tr class="odd"><td>Use perl function for timespec</td>
|
||||
<td><input type="checkbox" id="aw_ip"></td>
|
||||
</tr><tr class="even"><td>Timespec</td>
|
||||
<td><input type="text" id="aw_pts"></td>
|
||||
</tr><tr class="even"><td>Timespec</td>
|
||||
<td><input type="text" readonly id="aw_ts" size="5">
|
||||
<input type='button' value='+' id="aw_tsb"></td>
|
||||
</tr>
|
||||
</tr><tr class="even">
|
||||
<td colspan="2"><input type="button" id="aw_md" value="Modify"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<script type="text/javascript">
|
||||
loadScript("pgm2/jquery.min.js", atDetails);
|
||||
function
|
||||
atDetails()
|
||||
{
|
||||
var t=$("#atWizard"), ip=$(t).attr("ip"), ts=$(t).attr("ts");
|
||||
|
||||
function tsClick() {
|
||||
FW_timeCreate(this, function(val) { $("#aw_tsb").click(tsClick) })
|
||||
}
|
||||
function ipClick() {
|
||||
var c = $("#aw_ip").prop("checked");
|
||||
$("#aw_ts").closest("tr").css("display", !c ? "table-row" : "none");
|
||||
$("#aw_pts").closest("tr").css("display", c ? "table-row" : "none");
|
||||
}
|
||||
$("#aw_rl").prop("checked", $(t).attr("rl")=="yes");
|
||||
$("#aw_pr").prop("checked", $(t).attr("pr")=="yes");
|
||||
$("#aw_ip").prop("checked", ip);
|
||||
$("#aw_ts").val(ip ? "12:00" : ts);
|
||||
$("#aw_pts").val(ip ? ts : 'sunset()');
|
||||
$("#aw_tsb").click(tsClick);
|
||||
$("#aw_ip").change(ipClick);
|
||||
ipClick();
|
||||
$("#aw_md").click(function(){
|
||||
var nm = $(t).attr("nm");
|
||||
var def = nm+" ";
|
||||
def += $("#aw_rl").prop("checked") ? "+":"";
|
||||
def += $("#aw_pr").prop("checked") ? "*":"";
|
||||
def += $("#aw_ip").prop("checked") ?
|
||||
"{"+$("#aw_pts").val()+"}" : $("#aw_ts").val();
|
||||
def = def.replace(/\+/g, "%2b");
|
||||
def = def.replace(/;/g, ";;");
|
||||
location = location.pathname+"detail="+nm+"&cmd=modify "+def;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
EOF
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
@ -4,6 +4,7 @@ package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use vars qw($FW_ME); # webname (default is fhem)
|
||||
|
||||
#####################################
|
||||
sub
|
||||
@ -15,6 +16,8 @@ notify_Initialize($)
|
||||
$hash->{NotifyFn} = "notify_Exec";
|
||||
$hash->{AttrFn} = "notify_Attr";
|
||||
$hash->{AttrList} = "disable:0,1 disabledForIntervals forwardReturnValue:0,1 showTriggerTime:0,1 addStateEvent:0,1";
|
||||
$hash->{SetFn} = "notify_Set";
|
||||
$hash->{FW_detailFn} = "notify_fhemwebFn";
|
||||
}
|
||||
|
||||
|
||||
@ -39,6 +42,7 @@ notify_Define($$)
|
||||
eval { "Hallo" =~ m/^$re$/ };
|
||||
return "Bad regexp: $@" if($@);
|
||||
$hash->{REGEXP} = $re;
|
||||
$hash->{COMMAND} = $command;
|
||||
$hash->{STATE} = "active";
|
||||
notifyRegexpChanged($hash, $re);
|
||||
|
||||
@ -74,14 +78,12 @@ notify_Exec($$)
|
||||
}
|
||||
if($found) {
|
||||
Log3 $ln, 5, "Triggering $ln";
|
||||
my (undef, $exec) = split("[ \t]+", $ntfy->{DEF}, 2);
|
||||
|
||||
my %specials= (
|
||||
"%NAME" => $n,
|
||||
"%TYPE" => $t,
|
||||
"%EVENT" => $s
|
||||
);
|
||||
$exec= EvalSpecials($exec, %specials);
|
||||
my $exec = EvalSpecials($ntfy->{COMMAND}, %specials);
|
||||
|
||||
Log3 $ln, 4, "$ln exec $exec";
|
||||
my $r = AnalyzeCommandChain(undef, $exec);
|
||||
@ -111,6 +113,116 @@ notify_Attr(@)
|
||||
$defs{$a[1]}{STATE} = ($do == 1 ? "disabled" : "active");
|
||||
return undef;
|
||||
}
|
||||
|
||||
###################################
|
||||
|
||||
sub
|
||||
notify_Set($@)
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
my $me = $hash->{NAME};
|
||||
|
||||
return "no set argument specified" if(int(@a) < 2);
|
||||
my %sets = (addRegexpPart=>2, removeRegexpPart=>1);
|
||||
|
||||
my $cmd = $a[1];
|
||||
return "Unknown argument $cmd, choose one of " # No dropdown in FHEMWEB
|
||||
if(!defined($sets{$cmd}));
|
||||
return "$cmd needs $sets{$cmd} parameter(s)" if(@a-$sets{$cmd} != 2);
|
||||
|
||||
if($cmd eq "addRegexpPart") {
|
||||
my %h;
|
||||
my $re = "$a[2]:$a[3]";
|
||||
map { $h{$_} = 1 } split(/\|/, $hash->{REGEXP});
|
||||
$h{$re} = 1;
|
||||
$re = join("|", sort keys %h);
|
||||
return "Bad regexp: starting with *" if($re =~ m/^\*/);
|
||||
eval { "Hallo" =~ m/^$re$/ };
|
||||
return "Bad regexp: $@" if($@);
|
||||
$hash->{REGEXP} = $re;
|
||||
$hash->{DEF} = "$re $hash->{COMMAND}";
|
||||
notifyRegexpChanged($hash, $re);
|
||||
|
||||
} elsif($cmd eq "removeRegexpPart") {
|
||||
my %h;
|
||||
map { $h{$_} = 1 } split(/\|/, $hash->{REGEXP});
|
||||
return "Cannot remove regexp part: not found" if(!$h{$a[2]});
|
||||
return "Cannot remove last regexp part" if(int(keys(%h)) == 1);
|
||||
delete $h{$a[2]};
|
||||
my $re = join("|", sort keys %h);
|
||||
return "Bad regexp: starting with *" if($re =~ m/^\*/);
|
||||
eval { "Hallo" =~ m/^$re$/ };
|
||||
return "Bad regexp: $@" if($@);
|
||||
$hash->{REGEXP} = $re;
|
||||
$hash->{DEF} = "$re $hash->{COMMAND}";
|
||||
notifyRegexpChanged($hash, $re);
|
||||
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
#########################
|
||||
sub
|
||||
notify_fhemwebFn($$$$)
|
||||
{
|
||||
my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn.
|
||||
my $hash = $defs{$d};
|
||||
|
||||
my $ret .= "<br>Regexp wizard";
|
||||
my $row=0;
|
||||
$ret .= "<br><table class=\"block wide\">";
|
||||
my @ra = split(/\|/, $hash->{REGEXP});
|
||||
if(@ra > 1) {
|
||||
foreach my $r (@ra) {
|
||||
$ret .= "<tr class=\"".(($row++&1)?"odd":"even")."\">";
|
||||
my $cmd = "cmd.X= set $d removeRegexpPart&val.X=$r"; # =.set: avoid JS
|
||||
$ret .= "<td>$r</td>";
|
||||
$ret .= FW_pH("$cmd&detail=$d", "removeRegexpPart", 1,undef,1);
|
||||
$ret .= "</tr>";
|
||||
}
|
||||
}
|
||||
|
||||
my @et = devspec2array("TYPE=eventTypes");
|
||||
if(!@et) {
|
||||
$ret .= FW_pH("$FW_ME/docs/commandref.html#eventTypes",
|
||||
"To add a regexp an eventTypes definition is needed",
|
||||
1, undef, 1);
|
||||
} else {
|
||||
my %dh;
|
||||
foreach my $l (split("\n", AnalyzeCommand(undef, "get $et[0] list"))) {
|
||||
my @a = split(/[ \r\n]/, $l);
|
||||
$a[1] = "" if(!defined($a[1]));
|
||||
$a[1] =~ s/\.\*//g;
|
||||
$a[1] =~ s/,.*//g;
|
||||
next if(@a < 2);
|
||||
$dh{$a[0]}{".*"} = 1;
|
||||
$dh{$a[0]}{$a[1].".*"} = 1;
|
||||
}
|
||||
my $list = ""; my @al;
|
||||
foreach my $dev (sort keys %dh) {
|
||||
$list .= " $dev:" . join(",", sort keys %{$dh{$dev}});
|
||||
push @al, $dev;
|
||||
}
|
||||
$ret .= "<tr class=\"".(($row++&1)?"odd":"even")."\">";
|
||||
$ret .= "<td colspan=\"2\"><form autocomplete=\"off\">";
|
||||
$ret .= FW_hidden("detail", $d);
|
||||
$ret .= FW_hidden("dev.$d", "$d addRegexpPart");
|
||||
$ret .= FW_submit("cmd.$d", "set", "set");
|
||||
$ret .= "<div class=\"set downText\"> $d addRegexpPart </div>";
|
||||
$list =~ s/(['"])/./g;
|
||||
$ret .= FW_select("","arg.$d",\@al, undef, "set",
|
||||
"FW_selChange(this.options[selectedIndex].text,'$list','val.$d')");
|
||||
$ret .= FW_textfield("val.$d", 30, "set");
|
||||
$ret .= "<script type=\"text/javascript\">" .
|
||||
"FW_selChange('$al[0]','$list','val.$d')</script>";
|
||||
$ret .= "</form></td></tr>";
|
||||
}
|
||||
$ret .= "</table>";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
@ -221,7 +333,27 @@ notify_Attr(@)
|
||||
|
||||
|
||||
<a name="notifyset"></a>
|
||||
<b>Set</b> <ul>N/A</ul><br>
|
||||
<b>Set </b>
|
||||
<ul>
|
||||
<li>addRegexpPart <device> <regexp>
|
||||
<ul>
|
||||
add a regexp part, which is constructed as device:regexp. The parts
|
||||
are separated by |. Note: as the regexp parts are resorted, manually
|
||||
constructed regexps may become invalid.
|
||||
</ul>
|
||||
</li>
|
||||
<li>removeRegexpPart <re>
|
||||
<ul>
|
||||
remove a regexp part. Note: as the regexp parts are resorted, manually
|
||||
constructed regexps may become invalid.<br>
|
||||
The inconsistency in addRegexpPart/removeRegexPart arguments originates
|
||||
from the reusage of javascript functions.
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
|
||||
<a name="notifyget"></a>
|
||||
<b>Get</b> <ul>N/A</ul><br>
|
||||
@ -395,7 +527,23 @@ notify_Attr(@)
|
||||
|
||||
|
||||
<a name="notifyset"></a>
|
||||
<b>Set</b> <ul>N/A</ul><br>
|
||||
<b>Set </b>
|
||||
<ul>
|
||||
<li>addRegexpPart <device> <regexp>
|
||||
<ul>
|
||||
Fügt ein regexp Teil hinzu, der als device:regexp aufgebaut ist.
|
||||
Die Teile werden nach Regexp-Regeln mit | getrennt. Achtung: durch
|
||||
hinzufügen können manuell erzeugte Regexps ungültig
|
||||
werden.
|
||||
</ul></li>
|
||||
<li>removeRegexpPart <re>
|
||||
<ul>
|
||||
Entfernt ein regexp Teil. Die Inkonsistenz von addRegexpPart /
|
||||
removeRegexPart-Argumenten hat seinen Ursprung in der Wiederverwendung
|
||||
von Javascript-Funktionen.
|
||||
</ul></li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="notifyget"></a>
|
||||
<b>Get</b> <ul>N/A</ul><br>
|
||||
|
@ -9,7 +9,7 @@ use IO::File;
|
||||
# This block is only needed when FileLog is loaded bevore FHEMWEB
|
||||
sub FW_pO(@);
|
||||
sub FW_pH(@);
|
||||
use vars qw($FW_ME); # webname (default is fhem), needed by 97_GROUP
|
||||
use vars qw($FW_ME); # webname (default is fhem)
|
||||
use vars qw($FW_RET); # Returned data (html)
|
||||
use vars qw($FW_RETTYPE);
|
||||
use vars qw($FW_cmdret); # error msg forwarding from toSVG
|
||||
@ -183,7 +183,6 @@ FileLog_Attr(@)
|
||||
}
|
||||
|
||||
###################################
|
||||
|
||||
sub
|
||||
FileLog_Set($@)
|
||||
{
|
||||
@ -1259,26 +1258,22 @@ FileLog_sampleDataFn($$$$$)
|
||||
<ul>
|
||||
<li>reopen
|
||||
<ul>
|
||||
Erneutes Öffnen eines FileLogs nach händischen Änderungen in dieser Datei.
|
||||
</ul>
|
||||
</li>
|
||||
Erneutes Öffnen eines FileLogs nach händischen
|
||||
Änderungen in dieser Datei.
|
||||
</ul></li>
|
||||
<li>addRegexpPart <device> <regexp>
|
||||
<ul>
|
||||
Hinzufügen eines regexp Teiles, der gemäß device:regexp
|
||||
aufgebaut ist. Die Teile werden mit einem | voneinander getrennt.
|
||||
Achtung: Wenn die regexp-Teile umsortiert werden, können die
|
||||
manuell erzeugten regexps ungültig werden.
|
||||
</ul>
|
||||
</li>
|
||||
Fügt ein regexp Teil hinzu, der als device:regexp aufgebaut ist.
|
||||
Die Teile werden nach Regexp-Regeln mit | getrennt. Achtung: durch
|
||||
hinzufügen können manuell erzeugte Regexps ungültig
|
||||
werden.
|
||||
</ul></li>
|
||||
<li>removeRegexpPart <re>
|
||||
<ul>
|
||||
Entfernt ein regexp-Teil. Achtung: Wenn die regexp-Teile umsortiert
|
||||
werden, können die manuell erzeugten regexps ungültig
|
||||
werden.<br>
|
||||
Die Inkonsistenz von addRegexpPart/removeRegexPart-Argumenten hat
|
||||
seinen Ursprung in der Wiederverwendung von Javascript-Funktionen.
|
||||
</ul>
|
||||
</li>
|
||||
Entfernt ein regexp Teil. Die Inkonsistenz von addRegexpPart /
|
||||
removeRegexPart-Argumenten hat seinen Ursprung in der Wiederverwendung
|
||||
von Javascript-Funktionen.
|
||||
</ul></li>
|
||||
<li>absorb secondFileLog
|
||||
<ul>
|
||||
Führt den gegenwärtigen Log und den secondFileLog zu einer
|
||||
@ -1296,11 +1291,10 @@ FileLog_sampleDataFn($$$$$)
|
||||
<li>nur das aktuelle File wird zusammengeführt, keine
|
||||
archivierten Versionen.</li>
|
||||
<li>Weblinks, die das secondFilelog benutzen werden unbrauchbar, sie
|
||||
müssen deshalb auf das neue Logfile angepasst oder gelöscht
|
||||
werden.</li>
|
||||
müssen deshalb auf das neue Logfile angepasst oder
|
||||
gelöscht werden.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</li>
|
||||
</ul></li>
|
||||
<br>
|
||||
</ul>
|
||||
<br>
|
||||
|
@ -39,6 +39,7 @@ sub SVG_substcfg($$$$$$);
|
||||
sub SVG_time_align($$);
|
||||
sub SVG_time_to_sec($);
|
||||
sub SVG_openFile($$$);
|
||||
sub SVG_doShowLog($$$$;$$);
|
||||
|
||||
my %SVG_devs; # hash of from/to entries per device
|
||||
|
||||
@ -809,7 +810,7 @@ SVG_showLog($)
|
||||
}
|
||||
|
||||
sub
|
||||
SVG_doShowLog($$$$$$)
|
||||
SVG_doShowLog($$$$;$$)
|
||||
{
|
||||
my ($wl, $d, $type, $file, $styleW, $styleH) = @_;
|
||||
my $pm = AttrVal($wl,"plotmode",$FW_plotmode);
|
||||
|
@ -146,7 +146,7 @@ FW_longpoll()
|
||||
}
|
||||
}
|
||||
if(filter == "") {
|
||||
var sa = document.location.search.substring(1).split("&");
|
||||
var sa = location.search.substring(1).split("&");
|
||||
for(var i = 0; i < sa.length; i++) {
|
||||
if(sa[i].substring(0,5) == "room=")
|
||||
filter=sa[i];
|
||||
@ -172,7 +172,7 @@ FW_longpoll()
|
||||
if(iP != null)
|
||||
filter = filter +";iconPath="+iP;
|
||||
|
||||
var query = document.location.pathname+"?XHR=1"+
|
||||
var query = location.pathname+"?XHR=1"+
|
||||
"&inform=type=status;filter="+filter+
|
||||
"×tamp="+new Date().getTime();
|
||||
query = addcsrf(query);
|
||||
@ -292,7 +292,7 @@ FW_queryValue(cmd, qFn, qArg)
|
||||
eval(qFn.replace("%", qResp));
|
||||
delete qConn;
|
||||
}
|
||||
var query = document.location.pathname+"?cmd="+cmd+"&XHR=1"
|
||||
var query = location.pathname+"?cmd="+cmd+"&XHR=1"
|
||||
query = addcsrf(query);
|
||||
qConn.open("GET", query, true);
|
||||
qConn.send(null);
|
||||
|
@ -20,7 +20,9 @@ FW_timeCreate(el,cmd)
|
||||
if(brOff > 0) {
|
||||
par.innerHTML = par.innerHTML.substring(0, brOff).replace('"-"','"+"');
|
||||
if(cmd) {
|
||||
if(typeof FW_pollConn != "undefined")
|
||||
if(typeof cmd == "function")
|
||||
cmd(v);
|
||||
else if(typeof FW_pollConn != "undefined")
|
||||
FW_cmd(cmd.replace('%',v)+"&XHR=1");
|
||||
else
|
||||
window.location = addcsrf(cmd.replace('%',v));
|
||||
|
Loading…
x
Reference in New Issue
Block a user