2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-15 03:59:11 +00:00

fhemweb.js: add JavaScript trigger, implement red save config (Forum #31293)

git-svn-id: https://svn.fhem.de/fhem/trunk@7609 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2015-01-17 21:37:05 +00:00
parent dab46798aa
commit 7fbae0b2f4
3 changed files with 55 additions and 28 deletions

View File

@ -16,7 +16,7 @@ sub FW_answerCall($);
sub FW_dev2image($;$);
sub FW_devState($$@);
sub FW_digestCgi($);
sub FW_directNotify($$);
sub FW_directNotify($@);
sub FW_doDetail($);
sub FW_fatal($);
sub FW_fileList($);
@ -593,6 +593,7 @@ FW_answerCall($)
$filter = "room!=.+" if($filter eq "room=Unsorted");
my %h = map { $_ => 1 } devspec2array($filter);
$h{"#FHEMWEB:$FW_wname"} = 1;
$me->{inform}{devices} = \%h;
%FW_visibleDeviceHash = FW_visibleDevices();
@ -1262,6 +1263,11 @@ FW_roomOverview($)
} else {
FW_pF "<tr%s>", $l1 eq $FW_room ? " class=\"sel\"" : "";
my $class = $l1;
$class =~ s/[^A-Z0-9]/_/gi;
$class .= ($lastDefChange>$lastSavedChange) ? " changed" : ""
if($l1 eq "Save config");
# image tag if we have an icon, else empty
my $icoName = "ico$l1";
map { my ($n,$v) = split(":",$_); $icoName=$v if($l1 =~ m/$n/); }
@ -1273,7 +1279,7 @@ FW_roomOverview($)
if($l2 =~ m/.html$/ || $l2 =~ m/^http/) {
FW_pO "<td><div><a href=\"$l2\">$icon$l1</a></div></td>";
} else {
FW_pH $l2, "$icon$l1", 1;
FW_pH $l2, "$icon$l1", 1, $class;
}
FW_pO "</tr>";
}
@ -2216,16 +2222,15 @@ FW_makeEdit($$$)
my %jsTab = ( 92=>'\\\\', 34=>'\\"', 9=>'\\t', 13=>'\\r', 10=>'\\n' );
sub
FW_longpollInfo($$$$)
FW_longpollInfo($@)
{
my ($dev, $state, $html, $fmt) = @_;
my $fmt = shift;
if($fmt && $fmt eq "JSON") {
$dev =~ s/([\\"\t\r\n])/$jsTab{ord($1)}/ge;
$state =~ s/([\\"\t\r\n])/$jsTab{ord($1)}/ge;
$html =~ s/([\\"\t\r\n])/$jsTab{ord($1)}/ge;
return "[\"$dev\",\"$state\",\"$html\"]";
my @a;
map { my $x=$_; $x=~s/([\\"\t\r\n])/$jsTab{ord($1)}/ge; push @a,$x; } @_;
return '["'.join('","', @a).'"]';
} else {
return "$dev<<$state<<$html";
return join('<<', @_);
}
}
@ -2248,7 +2253,7 @@ FW_roomStatesForInform($$)
my ($allSet, $cmdlist, $txt) = FW_devState($dn, "", \%extPage);
if($defs{$dn} && $defs{$dn}{STATE} && $defs{$dn}{TYPE} ne "weblink") {
push @data,
FW_longpollInfo($dn, $defs{$dn}{STATE}, $txt, $me->{inform}{fmt});
FW_longpollInfo($me->{inform}{fmt}, $dn, $defs{$dn}{STATE}, $txt);
}
}
my $data = join("\n", map { s/\n/ /gm; $_ } @data)."\n";
@ -2260,6 +2265,16 @@ FW_Notify($$)
{
my ($ntfy, $dev) = @_;
if( $dev->{NAME} eq "global" ) {
my $n = "#FHEMWEB:$ntfy->{NAME}";
if( grep(m/^SAVE|INITIALIZED|REREADCFG|SHUTDOWN$/, @{$dev->{CHANGED}}) ) {
FW_directNotify($n, '$(".Save_config a").removeClass("changed")', '');
} elsif( grep(m/^DEFINED|MODIFIED|DELETED|ATTR|DELETEATTR$/,
@{$dev->{CHANGED}}) ) {
FW_directNotify($n, '$(".Save_config a").addClass("changed")', '');
}
}
my $h = $ntfy->{inform};
return undef if(!$h);
@ -2294,7 +2309,7 @@ FW_Notify($$)
if( !$modules{$defs{$dn}{TYPE}}{FW_atPageEnd} ) {
my ($allSet, $cmdlist, $txt) = FW_devState($dn, "", \%extPage);
($FW_wname, $FW_ME, $FW_ss, $FW_tp, $FW_subdir) = @old;
push @data, FW_longpollInfo($dn, $dev->{STATE}, $txt, $h->{fmt});
push @data, FW_longpollInfo($h->{fmt}, $dn, $dev->{STATE}, $txt);
}
#Add READINGS
@ -2306,9 +2321,9 @@ FW_Notify($$)
next; #ignore 'set' commands
}
my ($readingName,$readingVal) = split(": ",$events->[$i],2);
push @data, FW_longpollInfo("$dn-$readingName",
$readingVal,$readingVal, $h->{fmt});
push @data, FW_longpollInfo("$dn-$readingName-ts", $tn, $tn, $h->{fmt});
push @data, FW_longpollInfo($h->{fmt},
"$dn-$readingName", $readingVal,$readingVal);
push @data, FW_longpollInfo($h->{fmt}, "$dn-$readingName-ts", $tn, $tn);
}
}
}
@ -2341,16 +2356,16 @@ FW_Notify($$)
}
sub
FW_directNotify($$) # Notify without the event overhead (Forum #31293)
FW_directNotify($@) # Notify without the event overhead (Forum #31293)
{
my ($dev, $msg) = @_;
my $dev = $_[0];
foreach my $ntfy (values(%defs)) {
next if(!$ntfy->{TYPE} ||
$ntfy->{TYPE} ne "FHEMWEB" ||
!$ntfy->{inform} ||
!$ntfy->{inform}{devices}{$dev});
if(!addToWritebuffer($ntfy,
FW_longpollInfo($dev, $msg, "", $ntfy->{inform}{fmt})."\n")) {
FW_longpollInfo($ntfy->{inform}{fmt}, @_)."\n")) {
my $name = $ntfy->{NAME};
Log3 $name, 4, "Closing connection $name due to full buffer in FW_Notify";
TcpServer_Close($ntfy);

View File

@ -219,6 +219,7 @@ use vars qw(%readyfnlist); # devices which want a "readyfn"
use vars qw(%selectlist); # devices which want a "select"
use vars qw(%value); # Current values, see commandref.html
use vars qw($lastDefChange); # number of last def/attr change
use vars qw($lastSavedChange); # will be synced with lastDefChange on save
use vars qw($cmdFromAnalyze); # used by the warnings-sub
my $AttrList = "verbose:0,1,2,3,4,5 room group comment alias ".
@ -241,6 +242,7 @@ my @cmdList; # Remaining commands in a chain. Used by sleep
$init_done = 0;
$lastDefChange = 0;
$lastSavedChange = 0;
$readytimeout = ($^O eq "MSWin32") ? 0.1 : 5.0;
@ -506,6 +508,7 @@ foreach my $d (keys %defs) {
}
}
$lastSavedChange = $lastDefChange;
DoTrigger("global", "INITIALIZED", 1);
$fhem_started = time;
@ -1231,6 +1234,7 @@ CommandRereadCfg($$)
$defs{$name} = $selectlist{$name} = $cl if($name && $name ne "__anonymous__");
$inform{$name} = $informMe if($informMe);
$lastSavedChange = $lastDefChange;
DoTrigger("global", "REREADCFG", 1);
$init_done = 1;
@ -1408,6 +1412,8 @@ CommandSave($$)
next if($fh{$key} eq "1"); ## R/O include files
$ret .= "$key: $!" if(!close($fh{$key}));
}
$lastSavedChange = $lastDefChange;
return ($ret ? $ret : "Wrote configuration to $param");
}
@ -3576,8 +3582,9 @@ readingsEndUpdate($$)
my $oldvalue= $userReadings{$userReading}{value};
my $oldt= $userReadings{$userReading}{t};
#Debug "Evaluating " . $userReadings{$userReading};
# evaluate perl code
$cmdFromAnalyze = $perlCode; # For the __WARN__ sub
my $value= eval $perlCode;
$cmdFromAnalyze = undef;
my $result;
# store result
if($@) {

View File

@ -317,17 +317,22 @@ FW_doUpdate()
if(d.length != 3)
continue;
$("[informId='"+d[0]+"']").each(function(){
if(this.setValueFn) { // change the select/etc value
this.setValueFn(d[1]);
if( d[0].match(/^#FHEMWEB:/) ) {
eval(d[1]);
} else {
$(this).html(d[2]); // Readings-Value
if(d[0].match(/-ts$/)) // timestamps
$(this).addClass('changed');
$(this).find("a[href]").each(function() { FW_replaceLink(this) });
}
});
} else {
$("[informId='"+d[0]+"']").each(function(){
if(this.setValueFn) { // change the select/etc value
this.setValueFn(d[1]);
} else {
$(this).html(d[2]); // Readings-Value
if(d[0].match(/-ts$/)) // timestamps
$(this).addClass('changed');
$(this).find("a[href]").each(function() { FW_replaceLink(this) });
}
});
}
for(var w in FW_widgets)
if(FW_widgets[w].updateLine) // updateLine is deprecated, use setValueFn