FHEMWEB_JS_UMBAU: integrate it with the trunk
git-svn-id: https://svn.fhem.de/fhem/trunk@7496 2b470e98-0d58-463d-a4d8-8e2adae1ed80
38
fhem/CHANGED
@ -1,24 +1,35 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# 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.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
|
- feature: fhemweb.js rewrite based on jQuery, single-widget-implementation
|
||||||
|
- feature: SVG: multiple sources allowed, Plot-Editor
|
||||||
|
- feature: textfield-long and knob widgets
|
||||||
- added: some new icons by Rampler
|
- added: some new icons by Rampler
|
||||||
- feature: PRESENCE: new reading "presence" which contains the current (or last known)
|
- feature: PRESENCE: new reading "presence" which contains the current (or
|
||||||
presence state (can be "absent" or "present")
|
last known) presence state (can be "absent" or "present")
|
||||||
- bugfix: 70_Jabber.pm: hardening XML::Stream Process() call and fix of ssl_verify
|
- bugfix: 70_Jabber.pm: hardening XML::Stream Process() call and fix of
|
||||||
- feature: readingsGroup: allow devspec :FILTER= expressions in device selection
|
ssl_verify
|
||||||
|
- feature: readingsGroup: allow devspec :FILTER= expressions in device
|
||||||
|
selection
|
||||||
- added: 73_km200.pm for the Buderus KM200 heating controller (Sailor)
|
- added: 73_km200.pm for the Buderus KM200 heating controller (Sailor)
|
||||||
- feature: 70_XBMC: added command 'connect' to connect instantly
|
- feature: 70_XBMC: added command 'connect' to connect instantly
|
||||||
- change: FB_CALLMONITOR: use standard file read/write function to support use of configDb
|
- change: FB_CALLMONITOR: use standard file read/write function to support
|
||||||
- bugfix: FB_CALLMONITOR: fix phonebook file read when using configDb (Forum #30244)
|
use of configDb
|
||||||
- feature: 70_XBMC: added commands: openmovieid, openepisodeid, addon, jsonraw (thanks to siggi85)
|
- bugfix: FB_CALLMONITOR: fix phonebook file read when using configDb (Forum
|
||||||
|
#30244)
|
||||||
|
- feature: 70_XBMC: added commands: openmovieid, openepisodeid, addon,
|
||||||
|
jsonraw (thanks to siggi85)
|
||||||
- fix: 70_XBMC: made fork attribute to close file handles correctly
|
- fix: 70_XBMC: made fork attribute to close file handles correctly
|
||||||
- feature: 70_XBMC: added mechanism to detect disconnects (TCP)
|
- feature: 70_XBMC: added mechanism to detect disconnects (TCP)
|
||||||
- fix: 66_ECMD: avoid reading from a closed connection in ECMD_READ
|
- fix: 66_ECMD: avoid reading from a closed connection in ECMD_READ
|
||||||
- feature: 70_PIONEERAVR: readings for currentAlbum etc., more internals (network settings, moved some from readings to internals), new attributes volumeLimit & volumeLimitStraight
|
- feature: 70_PIONEERAVR: readings for currentAlbum etc., more internals
|
||||||
|
(network settings, moved some from readings to internals), new attributes
|
||||||
|
volumeLimit & volumeLimitStraight
|
||||||
- added: some new icons (hourglass, frost, sani_heating_level_XX)
|
- added: some new icons (hourglass, frost, sani_heating_level_XX)
|
||||||
- fix: sani_heating_boost (possibility to colorize)
|
- fix: sani_heating_boost (possibility to colorize)
|
||||||
- feature: FB_CALLMONITOR: add remote phonebook lookup via telnet connection
|
- feature: FB_CALLMONITOR: add remote phonebook lookup via telnet connection
|
||||||
to FritzBox (JoWiemann).
|
to FritzBox (JoWiemann).
|
||||||
- bugfix: 70_PIONEERAVR & 71_PIONEERAVRZONE: fixed not working set-extensions (on-for-timer,...)
|
- bugfix: 70_PIONEERAVR & 71_PIONEERAVRZONE: fixed not working set-extensions
|
||||||
|
(on-for-timer,...)
|
||||||
- feature: fheminfo: report third-party modules
|
- feature: fheminfo: report third-party modules
|
||||||
- feature: 99_Utils.pm: add getUniqueID, getKeyValue, setKeyValue
|
- feature: 99_Utils.pm: add getUniqueID, getKeyValue, setKeyValue
|
||||||
- feature: SMARTMON: additional parameters for smartctl
|
- feature: SMARTMON: additional parameters for smartctl
|
||||||
@ -33,7 +44,8 @@
|
|||||||
- feature: HUEDevice: allow ct presets in webCmd
|
- feature: HUEDevice: allow ct presets in webCmd
|
||||||
new subTypes extcolordimer and ctdimer
|
new subTypes extcolordimer and ctdimer
|
||||||
start support for Lightify bulbs
|
start support for Lightify bulbs
|
||||||
- added: SONOS and SONOSPLAYER to support Sonos Multiroom Audiosystems (Reinerlein)
|
- added: SONOS and SONOSPLAYER to support Sonos Multiroom Audiosystems
|
||||||
|
(Reinerlein)
|
||||||
- change: 64_ESA2000.pm: add batterystate
|
- change: 64_ESA2000.pm: add batterystate
|
||||||
- added: 42_SMARTMON: Frontend to smartctl (maintainer: hexenmeister)
|
- added: 42_SMARTMON: Frontend to smartctl (maintainer: hexenmeister)
|
||||||
- feature: 70_PushNotifier added line break in Messages (xusader)
|
- feature: 70_PushNotifier added line break in Messages (xusader)
|
||||||
@ -43,7 +55,8 @@
|
|||||||
- bugfix: FB_CALLMONITOR: fixing not working company numbers
|
- bugfix: FB_CALLMONITOR: fixing not working company numbers
|
||||||
reverse search for search.ch
|
reverse search for search.ch
|
||||||
- bugfix: 70_PushNotifier repair set function (xusader)
|
- bugfix: 70_PushNotifier repair set function (xusader)
|
||||||
- bugfix: PRESENCE: fixing not working timer, when using set [...] statusRequest
|
- bugfix: PRESENCE: fixing not working timer, when using set [...]
|
||||||
|
statusRequest
|
||||||
- bugfix: FB_CALLMONITOR: fixing reverse search for klicktel.de
|
- bugfix: FB_CALLMONITOR: fixing reverse search for klicktel.de
|
||||||
- feature: new module 52_I2C_MCP342x.pm added (klausw)
|
- feature: new module 52_I2C_MCP342x.pm added (klausw)
|
||||||
- feature: SYSMON: read cpu temp on FritzBox
|
- feature: SYSMON: read cpu temp on FritzBox
|
||||||
@ -57,7 +70,8 @@
|
|||||||
- feature: new module 98_logProxy.pm added (justme1968)
|
- feature: new module 98_logProxy.pm added (justme1968)
|
||||||
- change: 66_ECMD: ReadyFn added (fixes issue under Windows)
|
- change: 66_ECMD: ReadyFn added (fixes issue under Windows)
|
||||||
- change: 02_RSS: use a GUID in RSS; urlq source for img command
|
- change: 02_RSS: use a GUID in RSS; urlq source for img command
|
||||||
- feature: 70_PushNotifier improve usebility, configuration without cURL (xusader)
|
- feature: 70_PushNotifier improve usebility, configuration without cURL
|
||||||
|
(xusader)
|
||||||
- bugfix: SYSMON: prevent empty line im log by userReadings
|
- bugfix: SYSMON: prevent empty line im log by userReadings
|
||||||
- feature: 10_IT empfang (by bjoernh)
|
- feature: 10_IT empfang (by bjoernh)
|
||||||
- bugfix: PRESENCE: fix race condition, when delete disabled attribute and
|
- bugfix: PRESENCE: fix race condition, when delete disabled attribute and
|
||||||
|
@ -16,6 +16,7 @@ sub FW_answerCall($);
|
|||||||
sub FW_dev2image($;$);
|
sub FW_dev2image($;$);
|
||||||
sub FW_devState($$@);
|
sub FW_devState($$@);
|
||||||
sub FW_digestCgi($);
|
sub FW_digestCgi($);
|
||||||
|
sub FW_directNotify($$);
|
||||||
sub FW_doDetail($);
|
sub FW_doDetail($);
|
||||||
sub FW_fatal($);
|
sub FW_fatal($);
|
||||||
sub FW_fileList($);
|
sub FW_fileList($);
|
||||||
@ -187,11 +188,7 @@ FHEMWEB_Initialize($)
|
|||||||
closedir(DH);
|
closedir(DH);
|
||||||
}
|
}
|
||||||
|
|
||||||
$data{webCmdFn}{slider} = "FW_sliderFn";
|
$data{webCmdFn}{"~"} = "FW_widgetFallbackFn"; # Should be the last
|
||||||
$data{webCmdFn}{timepicker} = "FW_timepickerFn";
|
|
||||||
$data{webCmdFn}{noArg} = "FW_noArgFn";
|
|
||||||
$data{webCmdFn}{textField} = "FW_textFieldFn";
|
|
||||||
$data{webCmdFn}{"~dropdown"}= "FW_dropdownFn"; # Should be the last
|
|
||||||
|
|
||||||
if($init_done) { # reload workaround
|
if($init_done) { # reload workaround
|
||||||
foreach my $pe ("fhemSVG", "openautomation", "default") {
|
foreach my $pe ("fhemSVG", "openautomation", "default") {
|
||||||
@ -531,7 +528,9 @@ FW_answerCall($)
|
|||||||
$ldir = "$FW_dir/pgm2" if($dir eq "css" || $dir eq "js"); # FLOORPLAN compat
|
$ldir = "$FW_dir/pgm2" if($dir eq "css" || $dir eq "js"); # FLOORPLAN compat
|
||||||
$ldir = "$attr{global}{modpath}/docs" if($dir eq "docs");
|
$ldir = "$attr{global}{modpath}/docs" if($dir eq "docs");
|
||||||
|
|
||||||
if(-r "$ldir/$file.$ext") { # no return for FLOORPLAN
|
# pgm2 check is for jquery-ui images
|
||||||
|
my $static = ($ext =~ m/(css|js|png|jpg)/i || $dir =~ m/^pgm2/);
|
||||||
|
if(-r "$ldir/$file.$ext" || $static) { # no return for FLOORPLAN
|
||||||
return FW_serveSpecial($file, $ext, $ldir, ($arg =~ m/nocache/) ? 0 : 1);
|
return FW_serveSpecial($file, $ext, $ldir, ($arg =~ m/nocache/) ? 0 : 1);
|
||||||
}
|
}
|
||||||
$arg = "/$dir/$ofile";
|
$arg = "/$dir/$ofile";
|
||||||
@ -617,7 +616,6 @@ FW_answerCall($)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
# FHEMWEB extensions (FLOORPLOAN, SVG_WriteGplot, etc)
|
# FHEMWEB extensions (FLOORPLOAN, SVG_WriteGplot, etc)
|
||||||
my $FW_contentFunc;
|
my $FW_contentFunc;
|
||||||
@ -696,18 +694,26 @@ FW_answerCall($)
|
|||||||
FW_pO "<meta http-equiv=\"refresh\" content=\"$rf\">" if($rf);
|
FW_pO "<meta http-equiv=\"refresh\" content=\"$rf\">" if($rf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
########################
|
||||||
|
# CSS
|
||||||
my $cssTemplate = "<link href=\"$FW_ME/%s\" rel=\"stylesheet\"/>";
|
my $cssTemplate = "<link href=\"$FW_ME/%s\" rel=\"stylesheet\"/>";
|
||||||
FW_pO sprintf($cssTemplate, "pgm2/style.css");
|
FW_pO sprintf($cssTemplate, "pgm2/style.css");
|
||||||
my @cssFiles = split(" ", AttrVal($FW_wname, "CssFiles", ""));
|
FW_pO sprintf($cssTemplate, "pgm2/jquery-ui.min.css");
|
||||||
map { FW_pO sprintf($cssTemplate, $_); } @cssFiles;
|
map { FW_pO sprintf($cssTemplate, $_); }
|
||||||
|
split(" ", AttrVal($FW_wname, "CssFiles", ""));
|
||||||
|
|
||||||
|
########################
|
||||||
|
# JavaScripts
|
||||||
|
my $jsTemplate = '<script type="text/javascript" src="%s"></script>';
|
||||||
|
FW_pO sprintf($jsTemplate, "$FW_ME/pgm2/jquery.min.js");
|
||||||
|
FW_pO sprintf($jsTemplate, "$FW_ME/pgm2/jquery-ui.min.js");
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# FW Extensions
|
# FW Extensions
|
||||||
my $jsTemplate = '<script type="text/javascript" src="%s"></script>';
|
|
||||||
if(defined($data{FWEXT})) {
|
if(defined($data{FWEXT})) {
|
||||||
foreach my $k (sort keys %{$data{FWEXT}}) {
|
foreach my $k (sort keys %{$data{FWEXT}}) {
|
||||||
my $h = $data{FWEXT}{$k};
|
my $h = $data{FWEXT}{$k};
|
||||||
next if($h !~ m/HASH/ || !$h->{SCRIPT});
|
next if($h !~ m/HASH/ || !$h->{SCRIPT} || $h->{SCRIPT} =~ m+pgm2/jquery+);
|
||||||
my $script = $h->{SCRIPT};
|
my $script = $h->{SCRIPT};
|
||||||
$script = ($script =~ m,^/,) ? "$FW_ME$script" : "$FW_ME/pgm2/$script";
|
$script = ($script =~ m,^/,) ? "$FW_ME$script" : "$FW_ME/pgm2/$script";
|
||||||
FW_pO sprintf($jsTemplate, $script);
|
FW_pO sprintf($jsTemplate, $script);
|
||||||
@ -715,21 +721,18 @@ FW_answerCall($)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
# Other JavaScripts
|
# Other JavaScripts + their Attributes
|
||||||
FW_pO sprintf($jsTemplate, "$FW_ME/pgm2/svg.js") if($FW_plotmode eq "SVG");
|
|
||||||
map { FW_pO sprintf($jsTemplate, "$FW_ME/pgm2/$_") } @FW_fhemwebjs;
|
map { FW_pO sprintf($jsTemplate, "$FW_ME/pgm2/$_") } @FW_fhemwebjs;
|
||||||
|
|
||||||
$jsTemplate = '<script attr=\'%s\' type="text/javascript" src="%s"></script>';
|
$jsTemplate = '<script attr=\'%s\' type="text/javascript" src="%s"></script>';
|
||||||
map {
|
map {
|
||||||
my $n = $_; $n =~ s+.*/++; $n =~ s/.js$//; $n =~ s/fhem_//; $n .= "Param";
|
my $n = $_; $n =~ s+.*/++; $n =~ s/.js$//; $n =~ s/fhem_//; $n .= "Param";
|
||||||
FW_pO sprintf($jsTemplate, AttrVal($FW_wname, $n, ""), "$FW_ME/$_");
|
FW_pO sprintf($jsTemplate, AttrVal($FW_wname, $n, ""), "$FW_ME/$_");
|
||||||
} split(" ", AttrVal($FW_wname, "JavaScripts", ""));
|
} split(" ", AttrVal($FW_wname, "JavaScripts", ""));
|
||||||
|
|
||||||
my $onload = AttrVal($FW_wname, "longpoll", 1) ?
|
|
||||||
"onload=\"FW_delayedStart()\"" : "";
|
|
||||||
my $csrf= ($FW_CSRF ? "fwcsrf='$defs{$FW_wname}{CSRFTOKEN}'" : "");
|
my $csrf= ($FW_CSRF ? "fwcsrf='$defs{$FW_wname}{CSRFTOKEN}'" : "");
|
||||||
FW_pO "</head>\n<body generated=\"".(time()-1)
|
my $gen = 'generated="'.(time()-1).'"';
|
||||||
."\" name=\"$t\" $csrf $onload>";
|
my $lp = 'longpoll="'.AttrVal($FW_wname,"longpoll",1).'"';
|
||||||
|
FW_pO "</head>\n<body name=\"$t\" $gen $lp $csrf>";
|
||||||
|
|
||||||
if($FW_activateInform) {
|
if($FW_activateInform) {
|
||||||
$cmd = "style eventMonitor $FW_activateInform";
|
$cmd = "style eventMonitor $FW_activateInform";
|
||||||
@ -921,7 +924,7 @@ FW_makeTable($$$@)
|
|||||||
} else {
|
} else {
|
||||||
if( $title eq "Attributes" ) {
|
if( $title eq "Attributes" ) {
|
||||||
FW_pO "<td><div class=\"dname\">".
|
FW_pO "<td><div class=\"dname\">".
|
||||||
"<a onClick='FW_querySetSelected(\"sel.attr$name\",\"$n\")'>".
|
"<a onClick='FW_querySetSelected(\"sel_attr$name\",\"$n\")'>".
|
||||||
"$n</a></div></td>";
|
"$n</a></div></td>";
|
||||||
} else {
|
} else {
|
||||||
FW_pO "<td><div class=\"dname\">$n</div></td>";
|
FW_pO "<td><div class=\"dname\">$n</div></td>";
|
||||||
@ -978,7 +981,7 @@ FW_makeTable($$$@)
|
|||||||
##############################
|
##############################
|
||||||
# Used only for set or attr lists.
|
# Used only for set or attr lists.
|
||||||
sub
|
sub
|
||||||
FW_makeSelect($$$$)
|
FW_detailSelect($$$$)
|
||||||
{
|
{
|
||||||
my ($d, $cmd, $list,$class) = @_;
|
my ($d, $cmd, $list,$class) = @_;
|
||||||
return if(!$list || $FW_hiddenroom{input});
|
return if(!$list || $FW_hiddenroom{input});
|
||||||
@ -987,8 +990,9 @@ FW_makeSelect($$$$)
|
|||||||
my $selEl = (defined($al[0]) ? $al[0] : " ");
|
my $selEl = (defined($al[0]) ? $al[0] : " ");
|
||||||
$selEl = $1 if($list =~ m/([^ ]*):slider,/); # promote a slider if available
|
$selEl = $1 if($list =~ m/([^ ]*):slider,/); # promote a slider if available
|
||||||
$selEl = "room" if($list =~ m/room:/);
|
$selEl = "room" if($list =~ m/room:/);
|
||||||
|
$list =~ s/"/"/g;
|
||||||
|
|
||||||
FW_pO "<div class='makeSelect'>";
|
FW_pO "<div class='makeSelect' dev=\"$d\" cmd=\"$cmd\" list=\"$list\">";
|
||||||
FW_pO "<form method=\"$FW_formmethod\" ".
|
FW_pO "<form method=\"$FW_formmethod\" ".
|
||||||
"action=\"$FW_ME$FW_subdir\" autocomplete=\"off\">";
|
"action=\"$FW_ME$FW_subdir\" autocomplete=\"off\">";
|
||||||
FW_pO FW_hidden("detail", $d);
|
FW_pO FW_hidden("detail", $d);
|
||||||
@ -996,12 +1000,8 @@ FW_makeSelect($$$$)
|
|||||||
FW_pO FW_hidden("dev.$cmd$d", $d);
|
FW_pO FW_hidden("dev.$cmd$d", $d);
|
||||||
FW_pO FW_submit("cmd.$cmd$d", $cmd, $class);
|
FW_pO FW_submit("cmd.$cmd$d", $cmd, $class);
|
||||||
FW_pO "<div class=\"$class downText\"> $d </div>";
|
FW_pO "<div class=\"$class downText\"> $d </div>";
|
||||||
FW_pO FW_select("sel.$cmd$d","arg.$cmd$d",\@al, $selEl, $class,
|
FW_pO FW_select("sel_$cmd$d","arg.$cmd$d",\@al, $selEl, $class);
|
||||||
"FW_selChange(this.options[selectedIndex].text,'$list','val.$cmd$d')");
|
|
||||||
FW_pO FW_textfield("val.$cmd$d", 30, $class);
|
FW_pO FW_textfield("val.$cmd$d", 30, $class);
|
||||||
# Initial setting
|
|
||||||
FW_pO "<script type=\"text/javascript\">" .
|
|
||||||
"FW_selChange('$selEl','$list','val.$cmd$d')</script>";
|
|
||||||
FW_pO "</form></div>";
|
FW_pO "</form></div>";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1037,12 +1037,8 @@ FW_doDetail($)
|
|||||||
use strict "refs";
|
use strict "refs";
|
||||||
}
|
}
|
||||||
|
|
||||||
FW_pO "<form method=\"$FW_formmethod\" action=\"$FW_ME\">";
|
FW_detailSelect($d, "set", FW_widgetOverride($d, getAllSets($d)), "set");
|
||||||
FW_pO FW_hidden("detail", $d);
|
FW_detailSelect($d, "get", FW_widgetOverride($d, getAllGets($d)), "get");
|
||||||
FW_pO FW_hidden("fwcsrf", $defs{$FW_wname}{CSRFTOKEN}) if($FW_CSRF);
|
|
||||||
|
|
||||||
FW_makeSelect($d, "set", FW_widgetOverride($d, getAllSets($d)), "set");
|
|
||||||
FW_makeSelect($d, "get", FW_widgetOverride($d, getAllGets($d)), "get");
|
|
||||||
|
|
||||||
FW_makeTable("Internals", $d, $h);
|
FW_makeTable("Internals", $d, $h);
|
||||||
FW_makeTable("Readings", $d, $h->{READINGS});
|
FW_makeTable("Readings", $d, $h->{READINGS});
|
||||||
@ -1057,7 +1053,7 @@ FW_doDetail($)
|
|||||||
$attrList = FW_widgetOverride($d, $attrList);
|
$attrList = FW_widgetOverride($d, $attrList);
|
||||||
$attrList =~ s/\\/\\\\/g;
|
$attrList =~ s/\\/\\\\/g;
|
||||||
$attrList =~ s/'/\\'/g;
|
$attrList =~ s/'/\\'/g;
|
||||||
FW_makeSelect($d, "attr", $attrList,"attr");
|
FW_detailSelect($d, "attr", $attrList,"attr");
|
||||||
|
|
||||||
FW_makeTable("Attributes", $d, $attr{$d}, "deleteattr");
|
FW_makeTable("Attributes", $d, $attr{$d}, "deleteattr");
|
||||||
## dependent objects
|
## dependent objects
|
||||||
@ -1070,7 +1066,6 @@ FW_doDetail($)
|
|||||||
push(@dob, $dn);
|
push(@dob, $dn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FW_pO "</form>";
|
|
||||||
FW_makeTableFromArray("Probably associated with", "assoc", @dob,);
|
FW_makeTableFromArray("Probably associated with", "assoc", @dob,);
|
||||||
|
|
||||||
FW_pO "</td></tr></table>";
|
FW_pO "</td></tr></table>";
|
||||||
@ -1078,6 +1073,7 @@ FW_doDetail($)
|
|||||||
FW_pH "cmd=style iconFor $d", "Select icon";
|
FW_pH "cmd=style iconFor $d", "Select icon";
|
||||||
FW_pH "cmd=style showDSI $d", "Extend devStateIcon";
|
FW_pH "cmd=style showDSI $d", "Extend devStateIcon";
|
||||||
FW_pH "$FW_ME/docs/commandref.html#${t}", "Device specific help";
|
FW_pH "$FW_ME/docs/commandref.html#${t}", "Device specific help";
|
||||||
|
FW_pH "cmd=delete $d", "Delete this device ($d)" if($d ne "global");
|
||||||
FW_pO "<br><br>";
|
FW_pO "<br><br>";
|
||||||
FW_pO "</div>";
|
FW_pO "</div>";
|
||||||
|
|
||||||
@ -1300,7 +1296,7 @@ FW_showRoom()
|
|||||||
$FW_hiddengroup{$r} = 1;
|
$FW_hiddengroup{$r} = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FW_pO "<form method=\"$FW_formmethod\" ".
|
FW_pO "<form method=\"$FW_formmethod\" ". # Why do we need a form here?
|
||||||
"action=\"$FW_ME\" autocomplete=\"off\">";
|
"action=\"$FW_ME\" autocomplete=\"off\">";
|
||||||
FW_pO "<div id=\"content\" room=\"$FW_room\">";
|
FW_pO "<div id=\"content\" room=\"$FW_room\">";
|
||||||
FW_pO "<table class=\"roomoverview\">"; # Need for equal width of subtables
|
FW_pO "<table class=\"roomoverview\">"; # Need for equal width of subtables
|
||||||
@ -1358,7 +1354,7 @@ FW_showRoom()
|
|||||||
$icon = FW_makeImage($icon,$icon,"icon") . " " if($icon);
|
$icon = FW_makeImage($icon,$icon,"icon") . " " if($icon);
|
||||||
|
|
||||||
if($FW_hiddenroom{detail}) {
|
if($FW_hiddenroom{detail}) {
|
||||||
FW_pO "<td><div class=\"col1\">$icon$devName</div></td>";
|
FW_pO "<td><div class=\"col1\">$icon$devName</div></td>" if(!$usuallyAtEnd{$d});
|
||||||
} else {
|
} else {
|
||||||
FW_pH "detail=$d", "$icon$devName", 1, "col1" if(!$usuallyAtEnd{$d});
|
FW_pH "detail=$d", "$icon$devName", 1, "col1" if(!$usuallyAtEnd{$d});
|
||||||
}
|
}
|
||||||
@ -1506,8 +1502,10 @@ FW_returnFileAsStream($$$$$)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!open(FH, $path)) {
|
if(!open(FH, $path)) {
|
||||||
Log3 $FW_wname, 2, "FHEMWEB $FW_wname $path: $!";
|
Log3 $FW_wname, 4, "FHEMWEB $FW_wname $path: $!";
|
||||||
FW_pO "<div id=\"content\">$path: $!</div>";
|
TcpServer_WriteBlocking($FW_chash,
|
||||||
|
"HTTP/1.1 404 Not Found\r\n".
|
||||||
|
"Content-Length:0\r\n\r\n");
|
||||||
FW_closeConn($FW_chash);
|
FW_closeConn($FW_chash);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1569,12 +1567,12 @@ FW_hidden($$)
|
|||||||
sub
|
sub
|
||||||
FW_select($$$$$@)
|
FW_select($$$$$@)
|
||||||
{
|
{
|
||||||
my ($id, $n, $va, $def, $class, $jSelFn) = @_;
|
my ($id, $name, $valueArray, $selected, $class, $jSelFn) = @_;
|
||||||
$jSelFn = ($jSelFn ? "onchange=\"$jSelFn\"" : "");
|
$jSelFn = ($jSelFn ? "onchange=\"$jSelFn\"" : "");
|
||||||
$id = ($id ? "id=\"$id\" informId=\"$id\"" : "");
|
$id = ($id ? "id=\"$id\" informId=\"$id\"" : "");
|
||||||
my $s = "<select $jSelFn $id name=\"$n\" class=\"$class\">";
|
my $s = "<select $jSelFn $id name=\"$name\" class=\"$class\">";
|
||||||
foreach my $v (@{$va}) {
|
foreach my $v (@{$valueArray}) {
|
||||||
if(defined($def) && $v eq $def) {
|
if(defined($selected) && $v eq $selected) {
|
||||||
$s .= "<option selected=\"selected\" value='$v'>$v</option>\n";
|
$s .= "<option selected=\"selected\" value='$v'>$v</option>\n";
|
||||||
} else {
|
} else {
|
||||||
$s .= "<option value='$v'>$v</option>\n";
|
$s .= "<option value='$v'>$v</option>\n";
|
||||||
@ -1750,14 +1748,16 @@ FW_style($$)
|
|||||||
my $filePath = FW_fileNameToPath($fileName);
|
my $filePath = FW_fileNameToPath($fileName);
|
||||||
|
|
||||||
$FW_data =~ s/\r//g;
|
$FW_data =~ s/\r//g;
|
||||||
my $err = FileWrite({FileName=>$filePath, ForceType=>$forceType}, split("\n", $FW_data));
|
my $err = FileWrite({FileName=>$filePath, ForceType=>$forceType},
|
||||||
|
split("\n", $FW_data));
|
||||||
if($err) {
|
if($err) {
|
||||||
FW_pO "<div id=\"content\">$filePath: $!</div>";
|
FW_pO "<div id=\"content\">$filePath: $!</div>";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
my $ret = FW_fC("rereadcfg") if($filePath eq $attr{global}{configfile});
|
my $ret = FW_fC("rereadcfg") if($filePath eq $attr{global}{configfile});
|
||||||
$ret = FW_fC("reload $fileName") if($fileName =~ m,\.pm$,);
|
$ret = FW_fC("reload $fileName") if($fileName =~ m,\.pm$,);
|
||||||
$ret = ($ret ? "<h3>ERROR:</h3><b>$ret</b>" : "Saved the file $fileName to $forceType");
|
$ret = ($ret ? "<h3>ERROR:</h3><b>$ret</b>" :
|
||||||
|
"Saved the file $fileName to $forceType");
|
||||||
FW_style("style list", $ret);
|
FW_style("style list", $ret);
|
||||||
$ret = "";
|
$ret = "";
|
||||||
|
|
||||||
@ -2201,6 +2201,16 @@ FW_makeEdit($$$)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub
|
||||||
|
FW_longpollInfo($$$)
|
||||||
|
{
|
||||||
|
my ($dev, $state, $html) = @_;
|
||||||
|
$dev =~ s/([\\"])/\\$1/g;
|
||||||
|
$state =~ s/([\\"])/\\$1/g;
|
||||||
|
$html =~ s/([\\"])/\\$1/g;
|
||||||
|
return "[\"$dev\",\"$state\",\"$html\"]";
|
||||||
|
}
|
||||||
|
|
||||||
sub
|
sub
|
||||||
FW_roomStatesForInform($$)
|
FW_roomStatesForInform($$)
|
||||||
{
|
{
|
||||||
@ -2219,7 +2229,7 @@ FW_roomStatesForInform($$)
|
|||||||
|
|
||||||
my ($allSet, $cmdlist, $txt) = FW_devState($dn, "", \%extPage);
|
my ($allSet, $cmdlist, $txt) = FW_devState($dn, "", \%extPage);
|
||||||
if($defs{$dn} && $defs{$dn}{STATE} && $defs{$dn}{TYPE} ne "weblink") {
|
if($defs{$dn} && $defs{$dn}{STATE} && $defs{$dn}{TYPE} ne "weblink") {
|
||||||
push @data, "$dn<<$defs{$dn}{STATE}<<$txt";
|
push @data, FW_longpollInfo($dn, $defs{$dn}{STATE}, $txt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my $data = join("\n", map { s/\n/ /gm; $_ } @data)."\n";
|
my $data = join("\n", map { s/\n/ /gm; $_ } @data)."\n";
|
||||||
@ -2265,7 +2275,7 @@ FW_Notify($$)
|
|||||||
if( !$modules{$defs{$dn}{TYPE}}{FW_atPageEnd} ) {
|
if( !$modules{$defs{$dn}{TYPE}}{FW_atPageEnd} ) {
|
||||||
my ($allSet, $cmdlist, $txt) = FW_devState($dn, "", \%extPage);
|
my ($allSet, $cmdlist, $txt) = FW_devState($dn, "", \%extPage);
|
||||||
($FW_wname, $FW_ME, $FW_ss, $FW_tp, $FW_subdir) = @old;
|
($FW_wname, $FW_ME, $FW_ss, $FW_tp, $FW_subdir) = @old;
|
||||||
push @data, "$dn<<$dev->{STATE}<<$txt";
|
push @data, FW_longpollInfo($dn, $dev->{STATE}, $txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
#Add READINGS
|
#Add READINGS
|
||||||
@ -2277,8 +2287,8 @@ FW_Notify($$)
|
|||||||
next; #ignore 'set' commands
|
next; #ignore 'set' commands
|
||||||
}
|
}
|
||||||
my ($readingName,$readingVal) = split(": ",$events->[$i],2);
|
my ($readingName,$readingVal) = split(": ",$events->[$i],2);
|
||||||
push @data, "$dn-$readingName<<$readingVal<<$readingVal";
|
push @data, FW_longpollInfo("$dn-$readingName",$readingVal,$readingVal);
|
||||||
push @data, "$dn-$readingName-ts<<$tn<<$tn";
|
push @data, FW_longpollInfo("$dn-$readingName-ts", $tn, $tn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2310,6 +2320,24 @@ FW_Notify($$)
|
|||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
FW_directNotify($$) # Notify without the event overhead (Forum #31293)
|
||||||
|
{
|
||||||
|
my ($dev, $msg) = @_;
|
||||||
|
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, "")."\n")){
|
||||||
|
my $name = $ntfy->{NAME};
|
||||||
|
Log3 $name, 4, "Closing connection $name due to full buffer in FW_Notify";
|
||||||
|
TcpServer_Close($ntfy);
|
||||||
|
delete($defs{$name});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# Compute the state (==second) column
|
# Compute the state (==second) column
|
||||||
sub
|
sub
|
||||||
@ -2371,16 +2399,7 @@ FW_devState($$@)
|
|||||||
}
|
}
|
||||||
$link .= "&room=$room";
|
$link .= "&room=$room";
|
||||||
}
|
}
|
||||||
if(AttrVal($FW_wname, "longpoll", 1)) {
|
$txt = "<a href=\"$FW_ME$FW_subdir?$link$rf$FW_CSRF\">$txt</a>";
|
||||||
$txt = "<a onClick=\"FW_cmd('$FW_ME$FW_subdir?XHR=1&$link')\">$txt</a>";
|
|
||||||
|
|
||||||
} elsif($FW_ss || $FW_tp) {
|
|
||||||
$txt ="<a onClick=\"location.href='$FW_ME$FW_subdir?$link$rf$FW_CSRF'\">$txt</a>";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$txt = "<a href=\"$FW_ME$FW_subdir?$link$rf$FW_CSRF\">$txt</a>";
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
my $style = AttrVal($d, "devStateStyle", "");
|
my $style = AttrVal($d, "devStateStyle", "");
|
||||||
@ -2487,125 +2506,32 @@ FW_htmlEscape($)
|
|||||||
|
|
||||||
###########################
|
###########################
|
||||||
# Widgets START
|
# Widgets START
|
||||||
sub
|
|
||||||
FW_sliderFn($$$$$)
|
|
||||||
{
|
|
||||||
my ($FW_wname, $d, $FW_room, $cmd, $values) = @_;
|
|
||||||
|
|
||||||
return undef if($values !~ m/^slider,([-\d.]*),([-\d.]*),([-\d.]*)(,1)?$/);
|
|
||||||
return "" if($cmd =~ m/ /); # webCmd pct 30 should generate a link
|
|
||||||
my ($min,$stp, $max, $flt) = ($1, $2, $3, $4);
|
|
||||||
$flt = ($flt ? 1 : 0);
|
|
||||||
my $srf = $FW_room ? "&room=$FW_room" : "";
|
|
||||||
my $cv = ReadingsVal($d, $cmd, Value($d));
|
|
||||||
my $id = ($cmd eq "state") ? "" : "-$cmd";
|
|
||||||
$cmd = "" if($cmd eq "state");
|
|
||||||
$cv =~ s/.*?([.\-\d]+).*/$1/; # get first number
|
|
||||||
$cv = 0 if($cv !~ m/\d/);
|
|
||||||
return "<td colspan='2'>".
|
|
||||||
"<div class='slider' id='slider.$d$id' min='$min' stp='$stp' ".
|
|
||||||
"max='$max' cmd='$FW_ME?cmd=set $d $cmd %$srf' flt='$flt'>".
|
|
||||||
"<div class='handle'>$min</div>".
|
|
||||||
"</div>".
|
|
||||||
"<script type=\"text/javascript\">".
|
|
||||||
"FW_sliderCreate(document.getElementById('slider.$d$id'),'$cv');".
|
|
||||||
"</script>".
|
|
||||||
"</td>";
|
|
||||||
}
|
|
||||||
|
|
||||||
sub
|
|
||||||
FW_noArgFn($$$$$)
|
|
||||||
{
|
|
||||||
my ($FW_wname, $d, $FW_room, $cmd, $values) = @_;
|
|
||||||
|
|
||||||
return undef if($values !~ m/^noArg$/);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
sub
|
|
||||||
FW_timepickerFn()
|
|
||||||
{
|
|
||||||
my ($FW_wname, $d, $FW_room, $cmd, $values) = @_;
|
|
||||||
|
|
||||||
return undef if($values ne "time");
|
|
||||||
return "" if($cmd =~ m/ /); # webCmd on-for-timer 30 should generate a link
|
|
||||||
my $srf = $FW_room ? "&room=$FW_room" : "";
|
|
||||||
my $cv = ReadingsVal($d, $cmd, Value($d));
|
|
||||||
$cmd = "" if($cmd eq "state");
|
|
||||||
my $c = "\"$FW_ME?cmd=set $d $cmd %$srf\"";
|
|
||||||
return "<td colspan='2'>".
|
|
||||||
"<input name='time.$d' value='$cv' type='text' readonly size='5'>".
|
|
||||||
"<input type='button' value='+' onclick='FW_timeCreate(this,$c)'>".
|
|
||||||
"</td>";
|
|
||||||
}
|
|
||||||
|
|
||||||
sub
|
sub
|
||||||
FW_dropdownFn()
|
FW_widgetFallbackFn()
|
||||||
{
|
{
|
||||||
my ($FW_wname, $d, $FW_room, $cmd, $values) = @_;
|
my ($FW_wname, $d, $FW_room, $cmd, $values) = @_;
|
||||||
|
|
||||||
return "" if($cmd =~ m/ /); # webCmd temp 30 should generate a link
|
# webCmd "temp 30" should remain text
|
||||||
my @tv = split(",", $values);
|
# noArg is needed for fhem.cfg.demo / Cinema
|
||||||
# Hack: eventmap (translation only) should not result in a
|
return "" if(!$values || $values eq "noArg");
|
||||||
# dropdown. eventMap/webCmd/etc handling must be cleaned up.
|
|
||||||
if(@tv > 1) {
|
my($reading) = split( ' ', $cmd, 2 );
|
||||||
my $txt;
|
my $current;
|
||||||
if($cmd eq "desired-temp" || $cmd eq "desiredTemperature") {
|
if($cmd eq "desired-temp" || $cmd eq "desiredTemperature") {
|
||||||
$txt = ReadingsVal($d, $cmd, 20);
|
$current = ReadingsVal($d, $cmd, 20);
|
||||||
$txt =~ s/ .*//; # Cut off Celsius
|
$current =~ s/ .*//; # Cut off Celsius
|
||||||
$txt = sprintf("%2.1f", int(2*$txt)/2) if($txt =~ m/[0-9.-]/);
|
$current = sprintf("%2.1f", int(2*$current)/2) if($current =~ m/[0-9.-]/);
|
||||||
} else {
|
} else {
|
||||||
$txt = ReadingsVal($d, $cmd, Value($d));
|
$current = ReadingsVal($d, $reading, undef);
|
||||||
$txt =~ s/$cmd //;
|
if( !defined($current) ) {
|
||||||
|
$reading = 'state';
|
||||||
|
$current = Value($d);
|
||||||
}
|
}
|
||||||
|
$current =~ s/$cmd //;
|
||||||
my $fpname = $FW_wname;
|
|
||||||
$fpname =~ s/.*floorplan\/(\w+)$/$1/; #allow usage of attr fp_setbutton
|
|
||||||
|
|
||||||
my $readng = ($cmd eq "state" ? "" : "$cmd"." ");
|
|
||||||
|
|
||||||
# TODO in case of running in a floorplan split $FW_wname to get name of
|
|
||||||
# webInstance. Actually in floorplan the dropdown will refresh the page
|
|
||||||
# always independently from setting in corresponding web instance, cause
|
|
||||||
# statement if( AttrVal($FW_wname, "longpoll", 0) == 1) will always fail.
|
|
||||||
my $selFunct="";
|
|
||||||
if( AttrVal($FW_wname, "longpoll", 0) == 1) {
|
|
||||||
$selFunct = "FW_cmd('$FW_ME?XHR=1&cmd.$d=set $d $readng '+ ".
|
|
||||||
"this.options[this.selectedIndex].value+ ' &room=$FW_room')";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$selFunct = "window.location = addcsrf('$FW_ME?cmd.$d=set $d $readng '+".
|
|
||||||
"this.options[this.selectedIndex].value+ ' &room=$FW_room')";
|
|
||||||
|
|
||||||
}
|
|
||||||
my $fwsel;
|
|
||||||
$fwsel = ($cmd eq "state" ? "" : "$cmd ") .
|
|
||||||
FW_select("$d-$cmd","val.$d", \@tv, $txt,"dropdown","$selFunct");
|
|
||||||
return "<td colspan='2'>$fwsel</td>";
|
|
||||||
}
|
}
|
||||||
return undef;
|
return "<td><div class='fhemWidget' cmd='$cmd' reading='$reading' ".
|
||||||
|
"dev='$d' arg='$values' current='$current'></div></td>";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub
|
|
||||||
FW_textFieldFn($$$$)
|
|
||||||
{
|
|
||||||
my ($FW_wname, $d, $FW_room, $cmd, $values) = @_;
|
|
||||||
|
|
||||||
my @args = split("[ \t]+", $cmd);
|
|
||||||
|
|
||||||
return undef if($values !~ m/^textField$/);
|
|
||||||
return "" if($cmd =~ m/ /);
|
|
||||||
my $srf = $FW_room ? "&room=$FW_room" : "";
|
|
||||||
my $cv = ReadingsVal($d, $cmd, "");
|
|
||||||
my $id = ($cmd eq "state") ? "" : "-$cmd";
|
|
||||||
|
|
||||||
my $c = "$FW_ME?XHR=1&cmd=setreading $d $cmd %$srf";
|
|
||||||
return '<td align="center">'.
|
|
||||||
"<div>$cmd:<input id='textField.$d$id' type='text' value='$cv' ".
|
|
||||||
"onChange='textField_setText(this,\"$c\")'></div>".
|
|
||||||
'</td>';
|
|
||||||
}
|
|
||||||
|
|
||||||
# Widgets END
|
# Widgets END
|
||||||
###########################
|
###########################
|
||||||
|
|
||||||
@ -3148,18 +3074,23 @@ FW_widgetOverride($$)
|
|||||||
<li>if the modifier is ":time", then a javascript driven timepicker is
|
<li>if the modifier is ":time", then a javascript driven timepicker is
|
||||||
displayed.</li>
|
displayed.</li>
|
||||||
<li>if the modifier is ":textField", an input field is displayed.</li>
|
<li>if the modifier is ":textField", an input field is displayed.</li>
|
||||||
|
<li>if the modifier is ":textField-long", is like textField, but upon
|
||||||
|
clicking on the input field a textArea (60x25) will be opened.</li>
|
||||||
|
|
||||||
<li>if the modifier is of the form
|
<li>if the modifier is of the form
|
||||||
":slider,<min>,<step>,<max>[,1]", then a
|
":slider,<min>,<step>,<max>[,1]", then a
|
||||||
javascript driven slider is displayed. The optional ,1 at the end
|
javascript driven slider is displayed. The optional ,1 at the end
|
||||||
avoids the rounding of floating-point numbers.</li>
|
avoids the rounding of floating-point numbers.</li>
|
||||||
|
|
||||||
<li>if the modifier is of the form ":multiple,val1,val2,...", then
|
<li>if the modifier is of the form ":multiple,val1,val2,...", then
|
||||||
multiple values can be selected and own values can be written, the
|
multiple values can be selected and own values can be written, the
|
||||||
result is comma separated.</li>
|
result is comma separated.</li>
|
||||||
<li>if the modifier is of the form ":multiple-strict,val1,val2,...", then
|
<li>if the modifier is of the form ":multiple-strict,val1,val2,...",
|
||||||
multiple values can be selected and no new values can be added, the
|
then multiple values can be selected and no new values can be
|
||||||
result is comma separated.</li>
|
added, the result is comma separated.</li>
|
||||||
|
<li>if the modifier is of the form ":knob,min:1,max:100,...", then
|
||||||
|
the jQuery knob widget will be displayed. The parameters are
|
||||||
|
specified as a comma separated list of key:value pairs, where key
|
||||||
|
does not have to contain the "data-" prefix.</li>
|
||||||
<li>else a dropdown with all the modifier values is displayed</li>
|
<li>else a dropdown with all the modifier values is displayed</li>
|
||||||
</ul>
|
</ul>
|
||||||
If this attribute is specified for a FHEMWEB instance, then it is
|
If this attribute is specified for a FHEMWEB instance, then it is
|
||||||
@ -3167,6 +3098,7 @@ FW_widgetOverride($$)
|
|||||||
<ul>
|
<ul>
|
||||||
attr FS20dev widgetOverride on-till:time<br>
|
attr FS20dev widgetOverride on-till:time<br>
|
||||||
attr WEB widgetOverride room:textField<br>
|
attr WEB widgetOverride room:textField<br>
|
||||||
|
attr dimmer widgetOverride dim:knob,min:1,max:100,step:1,linecap:round<br>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<br>
|
<br>
|
||||||
@ -3714,13 +3646,17 @@ FW_widgetOverride($$)
|
|||||||
vorgesehene Widgets aendern kann.
|
vorgesehene Widgets aendern kann.
|
||||||
<ul>
|
<ul>
|
||||||
<li>Ist der Modifier ":noArg", wird kein weiteres Eingabefeld
|
<li>Ist der Modifier ":noArg", wird kein weiteres Eingabefeld
|
||||||
angezeigt.</li>
|
angezeigt.</li>
|
||||||
|
|
||||||
<li>Ist der Modifier ":time", wird ein in Javaskript geschreibenes
|
<li>Ist der Modifier ":time", wird ein in Javaskript geschreibenes
|
||||||
Zeitauswahlmenü angezeigt.</li>
|
Zeitauswahlmenü angezeigt.</li>
|
||||||
|
|
||||||
<li>Ist der Modifier ":textField", wird ein Eingabefeld
|
<li>Ist der Modifier ":textField", wird ein Eingabefeld
|
||||||
angezeigt.</li>
|
angezeigt.</li>
|
||||||
|
|
||||||
|
<li>Ist der Modified ":textField-long" ist wie textField, aber beim
|
||||||
|
Click im Eingabefeld ein Dialog mit einer HTML textarea
|
||||||
|
(60x25) wird geöffnet.</li>
|
||||||
|
|
||||||
<li>Ist der Modifier in der Form
|
<li>Ist der Modifier in der Form
|
||||||
":slider,<min>,<step>,<max>[,1]", so wird ein in
|
":slider,<min>,<step>,<max>[,1]", so wird ein in
|
||||||
@ -3735,8 +3671,15 @@ FW_widgetOverride($$)
|
|||||||
Mehrfachauswahl möglich, es können jedoch keine neuen
|
Mehrfachauswahl möglich, es können jedoch keine neuen
|
||||||
Werte definiert werden. Das Ergebnis ist Komma-separiert.</li>
|
Werte definiert werden. Das Ergebnis ist Komma-separiert.</li>
|
||||||
|
|
||||||
<li>In allen anderen Fällen erscheint ein Dropdown mit allen
|
<li>Ist der Modifier ":knob,min:1,max:100,...", dass ein
|
||||||
Modifier Werten.</li>
|
jQuery knob Widget wird angezeigt. Die Parameter werden als eine
|
||||||
|
Komma separierte Liste von Key:Value Paaren spezifiziert, wobei das
|
||||||
|
data- Präfix entfällt. </li>
|
||||||
|
|
||||||
|
<li>In allen anderen Fällen (oder falls der Modified explizit
|
||||||
|
mit :select anfaegt) erscheint ein HTML select mit allen Modifier
|
||||||
|
Werten.</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
Falls das Attribut für eine WEB Instanz gesetzt wurde, dann wird
|
Falls das Attribut für eine WEB Instanz gesetzt wurde, dann wird
|
||||||
es bei allen von diesem Web-Instan angezeigten Geräten angewendet.
|
es bei allen von diesem Web-Instan angezeigten Geräten angewendet.
|
||||||
@ -3744,6 +3687,7 @@ FW_widgetOverride($$)
|
|||||||
<ul>
|
<ul>
|
||||||
attr FS20dev widgetOverride on-till:time<br>
|
attr FS20dev widgetOverride on-till:time<br>
|
||||||
attr WEB widgetOverride room:textField<br>
|
attr WEB widgetOverride room:textField<br>
|
||||||
|
attr dimmer widgetOverride dim:knob,min:1,max:100,step:1,linecap:round<br>
|
||||||
</ul>
|
</ul>
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
|
@ -273,23 +273,18 @@ return "<br>Timespec wizard:".
|
|||||||
</tr><tr class="even"><td>Timespec</td>
|
</tr><tr class="even"><td>Timespec</td>
|
||||||
<td><input type="text" id="aw_pts"></td>
|
<td><input type="text" id="aw_pts"></td>
|
||||||
</tr><tr class="even"><td>Timespec</td>
|
</tr><tr class="even"><td>Timespec</td>
|
||||||
<td><input type="text" readonly id="aw_ts" size="5">
|
<td><input type="text" name="aw_ts" id="aw_ts" size="5"></td>
|
||||||
<input type='button' value='+' id="aw_tsb"></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tr><tr class="even">
|
</tr><tr class="even">
|
||||||
<td colspan="2"><input type="button" id="aw_md" value="Modify"></td>
|
<td colspan="2"><input type="button" id="aw_md" value="Modify"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
loadScript("pgm2/jquery.min.js", atDetails);
|
|
||||||
function
|
|
||||||
atDetails()
|
|
||||||
{
|
{
|
||||||
var t=$("#atWizard"), ip=$(t).attr("ip"), ts=$(t).attr("ts");
|
var t=$("#atWizard"), ip=$(t).attr("ip"), ts=$(t).attr("ts");
|
||||||
|
FW_replaceWidget("#aw_ts", "aw_ts", ["time"], "12:00");
|
||||||
|
$("[informid=aw_ts] input[type=text]").attr("id", "aw_ts");
|
||||||
|
|
||||||
function tsClick() {
|
|
||||||
FW_timeCreate(this, function(val) { $("#aw_tsb").click(tsClick) })
|
|
||||||
}
|
|
||||||
function ipClick() {
|
function ipClick() {
|
||||||
var c = $("#aw_ip").prop("checked");
|
var c = $("#aw_ip").prop("checked");
|
||||||
$("#aw_ts").closest("tr").css("display", !c ? "table-row" : "none");
|
$("#aw_ts").closest("tr").css("display", !c ? "table-row" : "none");
|
||||||
@ -300,7 +295,6 @@ return "<br>Timespec wizard:".
|
|||||||
$("#aw_ip").prop("checked", ip);
|
$("#aw_ip").prop("checked", ip);
|
||||||
$("#aw_ts").val(ip ? "12:00" : ts);
|
$("#aw_ts").val(ip ? "12:00" : ts);
|
||||||
$("#aw_pts").val(ip ? ts : 'sunset()');
|
$("#aw_pts").val(ip ? ts : 'sunset()');
|
||||||
$("#aw_tsb").click(tsClick);
|
|
||||||
$("#aw_ip").change(ipClick);
|
$("#aw_ip").change(ipClick);
|
||||||
ipClick();
|
ipClick();
|
||||||
$("#aw_md").click(function(){
|
$("#aw_md").click(function(){
|
||||||
|
@ -951,8 +951,8 @@ FileLog_sampleDataFn($$$$$)
|
|||||||
for(my $r=0; $r < $max; $r++) {
|
for(my $r=0; $r < $max; $r++) {
|
||||||
my @f = split(":", ($flog->[$r] ? $flog->[$r] : ":::"), 4);
|
my @f = split(":", ($flog->[$r] ? $flog->[$r] : ":::"), 4);
|
||||||
my $ret = "";
|
my $ret = "";
|
||||||
$ret .= SVG_sel("par_${r}_0", $colnums, $f[0]);
|
$ret .= SVG_sel("par_${r}_0", $colnums, $f[0], undef, "svgColumn");
|
||||||
$ret .= SVG_sel("par_${r}_1", $colregs, $f[1]);
|
$ret .= SVG_sel("par_${r}_1", $colregs, $f[1], undef, "svgRegexp");
|
||||||
$ret .= SVG_txt("par_${r}_2", "", $f[2], 1);
|
$ret .= SVG_txt("par_${r}_2", "", $f[2], 1);
|
||||||
$ret .= SVG_txt("par_${r}_3", "", $f[3], 6);
|
$ret .= SVG_txt("par_${r}_3", "", $f[3], 6);
|
||||||
push @htmlArr, $ret;
|
push @htmlArr, $ret;
|
||||||
|
@ -32,7 +32,7 @@ sub SVG_calcOffsets($$);
|
|||||||
sub SVG_doround($$$);
|
sub SVG_doround($$$);
|
||||||
sub SVG_fmtTime($$);
|
sub SVG_fmtTime($$);
|
||||||
sub SVG_pO($);
|
sub SVG_pO($);
|
||||||
sub SVG_readgplotfile($$);
|
sub SVG_readgplotfile($$$);
|
||||||
sub SVG_render($$$$$$$$$;$$);
|
sub SVG_render($$$$$$$$$;$$);
|
||||||
sub SVG_showLog($);
|
sub SVG_showLog($);
|
||||||
sub SVG_substcfg($$$$$$);
|
sub SVG_substcfg($$$$$$);
|
||||||
@ -40,8 +40,12 @@ sub SVG_time_align($$);
|
|||||||
sub SVG_time_to_sec($);
|
sub SVG_time_to_sec($);
|
||||||
sub SVG_openFile($$$);
|
sub SVG_openFile($$$);
|
||||||
sub SVG_doShowLog($$$$;$$);
|
sub SVG_doShowLog($$$$;$$);
|
||||||
|
sub SVG_getData($$$$$);
|
||||||
|
sub SVG_sel($$$;$$);
|
||||||
|
|
||||||
my %SVG_devs; # hash of from/to entries per device
|
my %SVG_devs; # hash of from/to entries per device
|
||||||
|
my $SVG_id=0;
|
||||||
|
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
sub
|
sub
|
||||||
@ -50,7 +54,8 @@ SVG_Initialize($)
|
|||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
|
|
||||||
$hash->{DefFn} = "SVG_Define";
|
$hash->{DefFn} = "SVG_Define";
|
||||||
$hash->{AttrList} = "fixedoffset fixedrange startDate plotsize nrAxis label title plotfunction";
|
$hash->{AttrList} = "fixedoffset fixedrange startDate plotsize nrAxis ".
|
||||||
|
"label title plotfunction";
|
||||||
$hash->{SetFn} = "SVG_Set";
|
$hash->{SetFn} = "SVG_Set";
|
||||||
$hash->{FW_summaryFn} = "SVG_FwFn";
|
$hash->{FW_summaryFn} = "SVG_FwFn";
|
||||||
$hash->{FW_detailFn} = "SVG_FwFn";
|
$hash->{FW_detailFn} = "SVG_FwFn";
|
||||||
@ -133,6 +138,21 @@ jsSVG_getAttrs($)
|
|||||||
} keys %{$attr{$d}});
|
} keys %{$attr{$d}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
SVG_getplotsize($)
|
||||||
|
{
|
||||||
|
my ($d) = @_;
|
||||||
|
return $FW_webArgs{plotsize} ?
|
||||||
|
$FW_webArgs{plotsize} : AttrVal($d,"plotsize",$FW_plotsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
SVG_isEmbed($)
|
||||||
|
{
|
||||||
|
return (AttrVal($FW_wname, "plotEmbed",
|
||||||
|
$FW_userAgent !~ m/(iPhone|iPad|iPod).*OS (8|9)/));
|
||||||
|
}
|
||||||
|
|
||||||
##################
|
##################
|
||||||
sub
|
sub
|
||||||
SVG_FwFn($$$$)
|
SVG_FwFn($$$$)
|
||||||
@ -141,6 +161,11 @@ SVG_FwFn($$$$)
|
|||||||
my $hash = $defs{$d};
|
my $hash = $defs{$d};
|
||||||
my $ret = "";
|
my $ret = "";
|
||||||
|
|
||||||
|
if(!$pageHash || !$pageHash->{jsLoaded}) {
|
||||||
|
$ret .= "<script type='text/javascript' src='$FW_ME/pgm2/svg.js'></script>";
|
||||||
|
$pageHash->{jsLoaded} = 1 if($pageHash);
|
||||||
|
}
|
||||||
|
|
||||||
if(AttrVal($FW_wname, "plotmode", "SVG") eq "jsSVG") {
|
if(AttrVal($FW_wname, "plotmode", "SVG") eq "jsSVG") {
|
||||||
|
|
||||||
my @d=split(":",$defs{$d}{DEF});
|
my @d=split(":",$defs{$d}{DEF});
|
||||||
@ -182,11 +207,10 @@ SVG_FwFn($$$$)
|
|||||||
"&pos=" . join(";", map {"$_=$FW_pos{$_}"} keys %FW_pos);
|
"&pos=" . join(";", map {"$_=$FW_pos{$_}"} keys %FW_pos);
|
||||||
|
|
||||||
if(AttrVal($d,"plotmode",$FW_plotmode) eq "SVG") {
|
if(AttrVal($d,"plotmode",$FW_plotmode) eq "SVG") {
|
||||||
my ($w, $h) = split(",", AttrVal($d,"plotsize",$FW_plotsize));
|
my ($w, $h) = split(",", SVG_getplotsize($d));
|
||||||
$ret .= "<div class=\"SVGplot SVG_$d\">";
|
$ret .= "<div class=\"SVGplot SVG_$d\">";
|
||||||
|
|
||||||
if(AttrVal($FW_wname, "plotEmbed",
|
if(SVG_isEmbed($FW_wname)) {
|
||||||
$FW_userAgent !~ m/(iPhone|iPad|iPod).*OS (8|9)/)) {
|
|
||||||
$ret .= "<embed src=\"$arg\" type=\"image/svg+xml\" " .
|
$ret .= "<embed src=\"$arg\" type=\"image/svg+xml\" " .
|
||||||
"width=\"$w\" height=\"$h\" name=\"$d\"/>\n";
|
"width=\"$w\" height=\"$h\" name=\"$d\"/>\n";
|
||||||
|
|
||||||
@ -236,12 +260,12 @@ SVG_txt($$$$)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub
|
sub
|
||||||
SVG_sel($$$@)
|
SVG_sel($$$;$$)
|
||||||
{
|
{
|
||||||
my ($v,$l,$c,$fnData) = @_;
|
my ($v,$l,$c,$fnData,$class) = @_;
|
||||||
my @al = split(",",$l);
|
my @al = split(",",$l);
|
||||||
$c =~ s/\\x3a/:/g if($c);
|
$c =~ s/\\x3a/:/g if($c);
|
||||||
return FW_select($v,$v,\@al,$c, "set", $fnData);
|
return FW_select(undef,$v,\@al,$c, $class?$class:"set", $fnData);
|
||||||
}
|
}
|
||||||
|
|
||||||
############################
|
############################
|
||||||
@ -255,12 +279,10 @@ SVG_PEdit($$$$)
|
|||||||
|
|
||||||
return "" if( $pe eq 'never' );
|
return "" if( $pe eq 'never' );
|
||||||
|
|
||||||
my $ld = $defs{$d}{LOGDEVICE};
|
|
||||||
my $ldt = $defs{$ld}{TYPE};
|
|
||||||
|
|
||||||
my $gp = "$FW_gplotdir/$defs{$d}{GPLOTFILE}.gplot";
|
my $gp = "$FW_gplotdir/$defs{$d}{GPLOTFILE}.gplot";
|
||||||
|
my $pm = AttrVal($d,"plotmode",$FW_plotmode);
|
||||||
|
|
||||||
my ($err, $cfg, $plot, $flog) = SVG_readgplotfile($d, $gp);
|
my ($err, $cfg, $plot, $srcDesc) = SVG_readgplotfile($d, $gp, $pm);
|
||||||
my %conf = SVG_digestConf($cfg, $plot);
|
my %conf = SVG_digestConf($cfg, $plot);
|
||||||
|
|
||||||
my $ret = "<br>";
|
my $ret = "<br>";
|
||||||
@ -280,8 +302,6 @@ SVG_PEdit($$$$)
|
|||||||
"action=\"$FW_ME/SVG_WriteGplot\">";
|
"action=\"$FW_ME/SVG_WriteGplot\">";
|
||||||
$ret .= "Plot Editor";
|
$ret .= "Plot Editor";
|
||||||
$ret .= FW_hidden("detail", $d); # go to detail after save
|
$ret .= FW_hidden("detail", $d); # go to detail after save
|
||||||
$ret .= FW_hidden("gplotName", $gp);
|
|
||||||
$ret .= FW_hidden("logdevicetype", $ldt);
|
|
||||||
if(defined($FW_pos{zoom}) && defined($FW_pos{off})) { # for showData
|
if(defined($FW_pos{zoom}) && defined($FW_pos{off})) { # for showData
|
||||||
$ret .= FW_hidden("pos", "zoom=$FW_pos{zoom};off=$FW_pos{off}");
|
$ret .= FW_hidden("pos", "zoom=$FW_pos{zoom};off=$FW_pos{off}");
|
||||||
}
|
}
|
||||||
@ -314,22 +334,39 @@ SVG_PEdit($$$$)
|
|||||||
$ret .= "</tr>";
|
$ret .= "</tr>";
|
||||||
|
|
||||||
my $max = @{$conf{lType}}+1;
|
my $max = @{$conf{lType}}+1;
|
||||||
my ($desc, $htmlArr, $example) = ("Spec", undef, "");
|
my ($desc, $cnt) = ("Spec", 0);
|
||||||
if($modules{$ldt}{SVG_sampleDataFn}) {
|
my (@srcHtml, @paramHtml, @exampleHtml, @revIdx);
|
||||||
no strict "refs";
|
my @srcNames = grep { $modules{$defs{$_}{TYPE}}{SVG_sampleDataFn} }
|
||||||
($desc, $htmlArr, $example) =
|
sort keys %defs;
|
||||||
&{$modules{$ldt}{SVG_sampleDataFn}}($ld, $flog, $max,\%conf, $FW_wname);
|
|
||||||
use strict "refs";
|
|
||||||
} else {
|
|
||||||
my @htmlArr;
|
|
||||||
@htmlArr = map { SVG_txt("par_${_}_0","",$flog->[$_] ? $flog->[$_]:"",20) }
|
|
||||||
(0..$max-1);
|
|
||||||
$htmlArr = \@htmlArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ret .= "<tr class=\"odd\"><td>Diagramm label</td>";
|
foreach my $src (@{$srcDesc->{order}}) {
|
||||||
$ret .= "<td>$desc</td>";
|
my $lmax = $srcDesc->{src}{$src}{idx}+1;
|
||||||
$ret .=" <td>Y-Axis,Plot-Type,Style,Width</td></tr>";
|
my $fn = $modules{$defs{$src}{TYPE}}{SVG_sampleDataFn};
|
||||||
|
my @argArr = split(" ", $srcDesc->{src}{$src}{arg});
|
||||||
|
if($fn) {
|
||||||
|
no strict "refs";
|
||||||
|
my ($ldesc, $paramHtml, $example) =
|
||||||
|
&{$fn}($src, \@argArr, $lmax,\%conf, $FW_wname);
|
||||||
|
use strict "refs";
|
||||||
|
$desc = $ldesc;
|
||||||
|
push @paramHtml, @{$paramHtml};
|
||||||
|
map { push @exampleHtml, $example } (0..$lmax-1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
push @paramHtml, map { SVG_txt("par_${_}_0","",$_,20) } @argArr;
|
||||||
|
map { push @exampleHtml, "" } (0..$lmax-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
push @srcHtml,
|
||||||
|
map { FW_select(undef,"src_$_",\@srcNames,$src,"svgSrc");} (0..$lmax-1);
|
||||||
|
map { push @revIdx,$srcDesc->{rev}{$cnt}{$_}; } (0..$lmax-1);
|
||||||
|
$cnt++;
|
||||||
|
}
|
||||||
|
# Last, empty line
|
||||||
|
push @revIdx,int(@revIdx);
|
||||||
|
push @srcHtml, $srcHtml[0];
|
||||||
|
push @paramHtml, $paramHtml[0];
|
||||||
|
push @exampleHtml, $exampleHtml[0];
|
||||||
|
|
||||||
my @lineStyles;
|
my @lineStyles;
|
||||||
if(SVG_openFile($FW_cssdir,
|
if(SVG_openFile($FW_cssdir,
|
||||||
@ -338,33 +375,46 @@ SVG_PEdit($$$$)
|
|||||||
close(FH);
|
close(FH);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $r = 0;
|
$ret .= "<tr class=\"odd\"><td>Diagramm label, Source</td>";
|
||||||
|
$ret .= "<td>$desc</td>";
|
||||||
|
$ret .=" <td>Y-Axis,Plot-Type,Style,Width</td></tr>";
|
||||||
|
|
||||||
|
|
||||||
|
my ($r, $example, @output) = (0, "");
|
||||||
for($r=0; $r < $max; $r++) {
|
for($r=0; $r < $max; $r++) {
|
||||||
$ret .= "<tr class=\"".(($r&1)?"odd":"even")."\"><td>";
|
my $idx = $revIdx[$r];
|
||||||
$ret .= SVG_txt("title_${r}", "", !$conf{lTitle}[$r]&&$r<($max-1) ?
|
$example .= "<div class='ex ex_$idx' style='display:".($idx?"none":"block").
|
||||||
"notitle" : $conf{lTitle}[$r], 12);
|
"'>$exampleHtml[$r]</div>";
|
||||||
$ret .= "</td><td>";
|
my $o = "<tr row='$idx' class=\"".(($r&1)?"odd":"even")."\"><td>";
|
||||||
$ret .= $htmlArr->[$r] if($htmlArr && @{$htmlArr} > $r);
|
$o .= SVG_txt("title_$idx", "", !$conf{lTitle}[$idx]&&$idx<($max-1) ?
|
||||||
$ret .= "</td><td>";
|
"notitle" : $conf{lTitle}[$idx], 12);
|
||||||
my $v = $conf{lAxis}[$r];
|
my $sh = $srcHtml[$r]; $sh =~ s/src_\d+/src_$idx/g;
|
||||||
$ret .= SVG_sel("axes_${r}", "left,right",
|
$o .= $sh;
|
||||||
|
$o .= "</td><td>";
|
||||||
|
my $ph = $paramHtml[$r]; $ph =~ s/par_\d+_/par_${idx}_/g;
|
||||||
|
$o .= $ph;
|
||||||
|
$o .= "</td><td>";
|
||||||
|
my $v = $conf{lAxis}[$idx];
|
||||||
|
$o .= SVG_sel("axes_${idx}", "left,right",
|
||||||
($v && $v eq "x1y1") ? "left" : "right");
|
($v && $v eq "x1y1") ? "left" : "right");
|
||||||
$ret .= SVG_sel("type_${r}", "lines,points,steps,fsteps,histeps,bars",
|
$o .= SVG_sel("type_${idx}", "lines,points,steps,fsteps,histeps,bars",
|
||||||
$conf{lType}[$r]);
|
$conf{lType}[$idx]);
|
||||||
my $ls = $conf{lStyle}[$r];
|
my $ls = $conf{lStyle}[$idx];
|
||||||
if($ls) {
|
if($ls) {
|
||||||
$ls =~ s/class=//g;
|
$ls =~ s/class=//g;
|
||||||
$ls =~ s/"//g;
|
$ls =~ s/"//g;
|
||||||
}
|
}
|
||||||
$ret .= SVG_sel("style_${r}", join(",", @lineStyles), $ls);
|
$o .= SVG_sel("style_$idx", join(",", @lineStyles), $ls);
|
||||||
my $lw = $conf{lWidth}[$r];
|
my $lw = $conf{lWidth}[$idx];
|
||||||
if($lw) {
|
if($lw) {
|
||||||
$lw =~ s/.*stroke-width://g;
|
$lw =~ s/.*stroke-width://g;
|
||||||
$lw =~ s/"//g;
|
$lw =~ s/"//g;
|
||||||
}
|
}
|
||||||
$ret .= SVG_sel("width_${r}", "0.2,0.5,1,1.5,2,3,4", ($lw ? $lw : 1));
|
$o .= SVG_sel("width_$idx", "0.2,0.5,1,1.5,2,3,4", ($lw ? $lw : 1));
|
||||||
$ret .= "</td></tr>";
|
$o .= "</td></tr>";
|
||||||
|
$output[$idx] = $o;
|
||||||
}
|
}
|
||||||
|
$ret .= join("", @output);
|
||||||
$ret .= "<tr class=\"".(($r++&1)?"odd":"even")."\"><td colspan=\"3\">";
|
$ret .= "<tr class=\"".(($r++&1)?"odd":"even")."\"><td colspan=\"3\">";
|
||||||
$ret .= "Example lines for input:<br>$example</td></tr>";
|
$ret .= "Example lines for input:<br>$example</td></tr>";
|
||||||
|
|
||||||
@ -374,6 +424,32 @@ SVG_PEdit($$$$)
|
|||||||
"</td></tr>";
|
"</td></tr>";
|
||||||
|
|
||||||
$ret .= "</table></form>";
|
$ret .= "</table></form>";
|
||||||
|
|
||||||
|
my $sl = "$FW_ME/SVG_WriteGplot?detail=$d&showFileLogData=1";
|
||||||
|
if(defined($FW_pos{zoom}) && defined($FW_pos{off})) {
|
||||||
|
$sl .= "&pos=zoom=$FW_pos{zoom};off=$FW_pos{off}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret .= <<'EOF';
|
||||||
|
<script type="text/javascript">
|
||||||
|
var sel = "table.plotEditor tr[row] ";
|
||||||
|
$(sel+"input,"+sel+"select").focus(function(){
|
||||||
|
var row = $(this).closest("tr").attr("row");
|
||||||
|
$("table.plotEditor div.ex").css("display","none");
|
||||||
|
$("table.plotEditor div.ex_"+row).css("display","block");
|
||||||
|
});
|
||||||
|
$("table.plotEditor input[name=title_0]").focus();
|
||||||
|
$("table.plotEditor input[name=showFileLogData]").click(function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
EOF
|
||||||
|
$ret .=
|
||||||
|
"FW_cmd('$sl', function(arg){" .<<'EOF';
|
||||||
|
FW_okDialog(arg);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
EOF
|
||||||
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
##################
|
##################
|
||||||
@ -439,6 +515,7 @@ SVG_zoomLink($$$)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Debugging: show the data received from GET
|
||||||
sub
|
sub
|
||||||
SVG_showData()
|
SVG_showData()
|
||||||
{
|
{
|
||||||
@ -446,17 +523,15 @@ SVG_showData()
|
|||||||
my $hash = $defs{$wl};
|
my $hash = $defs{$wl};
|
||||||
my ($d, $gplotfile, $file) = split(":", $hash->{DEF});
|
my ($d, $gplotfile, $file) = split(":", $hash->{DEF});
|
||||||
$gplotfile = "$FW_gplotdir/$gplotfile.gplot";
|
$gplotfile = "$FW_gplotdir/$gplotfile.gplot";
|
||||||
my ($err, $cfg, $plot, $flog) = SVG_readgplotfile($wl, $gplotfile);
|
my $pm = AttrVal($d,"plotmode",$FW_plotmode);
|
||||||
|
my ($err, $cfg, $plot, $srcDesc) = SVG_readgplotfile($wl, $gplotfile, $pm);
|
||||||
if($err) {
|
if($err) {
|
||||||
$FW_RET=$err;
|
$FW_RET=$err;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
SVG_calcOffsets($d, $wl);
|
SVG_calcOffsets($d, $wl);
|
||||||
my ($f,$t)=($SVG_devs{$d}{from}, $SVG_devs{$d}{to});
|
$FW_RET = SVG_getData($d, $SVG_devs{$d}{from}, $SVG_devs{$d}{to}, $srcDesc,1);
|
||||||
my $cmd = "get $d $file - $f $t " . join(" ", @{$flog});
|
$FW_RET =~ s/\n/<br>/gs;
|
||||||
my $ret = FW_fC($cmd, 1);
|
|
||||||
$ret =~ s/\n/<br>/gs;
|
|
||||||
$FW_RET = "$cmd<br><br>$ret";
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,7 +555,8 @@ SVG_WriteGplot($)
|
|||||||
}
|
}
|
||||||
return 0 if(!$maxLines);
|
return 0 if(!$maxLines);
|
||||||
|
|
||||||
my $fName = $FW_webArgs{gplotName};
|
my $wlName = $FW_webArgs{detail};
|
||||||
|
my $fName = "$FW_gplotdir/$defs{$wlName}{GPLOTFILE}.gplot";
|
||||||
return if(!$fName);
|
return if(!$fName);
|
||||||
|
|
||||||
my @rows;
|
my @rows;
|
||||||
@ -501,7 +577,6 @@ SVG_WriteGplot($)
|
|||||||
push @rows, "set y2range $FW_webArgs{y2range}" if($FW_webArgs{y2range});
|
push @rows, "set y2range $FW_webArgs{y2range}" if($FW_webArgs{y2range});
|
||||||
push @rows, "";
|
push @rows, "";
|
||||||
|
|
||||||
my $ld = $FW_webArgs{logdevicetype};
|
|
||||||
my @plot;
|
my @plot;
|
||||||
for(my $i=0; $i <= $maxLines; $i++) {
|
for(my $i=0; $i <= $maxLines; $i++) {
|
||||||
next if(!$FW_webArgs{"title_$i"});
|
next if(!$FW_webArgs{"title_$i"});
|
||||||
@ -512,7 +587,8 @@ SVG_WriteGplot($)
|
|||||||
join(":", map { $v[$_] =~ s/:/\\x3a/g if($_<$#v); $v[$_] } 0..$#v) :
|
join(":", map { $v[$_] =~ s/:/\\x3a/g if($_<$#v); $v[$_] } 0..$#v) :
|
||||||
$v[0];
|
$v[0];
|
||||||
|
|
||||||
push @rows, "#$ld $r";
|
my $src = $FW_webArgs{"src_$i"};
|
||||||
|
push @rows, "#$src $r";
|
||||||
push @plot, "\"<IN>\" using 1:2 axes ".
|
push @plot, "\"<IN>\" using 1:2 axes ".
|
||||||
($FW_webArgs{"axes_$i"} eq "right" ? "x1y2" : "x1y1").
|
($FW_webArgs{"axes_$i"} eq "right" ? "x1y2" : "x1y1").
|
||||||
($FW_webArgs{"title_$i"} eq "notitle" ? " notitle" :
|
($FW_webArgs{"title_$i"} eq "notitle" ? " notitle" :
|
||||||
@ -536,31 +612,51 @@ SVG_WriteGplot($)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#######################################################
|
||||||
|
# srcDesc:
|
||||||
|
# - {all} : space separated plot arguments, in the file order, without devname
|
||||||
|
# - {order}: unique name of the devs (FileLog,etc) in the .gplot order
|
||||||
|
# - {src}{X}: hash (X is an order element), consisting of
|
||||||
|
# {arg}: plot arguments for one dev, space separated
|
||||||
|
# {idx}: number of lines requested from the same source
|
||||||
|
# {num}: number or this src in the order array
|
||||||
|
# - {rev}{orderIdx}{localIdx} = N: reverse lookup of the plot argument index,
|
||||||
|
# using {src}{X}{num} as orderIdx and {src}{X}{idx} as localIdx
|
||||||
sub
|
sub
|
||||||
SVG_readgplotfile($$)
|
SVG_readgplotfile($$$)
|
||||||
{
|
{
|
||||||
my ($wl, $gplot_pgm) = @_;
|
my ($wl, $gplot_pgm, $plotmode) = @_;
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# Read in the template gnuplot file. Digest the #FileLog lines. Replace
|
# Read in the template gnuplot file. Digest the #FileLog lines. Replace
|
||||||
# the plot directive with our own, as we offer a file for each line
|
# the plot directive with our own, as we offer a file for each line
|
||||||
my (@filelog, @data, $plot);
|
my (%srcDesc, @data, $plot);
|
||||||
|
|
||||||
|
my $ld = $defs{$wl}{LOGDEVICE}
|
||||||
|
if($defs{$wl} && $defs{$wl}{LOGDEVICE});
|
||||||
my $ldType = $defs{$defs{$wl}{LOGDEVICE}}{TYPE}
|
my $ldType = $defs{$defs{$wl}{LOGDEVICE}}{TYPE}
|
||||||
if($defs{$wl} && $defs{$wl}{LOGDEVICE} && $defs{$defs{$wl}{LOGDEVICE}});
|
if($ld && $defs{$ld});
|
||||||
$ldType = $defs{$wl}{TYPE}
|
if(!$ldType && $defs{$wl}) {
|
||||||
if(!$ldType && $defs{$wl});
|
$ldType = $defs{$wl}{TYPE};
|
||||||
|
$ld = $wl;
|
||||||
|
}
|
||||||
|
|
||||||
my ($err, @svgplotfile) = FileRead($gplot_pgm);
|
my ($err, @svgplotfile) = FileRead($gplot_pgm);
|
||||||
return ("$err", undef) if($err);
|
return ("$err", undef) if($err);
|
||||||
|
my ($plotfnCnt, $srcNum) = (0,0);
|
||||||
|
my @empty;
|
||||||
|
$srcDesc{all} = "";
|
||||||
|
$srcDesc{order} = \@empty;
|
||||||
|
|
||||||
foreach my $l (@svgplotfile) {
|
foreach my $l (@svgplotfile) {
|
||||||
$l = "$l\n" unless $l =~ m/\n$/;
|
$l = "$l\n" unless $l =~ m/\n$/;
|
||||||
my $plotfn = undef;
|
my ($src, $plotfn) = (undef, undef);
|
||||||
if($l =~ m/^#$ldType (.*)$/) {
|
if($l =~ m/^#([^ ]*) (.*)$/) {
|
||||||
$plotfn = $1;
|
if($1 eq $ldType) {
|
||||||
Log 3, "$wl: space is not allowed in $ldType definition: $plotfn"
|
$src = $ld; $plotfn = $2;
|
||||||
if($plotfn =~ m/\s/);
|
} elsif($defs{$1}) {
|
||||||
|
$src = $1; $plotfn = $2;
|
||||||
|
}
|
||||||
} elsif($l =~ "^plot" || $plot) {
|
} elsif($l =~ "^plot" || $plot) {
|
||||||
$plot .= $l;
|
$plot .= $l;
|
||||||
} else {
|
} else {
|
||||||
@ -568,6 +664,8 @@ SVG_readgplotfile($$)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($plotfn) {
|
if($plotfn) {
|
||||||
|
Log 3, "$wl: space is not allowed in $ldType definition: $plotfn"
|
||||||
|
if($plotfn =~ m/\s/);
|
||||||
my $specval = AttrVal($wl, "plotfunction", undef);
|
my $specval = AttrVal($wl, "plotfunction", undef);
|
||||||
if ($specval) {
|
if ($specval) {
|
||||||
my @spec = split(" ",$specval);
|
my @spec = split(" ",$specval);
|
||||||
@ -577,11 +675,22 @@ SVG_readgplotfile($$)
|
|||||||
$spec_count++;
|
$spec_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push(@filelog, $plotfn);
|
|
||||||
|
my $p = $srcDesc{src}{$src};
|
||||||
|
if(!$p) {
|
||||||
|
$p = { arg => $plotfn, idx=>0, num=>$srcNum++ };
|
||||||
|
$srcDesc{src}{$src} = $p;
|
||||||
|
push(@{$srcDesc{order}}, $src);
|
||||||
|
} else {
|
||||||
|
$p->{arg} .= " $plotfn";
|
||||||
|
$p->{idx}++;
|
||||||
|
}
|
||||||
|
$srcDesc{rev}{$p->{num}}{$p->{idx}} = $plotfnCnt++;
|
||||||
|
$srcDesc{all} .= " $plotfn";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (undef, \@data, $plot, \@filelog);
|
return (undef, \@data, $plot, \%srcDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub
|
sub
|
||||||
@ -592,9 +701,6 @@ SVG_substcfg($$$$$$)
|
|||||||
# interpret title and label as a perl command and make
|
# interpret title and label as a perl command and make
|
||||||
# to all internal values e.g. $value.
|
# to all internal values e.g. $value.
|
||||||
|
|
||||||
my $oll = $attr{global}{verbose};
|
|
||||||
$attr{global}{verbose} = 0; # Else the filenames will be Log'ged
|
|
||||||
|
|
||||||
my $ldt = $defs{$defs{$wl}{LOGDEVICE}}{TYPE}
|
my $ldt = $defs{$defs{$wl}{LOGDEVICE}}{TYPE}
|
||||||
if($defs{$wl} && $defs{$wl}{LOGDEVICE});
|
if($defs{$wl} && $defs{$wl}{LOGDEVICE});
|
||||||
$ldt = "" if(!defined($ldt));
|
$ldt = "" if(!defined($ldt));
|
||||||
@ -605,17 +711,17 @@ SVG_substcfg($$$$$$)
|
|||||||
my $fileesc = $file;
|
my $fileesc = $file;
|
||||||
$fileesc =~ s/\\/\\\\/g; # For Windows, by MarkusRR
|
$fileesc =~ s/\\/\\\\/g; # For Windows, by MarkusRR
|
||||||
my $title = AttrVal($wl, "title", "\"$fileesc\"");
|
my $title = AttrVal($wl, "title", "\"$fileesc\"");
|
||||||
|
my $allowed = AttrVal($FW_wname,"allowedCommands",undef);
|
||||||
|
|
||||||
$title = AnalyzeCommand(undef, "{ $title }");
|
$title = AnalyzeCommand(undef, "{ $title }", $allowed);
|
||||||
my $label = AttrVal($wl, "label", undef);
|
my $label = AttrVal($wl, "label", undef);
|
||||||
my @g_label;
|
my @g_label;
|
||||||
if ($label) {
|
if ($label) {
|
||||||
@g_label = split("::",$label);
|
@g_label = split("::",$label);
|
||||||
foreach (@g_label) {
|
foreach (@g_label) {
|
||||||
$_ = AnalyzeCommand(undef, "{ $_ }");
|
$_ = AnalyzeCommand(undef, "{ $_ }", $allowed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$attr{global}{verbose} = $oll;
|
|
||||||
|
|
||||||
my $gplot_script = join("", @{$cfg});
|
my $gplot_script = join("", @{$cfg});
|
||||||
$gplot_script .= $plot if(!$splitret);
|
$gplot_script .= $plot if(!$splitret);
|
||||||
@ -623,7 +729,7 @@ SVG_substcfg($$$$$$)
|
|||||||
$gplot_script =~ s/<OUT>/$tmpfile/g;
|
$gplot_script =~ s/<OUT>/$tmpfile/g;
|
||||||
$gplot_script =~ s/<IN>/$file/g;
|
$gplot_script =~ s/<IN>/$file/g;
|
||||||
|
|
||||||
my $ps = AttrVal($wl,"plotsize",$FW_plotsize);
|
my $ps = SVG_getplotsize($wl);
|
||||||
$gplot_script =~ s/<SIZE>/$ps/g;
|
$gplot_script =~ s/<SIZE>/$ps/g;
|
||||||
|
|
||||||
$gplot_script =~ s/<TL>/$title/g;
|
$gplot_script =~ s/<TL>/$title/g;
|
||||||
@ -816,10 +922,9 @@ SVG_doShowLog($$$$;$$)
|
|||||||
{
|
{
|
||||||
my ($wl, $d, $type, $file, $styleW, $styleH) = @_;
|
my ($wl, $d, $type, $file, $styleW, $styleH) = @_;
|
||||||
my $pm = AttrVal($wl,"plotmode",$FW_plotmode);
|
my $pm = AttrVal($wl,"plotmode",$FW_plotmode);
|
||||||
|
|
||||||
my $gplot_pgm = "$FW_gplotdir/$type.gplot";
|
my $gplot_pgm = "$FW_gplotdir/$type.gplot";
|
||||||
|
|
||||||
my ($err, $cfg, $plot, $flog) = SVG_readgplotfile($wl, $gplot_pgm);
|
my ($err, $cfg, $plot, $srcDesc) = SVG_readgplotfile($wl, $gplot_pgm, $pm);
|
||||||
if($err || !$defs{$d}) {
|
if($err || !$defs{$d}) {
|
||||||
my $msg = ($defs{$d} ? "Cannot read $gplot_pgm" : "No Logdevice $d");
|
my $msg = ($defs{$d} ? "Cannot read $gplot_pgm" : "No Logdevice $d");
|
||||||
Log3 $FW_wname, 1, $msg;
|
Log3 $FW_wname, 1, $msg;
|
||||||
@ -851,8 +956,8 @@ SVG_doShowLog($$$$;$$)
|
|||||||
# Read the data from the filelog
|
# Read the data from the filelog
|
||||||
my $oll = $attr{global}{verbose};
|
my $oll = $attr{global}{verbose};
|
||||||
$attr{global}{verbose} = 0; # Else the filenames will be Log'ged
|
$attr{global}{verbose} = 0; # Else the filenames will be Log'ged
|
||||||
my @path = split(" ", FW_fC("get $d $file $tmpfile $f $t " .
|
my @path = split(" ",
|
||||||
join(" ", @{$flog})));
|
FW_fC("get $d $file $tmpfile $f $t $srcDesc->{all}"));
|
||||||
$attr{global}{verbose} = $oll;
|
$attr{global}{verbose} = $oll;
|
||||||
|
|
||||||
# replace the path with the temporary filenames of the filelog output
|
# replace the path with the temporary filenames of the filelog output
|
||||||
@ -878,8 +983,8 @@ SVG_doShowLog($$$$;$$)
|
|||||||
my ($f,$t)=($SVG_devs{$d}{from}, $SVG_devs{$d}{to});
|
my ($f,$t)=($SVG_devs{$d}{from}, $SVG_devs{$d}{to});
|
||||||
my $oll = $attr{global}{verbose};
|
my $oll = $attr{global}{verbose};
|
||||||
$attr{global}{verbose} = 0; # Else the filenames will be Log'ged
|
$attr{global}{verbose} = 0; # Else the filenames will be Log'ged
|
||||||
my @path = split(" ", FW_fC("get $d $file $tmpfile $f $t " .
|
my @path = split(" ",
|
||||||
join(" ", @{$flog})));
|
FW_fC("get $d $file $tmpfile $f $t $srcDesc->{all}"));
|
||||||
$attr{global}{verbose} = $oll;
|
$attr{global}{verbose} = $oll;
|
||||||
|
|
||||||
# replace the path with the temporary filenames of the filelog output
|
# replace the path with the temporary filenames of the filelog output
|
||||||
@ -915,8 +1020,7 @@ SVG_doShowLog($$$$;$$)
|
|||||||
$f = 0 if(!$f); # From the beginning of time...
|
$f = 0 if(!$f); # From the beginning of time...
|
||||||
$t = 9 if(!$t); # till the end
|
$t = 9 if(!$t); # till the end
|
||||||
|
|
||||||
Log3 $FW_wname, 5,
|
Log3 $FW_wname, 5, "plotcommand: get $d $file INT $f $t ".$srcDesc->{all};
|
||||||
"plotcommand: get $d $file INT $f $t " . join(" ", @{$flog});
|
|
||||||
|
|
||||||
$FW_RETTYPE = "image/svg+xml";
|
$FW_RETTYPE = "image/svg+xml";
|
||||||
|
|
||||||
@ -929,10 +1033,10 @@ SVG_doShowLog($$$$;$$)
|
|||||||
close(CFH);
|
close(CFH);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
FW_fC("get $d $file INT $f $t " . join(" ", @{$flog}), 1);
|
my $da = SVG_getData($wl, $f, $t, $srcDesc, 0); # substcfg needs it(!)
|
||||||
($cfg, $plot) = SVG_substcfg(1, $wl, $cfg, $plot, $file, "<OuT>");
|
($cfg, $plot) = SVG_substcfg(1, $wl, $cfg, $plot, $file, "<OuT>");
|
||||||
my $ret = SVG_render($wl, $f, $t, $cfg,
|
my $ret = SVG_render($wl, $f, $t, $cfg, $da,
|
||||||
$internal_data, $plot, $FW_wname, $FW_cssdir, $flog,
|
$plot, $FW_wname, $FW_cssdir, $srcDesc,
|
||||||
$styleW, $styleH);
|
$styleW, $styleH);
|
||||||
$internal_data = "";
|
$internal_data = "";
|
||||||
FW_pO $ret;
|
FW_pO $ret;
|
||||||
@ -950,6 +1054,58 @@ SVG_doShowLog($$$$;$$)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
SVG_getData($$$$$)
|
||||||
|
{
|
||||||
|
my ($d, $f,$t,$srcDesc,$showData) = @_;
|
||||||
|
my (@da, $ret, @vals);
|
||||||
|
my @keys = ("min","max","avg","cnt","currval","mindate","maxdate","lastraw");
|
||||||
|
|
||||||
|
foreach my $src (@{$srcDesc->{order}}) {
|
||||||
|
my $s = $srcDesc->{src}{$src};
|
||||||
|
my $fname = ($src eq $defs{$d}{LOGDEVICE} ? $defs{$d}{LOGFILE} : "CURRENT");
|
||||||
|
my $cmd = "get $src $fname INT $f $t ".$s->{arg};
|
||||||
|
FW_fC($cmd);
|
||||||
|
if($showData) {
|
||||||
|
$ret .= "\n$cmd\n\n";
|
||||||
|
$ret .= $$internal_data;
|
||||||
|
} else {
|
||||||
|
push(@da, $internal_data);
|
||||||
|
|
||||||
|
for(my $i = 0; $i<=$s->{idx}; $i++) {
|
||||||
|
my %h;
|
||||||
|
foreach my $k (@keys) {
|
||||||
|
$h{$k} = $data{$k.($i+1)};
|
||||||
|
}
|
||||||
|
push @vals, \%h;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Reorder the $data{maxX} stuff
|
||||||
|
my ($min, $max) = (999999, -999999);
|
||||||
|
my $no = int(keys %{$srcDesc->{rev}});
|
||||||
|
for(my $oi = 0; $oi < $no; $oi++) {
|
||||||
|
my $nl = int(keys %{$srcDesc->{rev}{$oi}});
|
||||||
|
for(my $li = 0; $li < $nl; $li++) {
|
||||||
|
my $r = $srcDesc->{rev}{$oi}{$li}+1;
|
||||||
|
my $val = shift @vals;
|
||||||
|
foreach my $k (@keys) {
|
||||||
|
$min = $val->{$k}
|
||||||
|
if($k eq "min" && defined($val->{$k}) && $val->{$k} < $min);
|
||||||
|
$max = $val->{$k}
|
||||||
|
if($k eq "max" && defined($val->{$k}) && $val->{$k} > $max);
|
||||||
|
$data{"$k$r"} = $val->{$k};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$data{maxAll} = $max;
|
||||||
|
$data{minAll} = $min;
|
||||||
|
|
||||||
|
return $ret if($showData);
|
||||||
|
return \@da;
|
||||||
|
}
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# Convert the configuration to a "readable" form -> array to hash
|
# Convert the configuration to a "readable" form -> array to hash
|
||||||
@ -1051,17 +1207,16 @@ SVG_render($$$$$$$$$;$$)
|
|||||||
my $from = shift; # e.g. 2008-01-01
|
my $from = shift; # e.g. 2008-01-01
|
||||||
my $to = shift; # e.g. 2009-01-01
|
my $to = shift; # e.g. 2009-01-01
|
||||||
my $confp = shift; # lines from the .gplot file, w/o FileLog and plot
|
my $confp = shift; # lines from the .gplot file, w/o FileLog and plot
|
||||||
my $dp = shift; # pointer to data (one string)
|
my $da = shift; # data pointer array
|
||||||
my $plot = shift; # Plot lines from the .gplot file
|
my $plot = shift; # Plot lines from the .gplot file
|
||||||
my $parent_name = shift; # e.g. FHEMWEB instance name
|
my $parent_name = shift; # e.g. FHEMWEB instance name
|
||||||
my $parent_dir = shift; # FW_dir
|
my $parent_dir = shift; # FW_dir
|
||||||
my $flog = shift; # #FileLog lines, as array pointer
|
my $srcDesc = shift; # #FileLog lines, as array pointer
|
||||||
my $styleW = shift;
|
my $styleW = shift;
|
||||||
my $styleH = shift;
|
my $styleH = shift;
|
||||||
|
|
||||||
$SVG_RET="";
|
$SVG_RET="";
|
||||||
my $SVG_ss = AttrVal($parent_name, "smallscreen", 0);
|
my $SVG_ss = AttrVal($parent_name, "smallscreen", 0);
|
||||||
return $SVG_RET if(!defined($dp) || $dp eq "");
|
|
||||||
|
|
||||||
my $nr_axis = AttrVal($parent_name,"nrAxis","1,1");
|
my $nr_axis = AttrVal($parent_name,"nrAxis","1,1");
|
||||||
my ($nr_left_axis,$nr_right_axis,$use_left_axis,$use_right_axis) =
|
my ($nr_left_axis,$nr_right_axis,$use_left_axis,$use_right_axis) =
|
||||||
@ -1084,23 +1239,24 @@ SVG_render($$$$$$$$$;$$)
|
|||||||
my $w = $ow-$nr_left_axis*$axis_width-$nr_right_axis*$axis_width;
|
my $w = $ow-$nr_left_axis*$axis_width-$nr_right_axis*$axis_width;
|
||||||
my $h = $oh-2*$y; # Rect size
|
my $h = $oh-2*$y; # Rect size
|
||||||
|
|
||||||
# Keep only the Filter part of the #FileLog
|
my $filter = $srcDesc->{all};
|
||||||
$flog = join(" ", map { my @a=split(":",$_);
|
$filter =~ s/[^: ]*:([^: ]):[^ ]*/$1/g;
|
||||||
$a[1]=~s/\.[^\.]*$//; $a[1]; } @{$flog});
|
$filter = AttrVal($parent_name, "longpollSVG", 0) ? "flog=\" $filter \"" : "";
|
||||||
$flog = AttrVal($parent_name, "longpollSVG", 0) ? "flog=\" $flog \"" : "";
|
|
||||||
|
my %dataIdx; # Build a reverse Index for the dataSource
|
||||||
|
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# Html Header
|
# SVG Header
|
||||||
|
my $svghdr = 'version="1.1" xmlns="http://www.w3.org/2000/svg" '.
|
||||||
|
'xmlns:xlink="http://www.w3.org/1999/xlink" '.
|
||||||
|
'id="SVGPLOT_'.(++$SVG_id).'"'.$filter;
|
||||||
if(!$styleW) {
|
if(!$styleW) {
|
||||||
SVG_pO '<?xml version="1.0" encoding="UTF-8"?>';
|
SVG_pO '<?xml version="1.0" encoding="UTF-8"?>';
|
||||||
SVG_pO '<!DOCTYPE svg>';
|
SVG_pO '<!DOCTYPE svg>';
|
||||||
SVG_pO '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" '.
|
SVG_pO "<svg $svghdr>";
|
||||||
'xmlns:xlink="http://www.w3.org/1999/xlink" '.$flog.'>';
|
|
||||||
} else {
|
} else {
|
||||||
SVG_pO '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" '.
|
SVG_pO "<svg $svghdr style='width:${styleW}px; height:${styleH}px;'>";
|
||||||
'xmlns:xlink="http://www.w3.org/1999/xlink" '.
|
|
||||||
"style='width:${styleW}px; height:${styleH}px;' ".
|
|
||||||
'>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
my $prf = AttrVal($parent_name, "stylesheetPrefix", "");
|
my $prf = AttrVal($parent_name, "stylesheetPrefix", "");
|
||||||
@ -1134,17 +1290,6 @@ SVG_render($$$$$$$$$;$$)
|
|||||||
SVG_pO "<text id=\"svg_title\" x=\"$off1\" y=\"$off2\" " .
|
SVG_pO "<text id=\"svg_title\" x=\"$off1\" y=\"$off2\" " .
|
||||||
"class=\"title\" text-anchor=\"middle\">$title</text>";
|
"class=\"title\" text-anchor=\"middle\">$title</text>";
|
||||||
|
|
||||||
######################
|
|
||||||
# Copy and Paste labels, hidden by default
|
|
||||||
SVG_pO "<text id=\"svg_paste\" x=\"" .
|
|
||||||
($ow-$axis_width-$nr_right_axis*$axis_width) . "\" y=\"$off2\" " .
|
|
||||||
"onclick=\"parent.svg_paste(evt)\" " .
|
|
||||||
"class=\"paste\" text-anchor=\"end\"> </text>";
|
|
||||||
SVG_pO "<text id=\"svg_copy\" x=\"" .
|
|
||||||
($ow-$nr_right_axis*$axis_width) . "\" y=\"$off2\" " .
|
|
||||||
"onclick=\"parent.svg_copy(evt)\" " .
|
|
||||||
"class=\"copy\" text-anchor=\"end\"> </text>";
|
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# Left label = ylabel and right label = y2label
|
# Left label = ylabel and right label = y2label
|
||||||
if(!$SVG_ss) {
|
if(!$SVG_ss) {
|
||||||
@ -1198,63 +1343,69 @@ SVG_render($$$$$$$$$;$$)
|
|||||||
my ($dxp, $dyp) = (\(), \());
|
my ($dxp, $dyp) = (\(), \());
|
||||||
|
|
||||||
my ($d, $v, $ld, $lv) = ("","","","");
|
my ($d, $v, $ld, $lv) = ("","","","");
|
||||||
|
for(my $dIdx=0; $dIdx<@{$da}; $dIdx++) {
|
||||||
my ($dpl,$dpoff,$l) = (length($$dp), 0, "");
|
my $lIdx = 0;
|
||||||
while($dpoff < $dpl) { # using split instead is memory hog
|
$idx = $srcDesc->{rev}{$dIdx}{$lIdx};
|
||||||
my $ndpoff = index($$dp, "\n", $dpoff);
|
my $dp = $da->[$dIdx];
|
||||||
if($ndpoff == -1) {
|
my ($dpl,$dpoff,$l) = (length($$dp), 0, "");
|
||||||
$l = substr($$dp, $dpoff);
|
while($dpoff < $dpl) { # using split instead is memory hog
|
||||||
} else {
|
my $ndpoff = index($$dp, "\n", $dpoff);
|
||||||
$l = substr($$dp, $dpoff, $ndpoff-$dpoff);
|
if($ndpoff == -1) {
|
||||||
}
|
$l = substr($$dp, $dpoff);
|
||||||
$dpoff = $ndpoff+1;
|
} else {
|
||||||
if($l =~ m/^#/) {
|
$l = substr($$dp, $dpoff, $ndpoff-$dpoff);
|
||||||
my $a = $conf{lAxis}[$idx];
|
|
||||||
if(defined($a)) {
|
|
||||||
$hmin{$a} = $min if(!defined($hmin{$a}) || $hmin{$a} > $min);
|
|
||||||
$hmax{$a} = $max if(!defined($hmax{$a}) || $hmax{$a} < $max);
|
|
||||||
}
|
}
|
||||||
($min, $max) = (99999999, -99999999);
|
$dpoff = $ndpoff+1;
|
||||||
$hdx[$idx] = $dxp; $hdy[$idx] = $dyp;
|
if($l =~ m/^#/) {
|
||||||
($dxp, $dyp) = (\(), \());
|
my $a = $conf{lAxis}[$idx];
|
||||||
$idx++;
|
if(defined($a)) {
|
||||||
|
$hmin{$a} = $min if(!defined($hmin{$a}) || $hmin{$a} > $min);
|
||||||
} elsif( $l =~ /^;/ ) { #allow ;special lines
|
$hmax{$a} = $max if(!defined($hmax{$a}) || $hmax{$a} < $max);
|
||||||
if( $l =~ m/^;p (\S+)\s(\S+)/ ) {# point
|
|
||||||
my $xmul = $w/($xmax-$xmin);
|
|
||||||
my $x1;
|
|
||||||
if( $conf{xrange} ) {
|
|
||||||
$x1 = int(($1-$xmin)*$xmul);
|
|
||||||
} else {
|
|
||||||
$x1 = $x1;
|
|
||||||
}
|
}
|
||||||
my $y1 = $2;
|
($min, $max) = (99999999, -99999999);
|
||||||
|
$hdx[$idx] = $dxp; $hdy[$idx] = $dyp;
|
||||||
|
($dxp, $dyp) = (\(), \());
|
||||||
|
$lIdx++;
|
||||||
|
$idx = $srcDesc->{rev}{$dIdx}{$lIdx};
|
||||||
|
last if(!$idx);
|
||||||
|
|
||||||
push @{$dxp}, $x1;
|
} elsif( $l =~ /^;/ ) { #allow ;special lines
|
||||||
push @{$dyp}, $y1;
|
if( $l =~ m/^;p (\S+)\s(\S+)/ ) {# point
|
||||||
|
my $xmul = $w/($xmax-$xmin);
|
||||||
|
my $x1;
|
||||||
|
if( $conf{xrange} ) {
|
||||||
|
$x1 = int(($1-$xmin)*$xmul);
|
||||||
|
} else {
|
||||||
|
$x1 = $x1;
|
||||||
|
}
|
||||||
|
my $y1 = $2;
|
||||||
|
|
||||||
} elsif( $conf{lType}[$idx] eq "lines" ) {
|
push @{$dxp}, $x1;
|
||||||
push @{$dxp}, undef;
|
push @{$dyp}, $y1;
|
||||||
push @{$dyp}, $l;
|
|
||||||
|
|
||||||
|
} elsif( $conf{lType}[$idx] eq "lines" ) {
|
||||||
|
push @{$dxp}, undef;
|
||||||
|
push @{$dyp}, $l;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
($d, $v) = split(" ", $l);
|
||||||
|
$d = ($tmul ? int((SVG_time_to_sec($d)-$fromsec)*$tmul) : $d);
|
||||||
|
if($ld ne $d || $lv ne $v) { # Saves a lot on year zoomlevel
|
||||||
|
$ld = $d; $lv = $v;
|
||||||
|
push @{$dxp}, $d;
|
||||||
|
push @{$dyp}, $v;
|
||||||
|
$min = $v if($min > $v);
|
||||||
|
$max = $v if($max < $v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
last if($ndpoff == -1);
|
||||||
} else {
|
|
||||||
($d, $v) = split(" ", $l);
|
|
||||||
$d = ($tmul ? int((SVG_time_to_sec($d)-$fromsec)*$tmul) : $d);
|
|
||||||
if($ld ne $d || $lv ne $v) { # Saves a lot on year zoomlevel
|
|
||||||
$ld = $d; $lv = $v;
|
|
||||||
push @{$dxp}, $d;
|
|
||||||
push @{$dyp}, $v;
|
|
||||||
$min = $v if($min > $v);
|
|
||||||
$max = $v if($max < $v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
last if($ndpoff == -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$dxp = $hdx[0];
|
$dxp = $hdx[0];
|
||||||
if(($dxp && int(@{$dxp}) < 2 && !$tosec) || # not enough data and no range...
|
if(($dxp && int(@{$dxp}) < 2 && !$tosec) || # not enough data and no range...
|
||||||
(!$tmul && !$dxp)) {
|
(!$tmul && !$dxp)) {
|
||||||
SVG_pO "</svg>";
|
SVG_pO "</svg>";
|
||||||
return $SVG_RET;
|
return $SVG_RET;
|
||||||
@ -1392,6 +1543,7 @@ SVG_render($$$$$$$$$;$$)
|
|||||||
|
|
||||||
my (%hstep,%htics,%axdrawn);
|
my (%hstep,%htics,%axdrawn);
|
||||||
|
|
||||||
|
my $allowed = AttrVal($FW_wname,"allowedCommands",undef);
|
||||||
#-- yrange handling for axes x1y1..x1y8
|
#-- yrange handling for axes x1y1..x1y8
|
||||||
for my $idx (0..7) {
|
for my $idx (0..7) {
|
||||||
my $a = "x1y".($idx+1);
|
my $a = "x1y".($idx+1);
|
||||||
@ -1399,10 +1551,15 @@ SVG_render($$$$$$$$$;$$)
|
|||||||
my $yra="y".($idx+1)."range";
|
my $yra="y".($idx+1)."range";
|
||||||
$yra="yrange" if ($yra eq "y1range");
|
$yra="yrange" if ($yra eq "y1range");
|
||||||
#-- yrange is specified in plotfile
|
#-- yrange is specified in plotfile
|
||||||
if($conf{$yra} && $conf{$yra} =~ /\[(.*):(.*)\]/) {
|
if($conf{$yra}) {
|
||||||
$hmin{$a} = $1 if($1 ne "");
|
$conf{$yra} = AnalyzeCommand(undef, $1, $allowed)
|
||||||
$hmax{$a} = $2 if($2 ne "");
|
if($conf{$yra} =~ /^({.*})$/);
|
||||||
|
if($conf{$yra} =~ /\[(.*):(.*)\]/) {
|
||||||
|
$hmin{$a} = $1 if($1 ne "");
|
||||||
|
$hmax{$a} = $2 if($2 ne "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- tics handling
|
#-- tics handling
|
||||||
my $yt="y".($idx+1)."tics";
|
my $yt="y".($idx+1)."tics";
|
||||||
$yt="ytics" if ($yt eq"y1tics");
|
$yt="ytics" if ($yt eq"y1tics");
|
||||||
@ -1732,13 +1889,15 @@ SVG_render($$$$$$$$$;$$)
|
|||||||
}
|
}
|
||||||
my $style = $conf{lStyle}[$i];
|
my $style = $conf{lStyle}[$i];
|
||||||
$style =~ s/class="/class="legend /;
|
$style =~ s/class="/class="legend /;
|
||||||
SVG_pO "<text title=\"$desc\" ".
|
SVG_pO "<text title=\"$desc\" line_id=\"line_$i\" " .
|
||||||
"onclick=\"parent.svg_labelselect(evt)\" line_id=\"line_$i\" " .
|
|
||||||
"x=\"$txtoff1\" y=\"$txtoff2\" text-anchor=\"end\" $style>$t</text>";
|
"x=\"$txtoff1\" y=\"$txtoff2\" text-anchor=\"end\" $style>$t</text>";
|
||||||
$txtoff2 += $th;
|
$txtoff2 += $th;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $fnName = SVG_isEmbed($FW_wname) ? "parent.window.svg_init" : "svg_init";
|
||||||
|
|
||||||
|
SVG_pO "<script type='text/javascript'>if(typeof $fnName == 'function') ".
|
||||||
|
"$fnName('SVGPLOT_$SVG_id')</script>";
|
||||||
SVG_pO "</svg>";
|
SVG_pO "</svg>";
|
||||||
return $SVG_RET;
|
return $SVG_RET;
|
||||||
}
|
}
|
||||||
@ -1974,6 +2133,9 @@ plotAsPng(@)
|
|||||||
set title <L1><br></li>
|
set title <L1><br></li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
The value minAll and maxAll (representing the minimum/maximum over all
|
||||||
|
values) is also available from the data hash.
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<a name="title"></a>
|
<a name="title"></a>
|
||||||
@ -2025,6 +2187,9 @@ plotAsPng(@)
|
|||||||
regexp switch.on, and "0" for the regexp switch.off.<br>
|
regexp switch.on, and "0" for the regexp switch.off.<br>
|
||||||
Write .gplot file again<br>
|
Write .gplot file again<br>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
|
<li>If the range is of the form {...}, then it will be evaluated with perl.
|
||||||
|
The result is a string, and must have the form [min:max]
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
The visibility of the ploteditor can be configured with the FHEMWEB attribute
|
The visibility of the ploteditor can be configured with the FHEMWEB attribute
|
||||||
<a href="#ploteditor">ploteditor</a>.
|
<a href="#ploteditor">ploteditor</a>.
|
||||||
@ -2142,7 +2307,7 @@ plotAsPng(@)
|
|||||||
können ebenfalls die Werte der individuellen Kurve für min,
|
können ebenfalls die Werte der individuellen Kurve für min,
|
||||||
max, mindate, maxdate, avg, cnt, sum, currval (letzter Wert) und currdate
|
max, mindate, maxdate, avg, cnt, sum, currval (letzter Wert) und currdate
|
||||||
(letztes Datum) durch Zugriff der entsprechenden Werte über das
|
(letztes Datum) durch Zugriff der entsprechenden Werte über das
|
||||||
DataHash verwendet werden. Siehe untenstehendes Beispiel:<br>
|
data Hash verwendet werden. Siehe untenstehendes Beispiel:<br>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Beschriftunng der rechten und linken y-Achse:<br>
|
<li>Beschriftunng der rechten und linken y-Achse:<br>
|
||||||
<ul>
|
<ul>
|
||||||
@ -2164,6 +2329,8 @@ plotAsPng(@)
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
Die Werte minAll und maxAll (die das Minimum/Maximum aller Werte
|
||||||
|
repräsentieren) sind ebenfals im data hash vorhanden.
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<a name="title"></a>
|
<a name="title"></a>
|
||||||
@ -2229,6 +2396,9 @@ plotAsPng(@)
|
|||||||
.gplot-Datei erneut speichern<br>
|
.gplot-Datei erneut speichern<br>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>Falls Range der Form {...} entspricht, dann wird sie als Perl -
|
||||||
|
Expression ausgewertet. Das Ergebnis muss in der Form [min:max] sein.
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
Die sichtbarkeit des Plot-Editors kann mit dem FHEMWEB Attribut <a
|
Die sichtbarkeit des Plot-Editors kann mit dem FHEMWEB Attribut <a
|
||||||
href="#ploteditor">ploteditor</a> konfiguriert werden.
|
href="#ploteditor">ploteditor</a> konfiguriert werden.
|
||||||
|
@ -17,81 +17,9 @@ Color_Initialize()
|
|||||||
sub
|
sub
|
||||||
FHEM_colorpickerInit()
|
FHEM_colorpickerInit()
|
||||||
{
|
{
|
||||||
$data{webCmdFn}{colorpicker} = "FHEM_colorpickerFn";
|
|
||||||
$data{FWEXT}{colorpicker}{SCRIPT} = "/jscolor/jscolor.js";
|
$data{FWEXT}{colorpicker}{SCRIPT} = "/jscolor/jscolor.js";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub
|
|
||||||
FHEM_colorpickerFn($$$$$)
|
|
||||||
{
|
|
||||||
#return undef;
|
|
||||||
my ($FW_wname, $d, $FW_room, $cmd, $values) = @_;
|
|
||||||
|
|
||||||
my @args = split("[ \t]+", $cmd);
|
|
||||||
|
|
||||||
my @value = split( ',', $values );
|
|
||||||
return undef if($values !~ m/^colorpicker,([^,]*)/);
|
|
||||||
|
|
||||||
my $mode = $1;
|
|
||||||
$mode = "RGB" if( !defined($mode) );
|
|
||||||
|
|
||||||
if( $mode eq "CT" ) {
|
|
||||||
if( !$args[1] && $data{webCmdFn}{slider} ) {
|
|
||||||
no strict "refs";
|
|
||||||
my $values = "slider,". join( ',', @value[2..4] );
|
|
||||||
my $htmlTxt = &{$data{webCmdFn}{slider}}($FW_wname, $d, $FW_room, $cmd, $values);
|
|
||||||
use strict "refs";
|
|
||||||
|
|
||||||
return $htmlTxt;
|
|
||||||
}
|
|
||||||
|
|
||||||
return undef if( !$args[1] );
|
|
||||||
}
|
|
||||||
|
|
||||||
my $trigger = $cmd; #default trigger is the event from the reading with the same name as the command
|
|
||||||
my $cv = ReadingsVal($d,$cmd,""); #get default value from this reading
|
|
||||||
if( !$cv ) { #if this reading does not exist ->
|
|
||||||
$trigger = "RGB"; # trigger name will be RGB
|
|
||||||
$cv = CommandGet("","$d $cmd"); # get default value from get command
|
|
||||||
}
|
|
||||||
|
|
||||||
$cmd = "" if($cmd eq "state");
|
|
||||||
my $srf = $FW_room ? "&room=$FW_room" : "";
|
|
||||||
if( $args[1] ) {
|
|
||||||
my $c = "cmd=set $d $cmd$srf";
|
|
||||||
|
|
||||||
if( $mode eq "CT" ) {
|
|
||||||
my $ct = $args[1];
|
|
||||||
my ($r, $g, $b) = Color::ct2rgb( $ct );
|
|
||||||
$args[1] = Color::rgb2hex( $r, $g, $b );
|
|
||||||
}
|
|
||||||
|
|
||||||
return '<td align="center">'.
|
|
||||||
"<div onClick=\"FW_cmd('$FW_ME?XHR=1&$c')\" style=\"width:32px;height:19px;".
|
|
||||||
'border:1px solid #fff;border-radius:8px;background-color:#'. $args[1] .';"></div>'.
|
|
||||||
'</td>' if( AttrVal($FW_wname, "longpoll", 1));
|
|
||||||
|
|
||||||
return '<td align="center">'.
|
|
||||||
"<a href=\"$FW_ME?$c\">".
|
|
||||||
'<div style="width:32px;height:19px;'.
|
|
||||||
'border:1px solid #fff;border-radius:8px;background-color:#'. $args[1] .';"></div>'.
|
|
||||||
'</a>'.
|
|
||||||
'</td>';
|
|
||||||
} elsif(AttrVal($d,"realtimePicker",0)) {
|
|
||||||
my $c = "$FW_ME?XHR=1&cmd=set $d $cmd %$srf";
|
|
||||||
my $ci = $c;
|
|
||||||
$ci = "$FW_ME?XHR=1&cmd=set $d $cmd % : transitiontime 0 : noUpdate$srf" if($defs{$d}->{TYPE} eq "HUEDevice");
|
|
||||||
return '<td align="center">'.
|
|
||||||
"<input maxlength='6' size='6' id='colorpicker.$d-$trigger' class=\"color {pickerMode:'$mode',pickerFaceColor:'transparent',pickerFace:3,pickerBorder:0,pickerInsetColor:'red',command:'$ci',onImmediateChange:'colorpicker_setColor(this)'}\" value='$cv' onChange='colorpicker_setColor(this,\"$mode\",\"$c\")'>".
|
|
||||||
'</td>';
|
|
||||||
} else {
|
|
||||||
my $c = "$FW_ME?XHR=1&cmd=set $d $cmd %$srf";
|
|
||||||
return '<td align="center">'.
|
|
||||||
"<input maxlength='6' size='6' id='colorpicker.$d-$trigger' class=\"color {pickerMode:'$mode',pickerFaceColor:'transparent',pickerFace:3,pickerBorder:0,pickerInsetColor:'red'}\" value='$cv' onChange='colorpicker_setColor(this,\"$mode\",\"$c\")'>".
|
|
||||||
'</td>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
my %dim_values = (
|
my %dim_values = (
|
||||||
0 => "dim06%",
|
0 => "dim06%",
|
||||||
1 => "dim12%",
|
1 => "dim12%",
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
#Mon Aug 26 16:36:31 2013
|
#Sun Jan 4 16:24:11 2015
|
||||||
{
|
{
|
||||||
'lcCinema' => {
|
'lcCinema' => {
|
||||||
'Break' => {
|
'Break' => {
|
||||||
'CeilingLight' => 'dim37%',
|
'CeilingLight' => 'dim37%',
|
||||||
'ReadingLight' => 'dim37%'
|
'ReadingLight' => 'dim37%'
|
||||||
},
|
},
|
||||||
'Cinema' => {
|
'Cinema' => {
|
||||||
'Screen' => 'down',
|
'CeilingLight' => 'off',
|
||||||
'Projector' => 'on',
|
'Projector' => 'on',
|
||||||
'CeilingLight' => 'off',
|
'Screen' => 'down',
|
||||||
'ReadingLight' => 'off',
|
'ReadingLight' => 'off',
|
||||||
'TV' => 'off'
|
'TV' => 'off'
|
||||||
},
|
},
|
||||||
'WatchTV' => {
|
'WatchTV' => {
|
||||||
'Screen' => 'up',
|
'CeilingLight' => 'off',
|
||||||
'Projector' => 'off',
|
'Projector' => 'off',
|
||||||
'CeilingLight' => 'off',
|
'Screen' => 'up',
|
||||||
'ReadingLight' => 'dim12%',
|
'ReadingLight' => 'dim12%',
|
||||||
'TV' => 'on'
|
'TV' => 'on'
|
||||||
},
|
},
|
||||||
'AllOff' => {
|
'AllOff' => {
|
||||||
'Screen' => 'up',
|
'CeilingLight' => 'off',
|
||||||
'Projector' => 'off',
|
'Projector' => 'off',
|
||||||
'CeilingLight' => 'off',
|
'Screen' => 'up',
|
||||||
'ReadingLight' => 'off',
|
'ReadingLight' => 'off',
|
||||||
'TV' => 'off'
|
'TV' => 'off'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
#Mon Feb 17 20:54:16 2014
|
#Sun Jan 4 16:24:11 2015
|
||||||
setstate Alarm on
|
setstate Alarm on
|
||||||
setstate Alarm 2013-08-23 07:42:48 state on
|
setstate Alarm 2015-01-04 16:22:21 state on
|
||||||
setstate AllLights on
|
setstate AllLights on
|
||||||
setstate AllLights 2013-08-25 14:23:20 LastDevice Office
|
setstate AllLights 2015-01-04 16:22:04 LastDevice Alarm
|
||||||
setstate AllLights 2013-08-25 14:23:20 LastDevice_Abs Office
|
setstate AllLights 2015-01-04 16:22:04 LastDevice_Abs Alarm
|
||||||
setstate AllLights 2013-08-25 14:23:20 state on
|
setstate AllLights 2015-01-04 16:22:04 state undefined
|
||||||
setstate AllResidentsAway active
|
setstate AllResidentsAway active
|
||||||
|
setstate CT off
|
||||||
|
setstate CT 2015-01-03 01:10:50 ct 3703
|
||||||
|
setstate CT 2015-01-04 13:30:52 lastCmd off
|
||||||
|
setstate CT 2015-01-04 16:22:04 state off
|
||||||
setstate CeilingLight dim0%
|
setstate CeilingLight dim0%
|
||||||
setstate CeilingLight 2013-08-26 18:01:06 state off
|
setstate CeilingLight 2015-01-04 16:22:40 state off
|
||||||
setstate Cellar T: 21.1 H: 54.6
|
setstate Cellar T: 21.1 H: 54.6
|
||||||
setstate Cellar 2013-08-13 08:00:48 DEVFAMILY WS300
|
setstate Cellar 2013-08-13 08:00:48 DEVFAMILY WS300
|
||||||
setstate Cellar 2013-08-13 08:00:48 DEVTYPE S300TH
|
setstate Cellar 2013-08-13 08:00:48 DEVTYPE S300TH
|
||||||
@ -26,7 +30,7 @@ setstate Garden 2013-08-13 15:03:17 israining no
|
|||||||
setstate Garden 2013-08-13 15:03:17 rain 81.9
|
setstate Garden 2013-08-13 15:03:17 rain 81.9
|
||||||
setstate Garden 2013-08-13 15:03:17 rain_raw 321
|
setstate Garden 2013-08-13 15:03:17 rain_raw 321
|
||||||
setstate Garden 2013-08-13 15:03:17 rain_raw_adj 321
|
setstate Garden 2013-08-13 15:03:17 rain_raw_adj 321
|
||||||
setstate Garden 2014-02-17 20:54:12 state defined
|
setstate Garden 2015-01-04 16:19:04 state defined
|
||||||
setstate Garden 2013-08-13 15:03:17 temperature 18.3
|
setstate Garden 2013-08-13 15:03:17 temperature 18.3
|
||||||
setstate Garden 2013-08-13 15:03:17 tsecs 1376805797
|
setstate Garden 2013-08-13 15:03:17 tsecs 1376805797
|
||||||
setstate Garden 2013-08-13 15:03:17 unknown1 a
|
setstate Garden 2013-08-13 15:03:17 unknown1 a
|
||||||
@ -34,36 +38,51 @@ setstate Garden 2013-08-13 15:03:17 unknown2 7
|
|||||||
setstate Garden 2013-08-13 15:03:17 unknown3 1
|
setstate Garden 2013-08-13 15:03:17 unknown3 1
|
||||||
setstate Garden 2013-08-13 15:03:17 wind 0.5
|
setstate Garden 2013-08-13 15:03:17 wind 0.5
|
||||||
setstate Livingroom dim100%
|
setstate Livingroom dim100%
|
||||||
setstate Livingroom 2013-08-23 07:57:21 state on
|
setstate Livingroom 2015-01-04 16:22:21 state on
|
||||||
setstate Log.Cellar active
|
setstate Log.Cellar active
|
||||||
setstate Log.Dewpoint active
|
setstate Log.Dewpoint active
|
||||||
setstate Log.Garden active
|
setstate Log.Garden active
|
||||||
setstate Logfile active
|
setstate Logfile active
|
||||||
setstate Office on
|
setstate Office on
|
||||||
setstate Office 2013-08-25 14:23:20 state on
|
setstate Office 2015-01-04 16:22:21 state on
|
||||||
setstate Outdoor on
|
setstate Outdoor on
|
||||||
setstate Outdoor 2013-08-25 14:23:20 state on
|
setstate Outdoor 2015-01-04 16:22:21 state on
|
||||||
setstate Projector off
|
setstate Projector off
|
||||||
setstate Projector 2013-08-26 18:01:06 state off
|
setstate Projector 2015-01-04 16:22:40 state off
|
||||||
setstate ReadingLight dim12%
|
setstate RGB off
|
||||||
setstate ReadingLight 2013-08-26 18:01:06 state dim12%
|
setstate RGB 2015-01-04 12:55:47 hue 220
|
||||||
|
setstate RGB 2015-01-04 13:30:54 lastCmd off
|
||||||
|
setstate RGB 2015-01-04 12:55:47 rgb 0054FF
|
||||||
|
setstate RGB 2015-01-04 16:22:04 state off
|
||||||
|
setstate ReadingLight dim0%
|
||||||
|
setstate ReadingLight 2015-01-04 16:22:40 state off
|
||||||
setstate ResidentsComeHome active
|
setstate ResidentsComeHome active
|
||||||
setstate SVG_01_Garden initialized
|
setstate SVG_01_Garden initialized
|
||||||
setstate SVG_02_Cellar initialized
|
setstate SVG_02_Cellar initialized
|
||||||
setstate SVG_03_Dewpoint initialized
|
setstate SVG_03_Dewpoint initialized
|
||||||
setstate Screen up
|
setstate Screen up
|
||||||
setstate Screen 2013-08-26 18:01:06 state up
|
setstate Screen 2015-01-04 16:22:40 state up
|
||||||
setstate TV on
|
setstate TV off
|
||||||
setstate TV 2013-08-26 18:01:06 state on
|
setstate TV 2015-01-04 16:22:40 state off
|
||||||
|
setstate anyViews 2015-01-04 16:24:11 lockstate 0
|
||||||
|
setstate anyViews 2015-01-04 16:19:04 state Initialized
|
||||||
setstate anyViews_weblink initialized
|
setstate anyViews_weblink initialized
|
||||||
setstate autocreate active
|
setstate autocreate active
|
||||||
|
setstate colorInit 2015-01-04 16:19:04
|
||||||
setstate dew_all active
|
setstate dew_all active
|
||||||
|
setstate eventTypes active
|
||||||
setstate global <no definition>
|
setstate global <no definition>
|
||||||
setstate outdoorNotifier active
|
setstate initialUsbCheck 2015-01-04 16:19:04
|
||||||
|
setstate lcCinema AllOff
|
||||||
|
setstate lcCinema 2015-01-04 16:22:40 state AllOff
|
||||||
|
setstate outdoorNotifier 2015-01-04 16:22:21
|
||||||
setstate rg_Guest1 none
|
setstate rg_Guest1 none
|
||||||
setstate rg_Guest1 2014-02-16 13:59:50 durTimerAbsence 0
|
setstate rg_Guest1 2015-01-04 16:19:19 durTimerAbsence 00:00:00
|
||||||
setstate rg_Guest1 2014-02-16 13:34:06 durTimerPresence 0
|
setstate rg_Guest1 2015-01-04 16:19:19 durTimerAbsence_cr 0
|
||||||
setstate rg_Guest1 2014-02-15 16:15:34 durTimerSleep 0
|
setstate rg_Guest1 2015-01-04 16:19:19 durTimerPresence 00:00:00
|
||||||
|
setstate rg_Guest1 2015-01-04 16:19:19 durTimerPresence_cr 0
|
||||||
|
setstate rg_Guest1 2015-01-04 16:19:19 durTimerSleep 00:00:00
|
||||||
|
setstate rg_Guest1 2015-01-04 16:19:19 durTimerSleep_cr 0
|
||||||
setstate rg_Guest1 2014-02-16 14:09:20 lastArrival -
|
setstate rg_Guest1 2014-02-16 14:09:20 lastArrival -
|
||||||
setstate rg_Guest1 2014-02-16 14:09:29 lastAwake 0
|
setstate rg_Guest1 2014-02-16 14:09:29 lastAwake 0
|
||||||
setstate rg_Guest1 2014-02-16 14:09:20 lastDeparture 2014-02-16 14:09:20
|
setstate rg_Guest1 2014-02-16 14:09:20 lastDeparture 2014-02-16 14:09:20
|
||||||
@ -80,9 +99,12 @@ setstate rg_Guest1 2014-02-16 14:09:20 presence absent
|
|||||||
setstate rg_Guest1 2014-02-16 14:09:20 state none
|
setstate rg_Guest1 2014-02-16 14:09:20 state none
|
||||||
setstate rg_Guest1 2014-02-15 16:16:27 wayhome 0
|
setstate rg_Guest1 2014-02-15 16:16:27 wayhome 0
|
||||||
setstate rg_Guest2 none
|
setstate rg_Guest2 none
|
||||||
setstate rg_Guest2 2014-02-15 16:15:39 durTimerAbsence 0
|
setstate rg_Guest2 2015-01-04 16:19:19 durTimerAbsence 00:00:00
|
||||||
setstate rg_Guest2 2014-02-16 13:34:05 durTimerPresence 0
|
setstate rg_Guest2 2015-01-04 16:19:19 durTimerAbsence_cr 0
|
||||||
setstate rg_Guest2 2014-02-15 16:15:39 durTimerSleep 0
|
setstate rg_Guest2 2015-01-04 16:19:19 durTimerPresence 00:00:00
|
||||||
|
setstate rg_Guest2 2015-01-04 16:19:19 durTimerPresence_cr 0
|
||||||
|
setstate rg_Guest2 2015-01-04 16:19:19 durTimerSleep 00:00:00
|
||||||
|
setstate rg_Guest2 2015-01-04 16:19:19 durTimerSleep_cr 0
|
||||||
setstate rg_Guest2 2014-02-16 14:01:22 lastArrival -
|
setstate rg_Guest2 2014-02-16 14:01:22 lastArrival -
|
||||||
setstate rg_Guest2 2014-02-16 14:09:29 lastAwake 0
|
setstate rg_Guest2 2014-02-16 14:09:29 lastAwake 0
|
||||||
setstate rg_Guest2 2014-02-16 14:00:46 lastDeparture 2014-02-16 14:00:45
|
setstate rg_Guest2 2014-02-16 14:00:46 lastDeparture 2014-02-16 14:00:45
|
||||||
@ -99,8 +121,8 @@ setstate rg_Guest2 2014-02-16 14:00:46 presence absent
|
|||||||
setstate rg_Guest2 2014-02-16 14:01:22 state none
|
setstate rg_Guest2 2014-02-16 14:01:22 state none
|
||||||
setstate rg_Guest2 2014-02-15 16:16:29 wayhome 0
|
setstate rg_Guest2 2014-02-15 16:16:29 wayhome 0
|
||||||
setstate rgr_Children home
|
setstate rgr_Children home
|
||||||
setstate rgr_Children 2014-02-17 20:45:12 lastActivity home
|
setstate rgr_Children 2015-01-04 16:19:19 lastActivity gone
|
||||||
setstate rgr_Children 2014-02-17 20:45:12 lastActivityBy Baby
|
setstate rgr_Children 2015-01-04 16:19:19 lastActivityBy Son
|
||||||
setstate rgr_Children 2014-02-16 14:31:05 lastArrival 2014-02-16 14:31:05
|
setstate rgr_Children 2014-02-16 14:31:05 lastArrival 2014-02-16 14:31:05
|
||||||
setstate rgr_Children 2014-02-17 20:45:12 lastAwake 2014-02-17 20:45:12
|
setstate rgr_Children 2014-02-17 20:45:12 lastAwake 2014-02-17 20:45:12
|
||||||
setstate rgr_Children 2014-02-16 14:26:55 lastDeparture 2014-02-16 14:26:55
|
setstate rgr_Children 2014-02-16 14:26:55 lastDeparture 2014-02-16 14:26:55
|
||||||
@ -110,10 +132,10 @@ setstate rgr_Children 2014-02-17 20:45:12 lastDurSleep 29:47:11
|
|||||||
setstate rgr_Children 2014-02-16 14:58:01 lastSleep 2014-02-16 14:58:01
|
setstate rgr_Children 2014-02-16 14:58:01 lastSleep 2014-02-16 14:58:01
|
||||||
setstate rgr_Children 2014-02-17 20:45:12 lastState asleep
|
setstate rgr_Children 2014-02-17 20:45:12 lastState asleep
|
||||||
setstate rgr_Children 2014-02-16 14:31:05 presence present
|
setstate rgr_Children 2014-02-16 14:31:05 presence present
|
||||||
setstate rgr_Children 2014-02-16 14:58:01 residentsAbsent 2
|
setstate rgr_Children 2015-01-04 16:19:19 residentsAbsent 0
|
||||||
setstate rgr_Children 2014-02-17 20:45:12 residentsAsleep 0
|
setstate rgr_Children 2014-02-17 20:45:12 residentsAsleep 0
|
||||||
setstate rgr_Children 2014-02-16 14:06:48 residentsAwoken 0
|
setstate rgr_Children 2014-02-16 14:06:48 residentsAwoken 0
|
||||||
setstate rgr_Children 2014-02-16 14:58:00 residentsGone 0
|
setstate rgr_Children 2015-01-04 16:19:19 residentsGone 2
|
||||||
setstate rgr_Children 2014-02-16 14:31:13 residentsGotosleep 0
|
setstate rgr_Children 2014-02-16 14:31:13 residentsGotosleep 0
|
||||||
setstate rgr_Children 2014-02-15 16:16:25 residentsGuests 0
|
setstate rgr_Children 2014-02-15 16:16:25 residentsGuests 0
|
||||||
setstate rgr_Children 2014-02-17 20:45:12 residentsHome 1
|
setstate rgr_Children 2014-02-17 20:45:12 residentsHome 1
|
||||||
@ -144,8 +166,8 @@ setstate rgr_Guests 2014-02-16 14:09:20 residentsTotalPresent 0
|
|||||||
setstate rgr_Guests 2014-02-15 16:16:27 residentsTotalWayhome 0
|
setstate rgr_Guests 2014-02-15 16:16:27 residentsTotalWayhome 0
|
||||||
setstate rgr_Guests 2014-02-16 14:09:20 state none
|
setstate rgr_Guests 2014-02-16 14:09:20 state none
|
||||||
setstate rgr_Parents home
|
setstate rgr_Parents home
|
||||||
setstate rgr_Parents 2014-02-17 20:45:19 lastActivity absent
|
setstate rgr_Parents 2015-01-04 16:19:19 lastActivity gone
|
||||||
setstate rgr_Parents 2014-02-17 20:45:19 lastActivityBy Father
|
setstate rgr_Parents 2015-01-04 16:19:19 lastActivityBy Father
|
||||||
setstate rgr_Parents 2014-02-16 14:16:17 lastArrival 2014-02-16 14:16:17
|
setstate rgr_Parents 2014-02-16 14:16:17 lastArrival 2014-02-16 14:16:17
|
||||||
setstate rgr_Parents 2014-02-15 16:39:35 lastAwake 2014-02-15 16:39:35
|
setstate rgr_Parents 2014-02-15 16:39:35 lastAwake 2014-02-15 16:39:35
|
||||||
setstate rgr_Parents 2014-02-16 14:16:16 lastDeparture 2014-02-16 14:16:16
|
setstate rgr_Parents 2014-02-16 14:16:16 lastDeparture 2014-02-16 14:16:16
|
||||||
@ -155,10 +177,10 @@ setstate rgr_Parents 2014-02-15 16:39:35 lastDurSleep 00:02:44
|
|||||||
setstate rgr_Parents 2014-02-15 16:36:51 lastSleep 2014-02-15 16:36:51
|
setstate rgr_Parents 2014-02-15 16:36:51 lastSleep 2014-02-15 16:36:51
|
||||||
setstate rgr_Parents 2014-02-16 14:16:17 lastState absent
|
setstate rgr_Parents 2014-02-16 14:16:17 lastState absent
|
||||||
setstate rgr_Parents 2014-02-16 14:16:17 presence present
|
setstate rgr_Parents 2014-02-16 14:16:17 presence present
|
||||||
setstate rgr_Parents 2014-02-17 20:45:19 residentsAbsent 1
|
setstate rgr_Parents 2015-01-04 16:19:19 residentsAbsent 0
|
||||||
setstate rgr_Parents 2014-02-16 13:31:53 residentsAsleep 0
|
setstate rgr_Parents 2014-02-16 13:31:53 residentsAsleep 0
|
||||||
setstate rgr_Parents 2014-02-16 13:31:53 residentsAwoken 0
|
setstate rgr_Parents 2014-02-16 13:31:53 residentsAwoken 0
|
||||||
setstate rgr_Parents 2014-02-17 20:45:19 residentsGone 0
|
setstate rgr_Parents 2015-01-04 16:19:19 residentsGone 1
|
||||||
setstate rgr_Parents 2014-02-15 16:36:51 residentsGotosleep 0
|
setstate rgr_Parents 2014-02-15 16:36:51 residentsGotosleep 0
|
||||||
setstate rgr_Parents 2014-02-15 16:13:39 residentsGuests 0
|
setstate rgr_Parents 2014-02-15 16:13:39 residentsGuests 0
|
||||||
setstate rgr_Parents 2014-02-16 14:26:52 residentsHome 1
|
setstate rgr_Parents 2014-02-16 14:26:52 residentsHome 1
|
||||||
@ -168,8 +190,8 @@ setstate rgr_Parents 2014-02-16 14:26:52 residentsTotalPresent 1
|
|||||||
setstate rgr_Parents 2014-02-15 16:13:39 residentsTotalWayhome 0
|
setstate rgr_Parents 2014-02-15 16:13:39 residentsTotalWayhome 0
|
||||||
setstate rgr_Parents 2014-02-16 14:16:17 state home
|
setstate rgr_Parents 2014-02-16 14:16:17 state home
|
||||||
setstate rgr_Residents home
|
setstate rgr_Residents home
|
||||||
setstate rgr_Residents 2014-02-17 20:45:19 lastActivity absent
|
setstate rgr_Residents 2015-01-04 16:19:19 lastActivity gone
|
||||||
setstate rgr_Residents 2014-02-17 20:45:19 lastActivityBy Father
|
setstate rgr_Residents 2015-01-04 16:19:19 lastActivityBy Son
|
||||||
setstate rgr_Residents 2014-02-16 14:16:17 lastArrival 2014-02-16 14:16:17
|
setstate rgr_Residents 2014-02-16 14:16:17 lastArrival 2014-02-16 14:16:17
|
||||||
setstate rgr_Residents 2014-02-16 14:02:48 lastAwake 2014-02-16 14:02:48
|
setstate rgr_Residents 2014-02-16 14:02:48 lastAwake 2014-02-16 14:02:48
|
||||||
setstate rgr_Residents 2014-02-16 14:16:16 lastDeparture 2014-02-16 14:16:16
|
setstate rgr_Residents 2014-02-16 14:16:16 lastDeparture 2014-02-16 14:16:16
|
||||||
@ -179,10 +201,10 @@ setstate rgr_Residents 2014-02-16 14:02:48 lastDurSleep 00:00:00
|
|||||||
setstate rgr_Residents 2014-02-16 14:02:48 lastSleep 2014-02-16 14:02:48
|
setstate rgr_Residents 2014-02-16 14:02:48 lastSleep 2014-02-16 14:02:48
|
||||||
setstate rgr_Residents 2014-02-16 14:16:17 lastState absent
|
setstate rgr_Residents 2014-02-16 14:16:17 lastState absent
|
||||||
setstate rgr_Residents 2014-02-16 14:16:17 presence present
|
setstate rgr_Residents 2014-02-16 14:16:17 presence present
|
||||||
setstate rgr_Residents 2014-02-17 20:45:19 residentsAbsent 3
|
setstate rgr_Residents 2015-01-04 16:19:19 residentsAbsent 0
|
||||||
setstate rgr_Residents 2014-02-17 20:45:12 residentsAsleep 0
|
setstate rgr_Residents 2014-02-17 20:45:12 residentsAsleep 0
|
||||||
setstate rgr_Residents 2014-02-16 14:06:49 residentsAwoken 0
|
setstate rgr_Residents 2014-02-16 14:06:49 residentsAwoken 0
|
||||||
setstate rgr_Residents 2014-02-17 20:45:19 residentsGone 0
|
setstate rgr_Residents 2015-01-04 16:19:19 residentsGone 3
|
||||||
setstate rgr_Residents 2014-02-16 14:31:13 residentsGotosleep 0
|
setstate rgr_Residents 2014-02-16 14:31:13 residentsGotosleep 0
|
||||||
setstate rgr_Residents 2014-02-16 14:09:20 residentsGuests 0
|
setstate rgr_Residents 2014-02-16 14:09:20 residentsGuests 0
|
||||||
setstate rgr_Residents 2014-02-17 20:45:12 residentsHome 2
|
setstate rgr_Residents 2014-02-17 20:45:12 residentsHome 2
|
||||||
@ -192,9 +214,12 @@ setstate rgr_Residents 2014-02-16 14:58:01 residentsTotalPresent 2
|
|||||||
setstate rgr_Residents 2014-02-15 16:13:39 residentsTotalWayhome 0
|
setstate rgr_Residents 2014-02-15 16:13:39 residentsTotalWayhome 0
|
||||||
setstate rgr_Residents 2014-02-16 14:16:17 state home
|
setstate rgr_Residents 2014-02-16 14:16:17 state home
|
||||||
setstate rr_Baby home
|
setstate rr_Baby home
|
||||||
setstate rr_Baby 2014-02-16 14:30:21 durTimerAbsence 0
|
setstate rr_Baby 2015-01-04 16:19:19 durTimerAbsence 00:00:00
|
||||||
setstate rr_Baby 2014-02-17 20:44:42 durTimerPresence 1814
|
setstate rr_Baby 2015-01-04 16:19:19 durTimerAbsence_cr 0
|
||||||
setstate rr_Baby 2014-02-17 20:45:12 durTimerSleep 0
|
setstate rr_Baby 2015-01-04 16:23:19 durTimerPresence 7729:52:58
|
||||||
|
setstate rr_Baby 2015-01-04 16:23:19 durTimerPresence_cr 463793
|
||||||
|
setstate rr_Baby 2015-01-04 16:19:19 durTimerSleep 00:00:00
|
||||||
|
setstate rr_Baby 2015-01-04 16:19:19 durTimerSleep_cr 0
|
||||||
setstate rr_Baby 2014-02-16 14:30:21 lastArrival 2014-02-16 14:30:21
|
setstate rr_Baby 2014-02-16 14:30:21 lastArrival 2014-02-16 14:30:21
|
||||||
setstate rr_Baby 2014-02-17 20:45:12 lastAwake 2014-02-17 20:45:12
|
setstate rr_Baby 2014-02-17 20:45:12 lastAwake 2014-02-17 20:45:12
|
||||||
setstate rr_Baby 2014-02-16 14:32:38 lastDeparture 0
|
setstate rr_Baby 2014-02-16 14:32:38 lastDeparture 0
|
||||||
@ -208,10 +233,13 @@ setstate rr_Baby 2014-02-17 20:45:12 mood calm
|
|||||||
setstate rr_Baby 2014-02-16 14:30:21 presence present
|
setstate rr_Baby 2014-02-16 14:30:21 presence present
|
||||||
setstate rr_Baby 2014-02-17 20:45:12 state home
|
setstate rr_Baby 2014-02-17 20:45:12 state home
|
||||||
setstate rr_Baby 2014-02-16 14:30:21 wayhome 0
|
setstate rr_Baby 2014-02-16 14:30:21 wayhome 0
|
||||||
setstate rr_Daughter absent
|
setstate rr_Daughter gone
|
||||||
setstate rr_Daughter 2014-02-17 20:45:42 durTimerAbsence 1787
|
setstate rr_Daughter 2015-01-04 16:23:19 durTimerAbsence 7729:25:20
|
||||||
setstate rr_Daughter 2014-02-16 14:26:54 durTimerPresence 0
|
setstate rr_Daughter 2015-01-04 16:23:19 durTimerAbsence_cr 463765
|
||||||
setstate rr_Daughter 2014-02-16 14:02:48 durTimerSleep 0
|
setstate rr_Daughter 2015-01-04 16:19:19 durTimerPresence 00:00:00
|
||||||
|
setstate rr_Daughter 2015-01-04 16:19:19 durTimerPresence_cr 0
|
||||||
|
setstate rr_Daughter 2015-01-04 16:19:19 durTimerSleep 00:00:00
|
||||||
|
setstate rr_Daughter 2015-01-04 16:19:19 durTimerSleep_cr 0
|
||||||
setstate rr_Daughter 2014-02-16 14:57:58 lastArrival 2014-02-16 14:57:58
|
setstate rr_Daughter 2014-02-16 14:57:58 lastArrival 2014-02-16 14:57:58
|
||||||
setstate rr_Daughter 2014-02-16 14:02:48 lastAwake 2014-02-16 14:02:48
|
setstate rr_Daughter 2014-02-16 14:02:48 lastAwake 2014-02-16 14:02:48
|
||||||
setstate rr_Daughter 2014-02-16 14:57:59 lastDeparture 2014-02-16 14:57:59
|
setstate rr_Daughter 2014-02-16 14:57:59 lastDeparture 2014-02-16 14:57:59
|
||||||
@ -221,32 +249,38 @@ setstate rr_Daughter 2014-02-16 14:02:48 lastDurSleep 00:08:12
|
|||||||
setstate rr_Daughter 2014-02-16 14:57:59 lastLocation home
|
setstate rr_Daughter 2014-02-16 14:57:59 lastLocation home
|
||||||
setstate rr_Daughter 2014-02-16 14:57:59 lastMood calm
|
setstate rr_Daughter 2014-02-16 14:57:59 lastMood calm
|
||||||
setstate rr_Daughter 2014-02-16 13:54:36 lastSleep 2014-02-16 13:54:36
|
setstate rr_Daughter 2014-02-16 13:54:36 lastSleep 2014-02-16 13:54:36
|
||||||
setstate rr_Daughter 2014-02-16 14:57:59 lastState home
|
setstate rr_Daughter 2015-01-04 16:19:19 lastState absent
|
||||||
setstate rr_Daughter 2014-02-16 14:57:59 location underway
|
setstate rr_Daughter 2014-02-16 14:57:59 location underway
|
||||||
setstate rr_Daughter 2014-02-16 14:57:59 mood -
|
setstate rr_Daughter 2014-02-16 14:57:59 mood -
|
||||||
setstate rr_Daughter 2014-02-16 14:57:59 presence absent
|
setstate rr_Daughter 2014-02-16 14:57:59 presence absent
|
||||||
setstate rr_Daughter 2014-02-16 14:57:59 state absent
|
setstate rr_Daughter 2015-01-04 16:19:19 state gone
|
||||||
setstate rr_Daughter 2014-02-16 13:46:26 wayhome 0
|
setstate rr_Daughter 2014-02-16 13:46:26 wayhome 0
|
||||||
setstate rr_Father absent
|
setstate rr_Father gone
|
||||||
setstate rr_Father 2014-02-17 20:45:19 durTimerAbsence 1818
|
setstate rr_Father 2015-01-04 16:23:19 durTimerAbsence 7729:56:27
|
||||||
setstate rr_Father 2014-02-16 14:26:52 durTimerPresence 0
|
setstate rr_Father 2015-01-04 16:23:19 durTimerAbsence_cr 463796
|
||||||
setstate rr_Father 2014-02-16 13:46:02 durTimerSleep 0
|
setstate rr_Father 2015-01-04 16:19:19 durTimerPresence 00:00:00
|
||||||
|
setstate rr_Father 2015-01-04 16:19:19 durTimerPresence_cr 0
|
||||||
|
setstate rr_Father 2015-01-04 16:19:19 durTimerSleep 00:00:00
|
||||||
|
setstate rr_Father 2015-01-04 16:19:19 durTimerSleep_cr 0
|
||||||
setstate rr_Father 2014-02-16 14:16:17 lastArrival 2014-02-16 14:16:17
|
setstate rr_Father 2014-02-16 14:16:17 lastArrival 2014-02-16 14:16:17
|
||||||
setstate rr_Father 2014-02-16 14:26:52 lastDeparture 2014-02-16 14:26:52
|
setstate rr_Father 2014-02-16 14:26:52 lastDeparture 2014-02-16 14:26:52
|
||||||
setstate rr_Father 2014-02-16 14:16:17 lastDurAbsence 00:00:01
|
setstate rr_Father 2014-02-16 14:16:17 lastDurAbsence 00:00:01
|
||||||
setstate rr_Father 2014-02-16 14:26:52 lastDurPresence 00:10:35
|
setstate rr_Father 2014-02-16 14:26:52 lastDurPresence 00:10:35
|
||||||
setstate rr_Father 2014-02-16 14:26:52 lastLocation home
|
setstate rr_Father 2014-02-16 14:26:52 lastLocation home
|
||||||
setstate rr_Father 2014-02-16 14:26:52 lastMood calm
|
setstate rr_Father 2014-02-16 14:26:52 lastMood calm
|
||||||
setstate rr_Father 2014-02-17 20:45:19 lastState gone
|
setstate rr_Father 2015-01-04 16:19:19 lastState absent
|
||||||
setstate rr_Father 2014-02-16 14:26:52 location underway
|
setstate rr_Father 2014-02-16 14:26:52 location underway
|
||||||
setstate rr_Father 2014-02-16 14:26:52 mood -
|
setstate rr_Father 2014-02-16 14:26:52 mood -
|
||||||
setstate rr_Father 2014-02-16 14:26:52 presence absent
|
setstate rr_Father 2014-02-16 14:26:52 presence absent
|
||||||
setstate rr_Father 2014-02-17 20:45:19 state absent
|
setstate rr_Father 2015-01-04 16:19:19 state gone
|
||||||
setstate rr_Father 2014-02-16 13:46:02 wayhome 0
|
setstate rr_Father 2014-02-16 13:46:02 wayhome 0
|
||||||
setstate rr_Mother home
|
setstate rr_Mother home
|
||||||
setstate rr_Mother 2014-02-16 14:04:26 durTimerAbsence 0
|
setstate rr_Mother 2015-01-04 16:19:19 durTimerAbsence 00:00:00
|
||||||
setstate rr_Mother 2014-02-17 20:45:42 durTimerPresence 1829
|
setstate rr_Mother 2015-01-04 16:19:19 durTimerAbsence_cr 0
|
||||||
setstate rr_Mother 2014-02-16 13:46:09 durTimerSleep 0
|
setstate rr_Mother 2015-01-04 16:23:19 durTimerPresence 7730:07:02
|
||||||
|
setstate rr_Mother 2015-01-04 16:23:19 durTimerPresence_cr 463807
|
||||||
|
setstate rr_Mother 2015-01-04 16:19:19 durTimerSleep 00:00:00
|
||||||
|
setstate rr_Mother 2015-01-04 16:19:19 durTimerSleep_cr 0
|
||||||
setstate rr_Mother 2014-02-16 14:16:17 lastArrival 2014-02-16 14:16:17
|
setstate rr_Mother 2014-02-16 14:16:17 lastArrival 2014-02-16 14:16:17
|
||||||
setstate rr_Mother 2014-02-16 14:16:16 lastDeparture 2014-02-16 14:16:16
|
setstate rr_Mother 2014-02-16 14:16:16 lastDeparture 2014-02-16 14:16:16
|
||||||
setstate rr_Mother 2014-02-16 14:16:17 lastDurAbsence 00:00:01
|
setstate rr_Mother 2014-02-16 14:16:17 lastDurAbsence 00:00:01
|
||||||
@ -259,10 +293,13 @@ setstate rr_Mother 2014-02-16 14:16:17 mood calm
|
|||||||
setstate rr_Mother 2014-02-16 14:16:17 presence present
|
setstate rr_Mother 2014-02-16 14:16:17 presence present
|
||||||
setstate rr_Mother 2014-02-16 14:16:17 state home
|
setstate rr_Mother 2014-02-16 14:16:17 state home
|
||||||
setstate rr_Mother 2014-02-16 13:46:09 wayhome 0
|
setstate rr_Mother 2014-02-16 13:46:09 wayhome 0
|
||||||
setstate rr_Son absent
|
setstate rr_Son gone
|
||||||
setstate rr_Son 2014-02-17 20:45:42 durTimerAbsence 1787
|
setstate rr_Son 2015-01-04 16:23:19 durTimerAbsence 7729:25:18
|
||||||
setstate rr_Son 2014-02-16 14:26:55 durTimerPresence 0
|
setstate rr_Son 2015-01-04 16:23:19 durTimerAbsence_cr 463765
|
||||||
setstate rr_Son 2014-02-16 14:00:53 durTimerSleep 0
|
setstate rr_Son 2015-01-04 16:19:19 durTimerPresence 00:00:00
|
||||||
|
setstate rr_Son 2015-01-04 16:19:19 durTimerPresence_cr 0
|
||||||
|
setstate rr_Son 2015-01-04 16:19:19 durTimerSleep 00:00:00
|
||||||
|
setstate rr_Son 2015-01-04 16:19:19 durTimerSleep_cr 0
|
||||||
setstate rr_Son 2014-02-16 14:58:00 lastArrival 2014-02-16 14:58:00
|
setstate rr_Son 2014-02-16 14:58:00 lastArrival 2014-02-16 14:58:00
|
||||||
setstate rr_Son 2014-02-16 14:06:44 lastAwake 2014-02-16 14:06:44
|
setstate rr_Son 2014-02-16 14:06:44 lastAwake 2014-02-16 14:06:44
|
||||||
setstate rr_Son 2014-02-16 14:58:01 lastDeparture 2014-02-16 14:58:01
|
setstate rr_Son 2014-02-16 14:58:01 lastDeparture 2014-02-16 14:58:01
|
||||||
@ -272,12 +309,12 @@ setstate rr_Son 2014-02-16 14:06:44 lastDurSleep 00:00:11
|
|||||||
setstate rr_Son 2014-02-16 14:58:01 lastLocation home
|
setstate rr_Son 2014-02-16 14:58:01 lastLocation home
|
||||||
setstate rr_Son 2014-02-16 14:58:01 lastMood calm
|
setstate rr_Son 2014-02-16 14:58:01 lastMood calm
|
||||||
setstate rr_Son 2014-02-16 14:06:33 lastSleep 2014-02-16 14:06:33
|
setstate rr_Son 2014-02-16 14:06:33 lastSleep 2014-02-16 14:06:33
|
||||||
setstate rr_Son 2014-02-16 14:58:01 lastState home
|
setstate rr_Son 2015-01-04 16:19:19 lastState absent
|
||||||
setstate rr_Son 2014-02-16 14:58:01 location underway
|
setstate rr_Son 2014-02-16 14:58:01 location underway
|
||||||
setstate rr_Son 2014-02-16 14:58:01 mood -
|
setstate rr_Son 2014-02-16 14:58:01 mood -
|
||||||
setstate rr_Son 2014-02-16 14:58:01 presence absent
|
setstate rr_Son 2014-02-16 14:58:01 presence absent
|
||||||
setstate rr_Son 2014-02-16 14:58:01 state absent
|
setstate rr_Son 2015-01-04 16:19:19 state gone
|
||||||
setstate rr_Son 2014-02-16 13:46:38 wayhome 0
|
setstate rr_Son 2014-02-16 13:46:38 wayhome 0
|
||||||
setstate sunRise Next: 06:58:34
|
setstate sunRise Next: 07:45:49
|
||||||
setstate sunSet Next: 18:20:46
|
setstate sunSet Next: 17:14:06
|
||||||
setstate wlCinema initialized
|
setstate wlCinema initialized
|
||||||
|
@ -73,7 +73,7 @@ attr Livingroom icon light_pendant_light
|
|||||||
attr Livingroom model fs20di
|
attr Livingroom model fs20di
|
||||||
attr Livingroom room Light
|
attr Livingroom room Light
|
||||||
attr Livingroom webCmd dim
|
attr Livingroom webCmd dim
|
||||||
define AllLights structure Light Alarm Livingroom Office Outdoor
|
define AllLights structure Light Alarm Livingroom Office Outdoor CT RGB
|
||||||
attr AllLights devStateIcon undefined:light_question
|
attr AllLights devStateIcon undefined:light_question
|
||||||
attr AllLights group Structure
|
attr AllLights group Structure
|
||||||
attr AllLights icon light_light
|
attr AllLights icon light_light
|
||||||
@ -164,7 +164,7 @@ attr ReadingLight eventMap off:dim0% on:dim100%
|
|||||||
attr ReadingLight group Light
|
attr ReadingLight group Light
|
||||||
attr ReadingLight icon light_floor_lamp
|
attr ReadingLight icon light_floor_lamp
|
||||||
attr ReadingLight room Cinema
|
attr ReadingLight room Cinema
|
||||||
attr ReadingLight webCmd on:off:dim
|
attr ReadingLight webCmd on:off:dim:dim 50
|
||||||
define wlCinema weblink htmlCode {LightScene_2html("lcCinema")}
|
define wlCinema weblink htmlCode {LightScene_2html("lcCinema")}
|
||||||
attr wlCinema room Cinema
|
attr wlCinema room Cinema
|
||||||
define lcCinema LightScene Projector Screen TV CeilingLight ReadingLight
|
define lcCinema LightScene Projector Screen TV CeilingLight ReadingLight
|
||||||
@ -185,6 +185,7 @@ attr anyViews dashboard_tab1name Dashboard Demo
|
|||||||
attr anyViews dashboard_tab1sorting t0c100,Light,true,518,129:t0c100,Home State,true,496,204:t0c0,Single Lights,true,522,209:t0c0,AV,true,221,170:
|
attr anyViews dashboard_tab1sorting t0c100,Light,true,518,129:t0c100,Home State,true,496,204:t0c0,Single Lights,true,522,209:t0c0,AV,true,221,170:
|
||||||
attr anyViews dashboard_tabcount 1
|
attr anyViews dashboard_tabcount 1
|
||||||
attr anyViews dashboard_width 80%
|
attr anyViews dashboard_width 80%
|
||||||
|
attr anyViews room hidden
|
||||||
|
|
||||||
define anyViews_weblink weblink htmlCode {DashboardAsHtml("anyViews")}
|
define anyViews_weblink weblink htmlCode {DashboardAsHtml("anyViews")}
|
||||||
attr anyViews_weblink room DashboardRoom
|
attr anyViews_weblink room DashboardRoom
|
||||||
@ -288,3 +289,29 @@ attr rr_Baby icon status_available
|
|||||||
attr rr_Baby room Residents
|
attr rr_Baby room Residents
|
||||||
attr rr_Baby sortby 0
|
attr rr_Baby sortby 0
|
||||||
attr rr_Baby webCmd state
|
attr rr_Baby webCmd state
|
||||||
|
define RGB readingsProxy RGB
|
||||||
|
attr RGB userattr Light Light_map structexclude
|
||||||
|
attr RGB Light AllLights
|
||||||
|
attr RGB alias RGB Light
|
||||||
|
attr RGB comment light with the ability to change RGB color
|
||||||
|
attr RGB devStateIcon {Color::devStateIcon("RGB","rgb","rgb","state")}
|
||||||
|
attr RGB group Color Lights
|
||||||
|
attr RGB room Light
|
||||||
|
attr RGB setFn {if( $CMD =~ m/on|off/ ) { $ARGS=$CMD;;$CMD = "state" } else {fhem ("setreading $DEVICE state on");;} if( $CMD =~ m/hue/ ) {my ($r,$g,$b) = Color::hsv2rgb($ARGS/360,1,1);; my $rgb = Color::rgb2hex( $r*255, $g*255, $b*255 );; fhem ("setreading $DEVICE rgb $rgb");;} if( $CMD =~ m/rgb/ && $ARGS =~ m/^(..)(..)(..)/ ) {my( $r, $g, $b ) = (hex($1)/255.0, hex($2)/255.0, hex($3)/255.0);; my ($h,$s,$v) = Color::rgb2hsv($r,$g,$b);; my $hue = int($h*359);; fhem ("setreading $DEVICE hue $hue");;} fhem ("setreading $DEVICE $CMD $ARGS");;return undef;;}
|
||||||
|
attr RGB setList on:noArg off:noArg rgb:colorpicker,RGB hue:colorpicker,HUE,0,1,359
|
||||||
|
attr RGB webCmd hue:rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:rgb ffffff:on:off
|
||||||
|
define colorInit notify global:INITIALIZED {use Color;;Color_Initialize()}
|
||||||
|
attr colorInit room hidden
|
||||||
|
define CT readingsProxy CT
|
||||||
|
attr CT userattr Light Light_map structexclude
|
||||||
|
attr CT Light AllLights
|
||||||
|
attr CT alias CT Light
|
||||||
|
attr CT comment light with the ability to change the color temperature
|
||||||
|
attr CT devStateIcon {Color::devStateIcon("CT","rgb","rgb","state")}
|
||||||
|
attr CT getFn { my ($r,$g,$b) = Color::ct2rgb( ReadingsVal($DEVICE,"ct",333) );; return (Color::rgb2hex($r,$g,$b), 1);; }
|
||||||
|
attr CT getList rgb:noArg
|
||||||
|
attr CT group Color Lights
|
||||||
|
attr CT room Light
|
||||||
|
attr CT setFn {if( $CMD =~ m/on|off/ ) { $ARGS=$CMD;;$CMD = "state" } else {fhem ("setreading $DEVICE state on");;} fhem ("setreading $DEVICE $CMD $ARGS");;return undef;;}
|
||||||
|
attr CT setList on:noArg off:noArg ct:colorpicker,CT,2000,1,6500
|
||||||
|
attr CT webCmd ct::ct 2040:ct 2630:ct 3703:ct 6250:on:off
|
||||||
|
@ -37,13 +37,18 @@ div.block { border:1px solid gray; background: #F8F8E0; padding:0.7em; }
|
|||||||
.makeSelect { display:inline; float:left; clear:left; }
|
.makeSelect { display:inline; float:left; clear:left; }
|
||||||
select { margin-left:5px; margin-right:5px; }
|
select { margin-left:5px; margin-right:5px; }
|
||||||
.slider { float:left; width:250px; height:26px; }
|
.slider { float:left; width:250px; height:26px; }
|
||||||
|
.colorpicker_ct .slider { background: url(../jscolor/ct_background.svg); }
|
||||||
|
.colorpicker_hue .slider { background: url(../jscolor/hue_background.svg); }
|
||||||
.get,.set,.attr { margin-bottom:5px; float:left; }
|
.get,.set,.attr { margin-bottom:5px; float:left; }
|
||||||
|
select.svgSrc { width:100px; }
|
||||||
|
select.svgColumn { width:50px; }
|
||||||
|
select.svgRegexp { width:120px; }
|
||||||
|
|
||||||
.handle { position:relative; cursor:pointer; width:50px;
|
.handle { position:relative; cursor:pointer; width:50px;
|
||||||
height:20px; line-height:20px;
|
height:20px; line-height:20px;
|
||||||
-webkit-user-select:none; -moz-user-select:none; -user-select:none;
|
-webkit-user-select:none; -moz-user-select:none; -user-select:none;
|
||||||
border:3px solid; color:#278727; text-align:center; }
|
border:3px solid; color:#278727; text-align:center; }
|
||||||
.downText { margin-top:2px; }
|
.downText { margin-top:2px; }
|
||||||
.makeSelect .slider {background:#F0F0D8; border-radius:8px;} /* detail only */
|
|
||||||
.set .set { margin-bottom:2px; margin-top:3px; } /* timepicker */
|
.set .set { margin-bottom:2px; margin-top:3px; } /* timepicker */
|
||||||
|
|
||||||
pre { white-space: pre-wrap; }
|
pre { white-space: pre-wrap; }
|
||||||
@ -60,8 +65,23 @@ svg.on,svg.FS20_on { fill:orange; }
|
|||||||
border-color:transparent; }
|
border-color:transparent; }
|
||||||
.rc_button img:active { border-color: gray; }
|
.rc_button img:active { border-color: gray; }
|
||||||
|
|
||||||
|
table#atWizard td:first-child { width: 240px; }
|
||||||
|
|
||||||
/* jQuery-UI mods */
|
/* jQuery-UI mods */
|
||||||
div.ui-dialog { border:3px solid #278727; padding: 0.2em; }
|
div.ui-dialog { border:3px solid #278727; padding: 0.2em; }
|
||||||
div.ui-dialog div.ui-dialog-titlebar { display:none; }
|
div.ui-dialog div.ui-dialog-titlebar { display:none; }
|
||||||
div.ui-widget-content { background:#FFFFE7; }
|
div.ui-widget-content { background:#FFFFE7; }
|
||||||
|
#fwmenu {
|
||||||
|
position: absolute; z-index:1005;
|
||||||
|
text-align:left; max-width:600px;
|
||||||
|
font-weight: normal; font-size: 100%;
|
||||||
|
background:#FFFFE7; border:1px solid #278727;
|
||||||
|
}
|
||||||
|
#fwmenu li a { color:#278727; }
|
||||||
|
|
||||||
|
div#svgmarker {
|
||||||
|
position: absolute; z-index:1005; padding: 6px 10px;
|
||||||
|
text-align:left; max-width:600px;
|
||||||
|
color:#278727; background:#FFFFE7;
|
||||||
|
border:2px solid #278727; border-radius:4px;
|
||||||
|
}
|
||||||
|
@ -1,51 +1,143 @@
|
|||||||
|
|
||||||
function
|
//TODO: realtime picker
|
||||||
FW_colorpickerUpdateLine(d)
|
//
|
||||||
{
|
|
||||||
var name = "colorpicker."+d[0];
|
|
||||||
|
|
||||||
el = document.getElementById(name);
|
|
||||||
|
|
||||||
if(el) {
|
|
||||||
if( d[1].length > 6 ) {
|
|
||||||
d[1] = d[1].slice(0,6);
|
|
||||||
}
|
|
||||||
el.color.fromString(d[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
colorpicker_setColor(el,mode,cmd)
|
|
||||||
{
|
|
||||||
var v = el.color;
|
|
||||||
|
|
||||||
if(mode==undefined) {
|
|
||||||
mode=el.pickerMode;
|
|
||||||
}
|
|
||||||
if(cmd==undefined) {
|
|
||||||
cmd=el.command;
|
|
||||||
}
|
|
||||||
if(v==undefined) {
|
|
||||||
v=el.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mode=="HSV") {
|
|
||||||
v = (0x100 | Math.round(42*el.color.hsv[0])).toString(16).substr(1) +
|
|
||||||
(0x100 | Math.round(255*el.color.hsv[1])).toString(16).substr(1) +
|
|
||||||
(0x100 | Math.round(255*el.color.hsv[2])).toString(16).substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var req = new XMLHttpRequest();
|
|
||||||
var qcmd = addcsrf(cmd.replace('%',v));
|
|
||||||
req.open("GET", qcmd, true);
|
|
||||||
req.send(null);
|
|
||||||
|
|
||||||
if( 0 )
|
|
||||||
if(cmd)
|
|
||||||
document.location = cmd.replace('%',v);
|
|
||||||
}
|
|
||||||
|
|
||||||
FW_widgets['colorpicker'] = {
|
FW_widgets['colorpicker'] = {
|
||||||
updateLine:FW_colorpickerUpdateLine
|
createFn:FW_colorpickerCreate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function
|
||||||
|
FW_colorpickerCreate(elName, devName, vArr, currVal, set, params, cmd)
|
||||||
|
{
|
||||||
|
if( 0 ) {
|
||||||
|
console.log( "elName: "+elName );
|
||||||
|
console.log( "devName: "+devName );
|
||||||
|
console.log( "vArr: "+vArr );
|
||||||
|
console.log( "currVal: "+currVal );
|
||||||
|
console.log( "set: "+set );
|
||||||
|
console.log( "params: "+params );
|
||||||
|
console.log( "cmd: "+cmd );
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!vArr.length || vArr[0] != "colorpicker")
|
||||||
|
return undefined;
|
||||||
|
|
||||||
|
|
||||||
|
var mode = "RGB";
|
||||||
|
if( vArr.length >= 1 )
|
||||||
|
mode = vArr[1]
|
||||||
|
|
||||||
|
//console.log( "mode: "+mode );
|
||||||
|
|
||||||
|
if( params && params.length ) {
|
||||||
|
var color = params[0];
|
||||||
|
if( mode == "CT" )
|
||||||
|
color = colorpicker_ct2rgb(color);
|
||||||
|
|
||||||
|
var newEl = $('<div informID="###" style="width:32px;height:19px;border:1px solid #fff;border-radius:8px;background-color:#'+color+'" >').get(0);
|
||||||
|
$(newEl).click(function(arg) { cmd(params[0]) });
|
||||||
|
return newEl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mode == "CT" ) {
|
||||||
|
var newEl = FW_createSlider(elName, devName, ["slider",vArr[2],vArr[3],vArr[4]], currVal, set, params, cmd);
|
||||||
|
$(newEl).addClass("colorpicker_ct");
|
||||||
|
return newEl;
|
||||||
|
|
||||||
|
} else if( mode == "HUE" ) {
|
||||||
|
var newEl = FW_createSlider(elName, devName, ["slider",vArr[2],vArr[3],vArr[4]], currVal, set, params, cmd);
|
||||||
|
$(newEl).addClass("colorpicker_hue");
|
||||||
|
return newEl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( currVal )
|
||||||
|
currVal = currVal.toUpperCase();
|
||||||
|
|
||||||
|
var newEl = $("<div style='display:inline-block'>").get(0);
|
||||||
|
$(newEl).append('<input type="text" id="colorpicker.'+ devName +'-'+set +'" maxlength="6" size="6">');
|
||||||
|
|
||||||
|
var inp = $(newEl).find("[type=text]");
|
||||||
|
|
||||||
|
var myPicker = new jscolor.color(inp.get(0),
|
||||||
|
{pickerMode:'RGB',pickerFaceColor:'transparent',pickerFace:3,pickerBorder:0,pickerInsetColor:'red'});
|
||||||
|
inp.get(0).color = myPicker;
|
||||||
|
|
||||||
|
if( currVal ) {
|
||||||
|
if( currVal.length > 6 ) currVal = currVal.slice(0,6);
|
||||||
|
myPicker.fromString(currVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( elName )
|
||||||
|
$(inp).attr("name", elName);
|
||||||
|
|
||||||
|
if( cmd )
|
||||||
|
$(newEl).change(function(arg) { cmd( myPicker.toString() ) });
|
||||||
|
else
|
||||||
|
$(newEl).change(function(arg) { $(inp).attr("value", myPicker.toString() ) });
|
||||||
|
|
||||||
|
newEl.setValueFn = function(arg){ if( arg.length > 6 ) arg = arg.slice(0,6);
|
||||||
|
myPicker.fromString(arg); };
|
||||||
|
|
||||||
|
return newEl;
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
colorpicker_ct2rgb(ct)
|
||||||
|
{
|
||||||
|
// calculation from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code
|
||||||
|
|
||||||
|
if( ct > 1000 ) // kelvin -> mired
|
||||||
|
ct = 1000000/ct;
|
||||||
|
|
||||||
|
// adjusted by 1000K
|
||||||
|
var temp = (1000000/ct)/100 + 10;
|
||||||
|
|
||||||
|
var r = 0;
|
||||||
|
var g = 0;
|
||||||
|
var b = 0;
|
||||||
|
|
||||||
|
r = 255;
|
||||||
|
if( temp > 66 )
|
||||||
|
r = 329.698727446 * Math.pow((temp - 60), -0.1332047592);
|
||||||
|
|
||||||
|
if( r < 0 )
|
||||||
|
r = 0;
|
||||||
|
else if( r > 255 )
|
||||||
|
r = 255;
|
||||||
|
|
||||||
|
if( temp <= 66 )
|
||||||
|
g = 99.4708025861 * Math.log(temp) - 161.1195681661;
|
||||||
|
else
|
||||||
|
g = 288.1221695283 * Math.pow((temp - 60), -0.0755148492);
|
||||||
|
|
||||||
|
if( g < 0 )
|
||||||
|
g = 0;
|
||||||
|
else if( g > 255 )
|
||||||
|
g = 255;
|
||||||
|
|
||||||
|
b = 255;
|
||||||
|
if( temp <= 19 )
|
||||||
|
b = 0;
|
||||||
|
if( temp < 66 )
|
||||||
|
b = 138.5177312231 * Math.log(temp-10) - 305.0447927307;
|
||||||
|
|
||||||
|
r = Math.round( r );
|
||||||
|
g = Math.round( g );
|
||||||
|
b = Math.round( b );
|
||||||
|
|
||||||
|
if( b < 0 )
|
||||||
|
b = 0;
|
||||||
|
else if( b > 255 )
|
||||||
|
b = 255;
|
||||||
|
|
||||||
|
return colorpicker_rgb2hex(r,g,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
colorpicker_rgb2hex(r,g,b) {
|
||||||
|
if( g !== undefined )
|
||||||
|
return Number(0x1000000 + r*0x10000 + g*0x100 + b).toString(16).substring(1);
|
||||||
|
else
|
||||||
|
return Number(0x1000000 + r[0]*0x10000 + r[1]*0x100 + r[2]).toString(16).substring(1);
|
||||||
|
}
|
||||||
|
38
fhem/www/pgm2/fhemweb_knob.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Wrapper for the jquery knob widget.
|
||||||
|
FW_widgets['knob'] = { createFn:FW_knobCreate, };
|
||||||
|
|
||||||
|
function
|
||||||
|
FW_knobCreate(elName, devName, vArr, currVal, set, params, cmd)
|
||||||
|
{
|
||||||
|
if(!vArr.length || vArr[0] != "knob" || (params && params.length))
|
||||||
|
return undefined;
|
||||||
|
|
||||||
|
var conf = {};
|
||||||
|
for(var i1=0; i1<vArr.length; i1++) {
|
||||||
|
var kv = vArr[i1].split(":");
|
||||||
|
conf[kv[0]] = kv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
currVal = (currVal == undefined) ?
|
||||||
|
conf.min : parseFloat(currVal.replace(/[^\d.\-]/g, ""));
|
||||||
|
if(!conf.width) conf.width=conf.height=100;
|
||||||
|
if(!conf.fgColor) conf.fgColor="#278727";
|
||||||
|
|
||||||
|
var newEl = $("<div style='display:inline-block'>").get(0);
|
||||||
|
$(newEl).append('<input type="text" id="knob.'+devName+'-'+set +'" >');
|
||||||
|
var inp = $(newEl).find("input");
|
||||||
|
if(elName)
|
||||||
|
$(inp).attr("name", elName);
|
||||||
|
for(c in conf)
|
||||||
|
$(inp).attr("data-"+c, conf[c]);
|
||||||
|
|
||||||
|
loadScript("pgm2/jquery.knob.min.js",
|
||||||
|
function() {
|
||||||
|
inp.knob({ 'release' : function(v){ if(cmd) cmd(v) } });
|
||||||
|
newEl.setValueFn = function(arg){ inp.val(arg);
|
||||||
|
inp.trigger('change'); };
|
||||||
|
newEl.setValueFn(currVal);
|
||||||
|
});
|
||||||
|
|
||||||
|
return newEl;
|
||||||
|
}
|
@ -1,90 +0,0 @@
|
|||||||
function
|
|
||||||
FW_multipleSelChange(name, devName, vArr)
|
|
||||||
{
|
|
||||||
if(vArr.length < 2 || (vArr[0] != "multiple" && vArr[0] != "multiple-strict"))
|
|
||||||
return undefined;
|
|
||||||
|
|
||||||
var o = new Object();
|
|
||||||
o.newEl = document.createElement('input');
|
|
||||||
o.newEl.type='text';
|
|
||||||
o.newEl.size=30;
|
|
||||||
o.qFn = 'FW_multipleSetSelected(qArg, "%")';
|
|
||||||
o.qArg = o.newEl;
|
|
||||||
|
|
||||||
o.newEl.setAttribute('onFocus', vArr[0] == "multiple-strict" ?
|
|
||||||
'FW_multipleSelect(this, true)' : 'FW_multipleSelect(this, false)');
|
|
||||||
|
|
||||||
o.newEl.setAttribute('allVals', vArr);
|
|
||||||
o.newEl.setAttribute('readonly', 'readonly');
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
FW_multipleSelect(el, strict)
|
|
||||||
{
|
|
||||||
loadLink("pgm2/jquery-ui.min.css");
|
|
||||||
loadScript("pgm2/jquery.min.js", function(){
|
|
||||||
loadScript("pgm2/jquery-ui.min.js", function() {
|
|
||||||
|
|
||||||
var sel = $(el).val().split(","), selObj={};
|
|
||||||
for(var i1=0; i1<sel.length; i1++)
|
|
||||||
selObj[sel[i1]] = 1;
|
|
||||||
|
|
||||||
var vArr = $(el).attr("allVals").replace(/#/g, " ").split(",");
|
|
||||||
var table = "";
|
|
||||||
for(var i1=1; i1<vArr.length; i1++) {
|
|
||||||
var v = vArr[i1];
|
|
||||||
table += '<tr>'+ // funny stuff for ios6 style, forum #23561
|
|
||||||
'<td><div class="checkbox"><input name="'+v+'" type="checkbox"'+
|
|
||||||
(selObj[v] ? " checked" : "")+'/>'+
|
|
||||||
'<label for="'+v+'"><span></span></label></div></td>'+
|
|
||||||
'<td><label for="' +v+'">'+v+'</label></td></tr>';
|
|
||||||
delete(selObj[v]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var selArr=[];
|
|
||||||
for(var i1 in selObj)
|
|
||||||
selArr.push(i1);
|
|
||||||
|
|
||||||
$('body').append(
|
|
||||||
'<div id="multidlg" style="display:none">'+
|
|
||||||
'<table>'+table+'</table>'+(!strict ? '<input id="md_freeText" '+
|
|
||||||
'value="'+selArr.join(',')+'"/>' : '')+
|
|
||||||
'</div>');
|
|
||||||
|
|
||||||
$('#multidlg').dialog(
|
|
||||||
{ modal:true, closeOnEscape:false, maxHeight:$(window).height()*3/4,
|
|
||||||
buttons:[
|
|
||||||
{ text:"Cancel", click:function(){ $('#multidlg').remove(); }},
|
|
||||||
{ text:"OK", click:function(){
|
|
||||||
var res=[];
|
|
||||||
if($("#md_freeText").val())
|
|
||||||
res.push($("#md_freeText").val());
|
|
||||||
$("#multidlg table input").each(function(){
|
|
||||||
if($(this).prop("checked"))
|
|
||||||
res.push($(this).attr("name"));
|
|
||||||
});
|
|
||||||
$(el).val(res.join(","));
|
|
||||||
$('#multidlg').remove();
|
|
||||||
}}]});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
FW_multipleSetSelected(el, val)
|
|
||||||
{
|
|
||||||
if(typeof el == 'string')
|
|
||||||
el = document.getElementById(el);
|
|
||||||
el.value=val;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FW_widgets['multiple'] = {
|
|
||||||
selChange:FW_multipleSelChange
|
|
||||||
};
|
|
||||||
|
|
||||||
FW_widgets['multiple-strict'] = {
|
|
||||||
selChange:FW_multipleSelChange
|
|
||||||
};
|
|
@ -1,14 +0,0 @@
|
|||||||
function
|
|
||||||
FW_noArgSelChange(name, devName, vArr)
|
|
||||||
{
|
|
||||||
if(vArr.length != 1 || vArr[0] != "noArg")
|
|
||||||
return undefined;
|
|
||||||
|
|
||||||
var o = new Object();
|
|
||||||
o.newEl = document.createElement('div');
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
FW_widgets['noArg'] = {
|
|
||||||
selChange:FW_noArgSelChange
|
|
||||||
};
|
|
@ -1,153 +0,0 @@
|
|||||||
/*************** SLIDER **************/
|
|
||||||
|
|
||||||
function
|
|
||||||
FW_sliderUpdateLine(d)
|
|
||||||
{
|
|
||||||
for(var k=0; k<2; k++) {
|
|
||||||
var name = "slider."+d[0];
|
|
||||||
if(k == 1)
|
|
||||||
name = name+"-"+d[1].replace(/[ \d].*$/,'');
|
|
||||||
el = document.getElementById(name);
|
|
||||||
if(el) {
|
|
||||||
var doSet = 1; // Only set the "state" slider in the detail view
|
|
||||||
if(el.parentNode.getAttribute("name") == "val.set"+d[0]) {
|
|
||||||
var el2 = document.getElementsByName("arg.set"+d[0])[0];
|
|
||||||
if(el2.nodeName.toLowerCase() == "select" &&
|
|
||||||
el2.options[el2.selectedIndex].value != "state")
|
|
||||||
doSet = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(doSet) {
|
|
||||||
var val = d[1].replace(/^.*?([.\-\d]+).*/g, "$1"); // get first number
|
|
||||||
if(!val.match(/[.\-\d]+/))
|
|
||||||
val = 0;
|
|
||||||
FW_sliderCreate(el, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
FW_sliderCreate(slider, curr)
|
|
||||||
{
|
|
||||||
var sh = slider.firstChild;
|
|
||||||
var lastX=-1, offX=0, maxX=0, val;
|
|
||||||
var min = parseFloat(slider.getAttribute("min"));
|
|
||||||
var stp = parseFloat(slider.getAttribute("stp"));
|
|
||||||
var max = parseFloat(slider.getAttribute("max"));
|
|
||||||
var flt = parseFloat(slider.getAttribute("flt"));
|
|
||||||
var cmd = slider.getAttribute("cmd");
|
|
||||||
|
|
||||||
function
|
|
||||||
init()
|
|
||||||
{
|
|
||||||
maxX = slider.offsetWidth-sh.offsetWidth;
|
|
||||||
if(curr) {
|
|
||||||
offX += (curr-min)*maxX/(max-min);
|
|
||||||
sh.innerHTML = curr;
|
|
||||||
sh.setAttribute('style', 'left:'+offX+'px;');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
init();
|
|
||||||
|
|
||||||
function
|
|
||||||
touchFn(e, fn)
|
|
||||||
{
|
|
||||||
e.preventDefault(); // Prevents Safari from scrolling!
|
|
||||||
if(e.touches == null || e.touches.length == 0)
|
|
||||||
return;
|
|
||||||
e.clientX = e.touches[0].clientX;
|
|
||||||
fn(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
mouseDown(e)
|
|
||||||
{
|
|
||||||
var oldFn1 = document.onmousemove, oldFn2 = document.onmouseup,
|
|
||||||
oldFn3 = document.ontouchmove, oldFn4 = document.ontouchend;
|
|
||||||
|
|
||||||
if(maxX == 0)
|
|
||||||
init();
|
|
||||||
lastX = e.clientX;
|
|
||||||
|
|
||||||
function
|
|
||||||
mouseMove(e)
|
|
||||||
{
|
|
||||||
var diff = e.clientX-lastX; lastX = e.clientX;
|
|
||||||
offX += diff;
|
|
||||||
if(offX < 0) offX = 0;
|
|
||||||
if(offX > maxX) offX = maxX;
|
|
||||||
val = min+(offX/maxX * (max-min));
|
|
||||||
val = (flt ? Math.floor(val/stp)*stp :
|
|
||||||
Math.floor(Math.floor(val/stp)*stp));
|
|
||||||
sh.innerHTML = val;
|
|
||||||
sh.setAttribute('style', 'left:'+offX+'px;');
|
|
||||||
if(cmd && cmd.substring(0,3) == "js:") {
|
|
||||||
eval(cmd.substring(3).replace('%',val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
document.onmousemove = mouseMove;
|
|
||||||
document.ontouchmove = function(e) { touchFn(e, mouseMove); }
|
|
||||||
|
|
||||||
document.onmouseup = document.ontouchend = function(e)
|
|
||||||
{
|
|
||||||
document.onmousemove = oldFn1; document.onmouseup = oldFn2;
|
|
||||||
document.ontouchmove = oldFn3; document.ontouchend = oldFn4;
|
|
||||||
if(cmd) {
|
|
||||||
if(cmd.substring(0,3) != "js:")
|
|
||||||
if(typeof val != "undefined") {
|
|
||||||
if(typeof FW_pollConn != "undefined")
|
|
||||||
FW_cmd(cmd.replace('%',val)+"&XHR=1");
|
|
||||||
else
|
|
||||||
window.location = addcsrf(cmd.replace('%',val));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(typeof val != "undefined")
|
|
||||||
slider.nextSibling.setAttribute('value', val);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sh.onselectstart = function() { return false; }
|
|
||||||
sh.onmousedown = mouseDown;
|
|
||||||
sh.ontouchstart = function(e) { touchFn(e, mouseDown); }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function
|
|
||||||
FW_sliderSelChange(name, devName, vArr)
|
|
||||||
{
|
|
||||||
if(vArr.length < 4 || vArr.length > 5 || vArr[0] != "slider")
|
|
||||||
return undefined;
|
|
||||||
|
|
||||||
var o = new Object();
|
|
||||||
var min=parseFloat(vArr[1]),
|
|
||||||
stp=parseFloat(vArr[2]),
|
|
||||||
max=parseFloat(vArr[3]),
|
|
||||||
flt=parseFloat(vArr[4]);
|
|
||||||
if(!flt) flt=0;
|
|
||||||
o.newEl = document.createElement('div');
|
|
||||||
o.newEl.innerHTML =
|
|
||||||
'<div class="slider" id="slider.'+devName+
|
|
||||||
'" min="'+min+'" stp="'+stp+'" max="'+max+'" flt="'+flt+
|
|
||||||
'"><div class="handle">'+min+'</div></div>'+
|
|
||||||
'<input type="hidden" name="'+name+'" value="'+min+'">';
|
|
||||||
FW_sliderCreate(o.newEl.firstChild, undefined);
|
|
||||||
|
|
||||||
o.qFn = 'FW_querySetSlider(qArg, "%")';
|
|
||||||
o.qArg = o.newEl.firstChild;
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
FW_querySetSlider(el, val)
|
|
||||||
{
|
|
||||||
val = val.replace(/[^\d.\-]/g, ""); // remove non numbers
|
|
||||||
FW_sliderCreate(el, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
FW_widgets['slider'] = {
|
|
||||||
updateLine:FW_sliderUpdateLine,
|
|
||||||
selChange:FW_sliderSelChange
|
|
||||||
};
|
|
@ -1,27 +0,0 @@
|
|||||||
function
|
|
||||||
FW_svgUpdateDevs(devs)
|
|
||||||
{
|
|
||||||
// if matches, refresh the SVG by removing and readding the embed tag
|
|
||||||
var embArr = document.getElementsByTagName("embed");
|
|
||||||
for(var i = 0; i < embArr.length; i++) {
|
|
||||||
var svg = embArr[i].getSVGDocument();
|
|
||||||
if(!svg || !svg.firstChild || !svg.firstChild.nextSibling)
|
|
||||||
continue;
|
|
||||||
var flog = svg.firstChild.nextSibling.getAttribute("flog");
|
|
||||||
for(var j=0; j < devs.length; j++) {
|
|
||||||
if(flog !== null && flog.match(" "+devs[j]+" ")) {
|
|
||||||
var e = embArr[i];
|
|
||||||
var newE = document.createElement("embed");
|
|
||||||
for(var k=0; k<e.attributes.length; k++)
|
|
||||||
newE.setAttribute(e.attributes[k].name, e.attributes[k].value);
|
|
||||||
e.parentNode.insertBefore(newE, e);
|
|
||||||
e.parentNode.removeChild(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FW_widgets['SVG'] = {
|
|
||||||
updateDevs:FW_svgUpdateDevs,
|
|
||||||
};
|
|
@ -1,46 +0,0 @@
|
|||||||
function
|
|
||||||
FW_textFieldUpdateLine(d)
|
|
||||||
{
|
|
||||||
var name = "textField."+d[0];
|
|
||||||
el = document.getElementById(name);
|
|
||||||
if(el)
|
|
||||||
el.value = d[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
FW_textFieldSelChange(name, devName, vArr)
|
|
||||||
{
|
|
||||||
if(vArr.length != 1 || vArr[0] != "textField")
|
|
||||||
return undefined;
|
|
||||||
|
|
||||||
var o = new Object();
|
|
||||||
o.newEl = document.createElement('input');
|
|
||||||
o.newEl.type='text';
|
|
||||||
o.newEl.size=30;
|
|
||||||
o.qFn = 'FW_textFieldSetSelected(qArg, "%")';
|
|
||||||
o.qArg = o.newEl;
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
FW_textFieldSetSelected(el, val)
|
|
||||||
{
|
|
||||||
if(typeof el == 'string')
|
|
||||||
el = document.getElementById(el);
|
|
||||||
el.value=val;
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
textField_setText(el,cmd)
|
|
||||||
{
|
|
||||||
var v = el.value;
|
|
||||||
var req = new XMLHttpRequest();
|
|
||||||
var qcmd = addcsrf(cmd.replace('%',v));
|
|
||||||
req.open("GET", qcmd, true);
|
|
||||||
req.send(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
FW_widgets['textField'] = {
|
|
||||||
updateLine:FW_textFieldUpdateLine,
|
|
||||||
selChange:FW_textFieldSelChange
|
|
||||||
};
|
|
@ -1,69 +0,0 @@
|
|||||||
function
|
|
||||||
FW_timeSet(el,name,val)
|
|
||||||
{
|
|
||||||
var el = el.parentNode.parentNode.firstChild;
|
|
||||||
var v = el.value.split(":");
|
|
||||||
v[name] = ''+val;
|
|
||||||
if(v[0].length < 2) v[0] = '0'+v[0];
|
|
||||||
if(v[1].length < 2) v[1] = '0'+v[1];
|
|
||||||
el.value = v[0]+":"+v[1];
|
|
||||||
el.setAttribute('value', el.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
FW_timeCreate(el,cmd)
|
|
||||||
{
|
|
||||||
var par = el.parentNode;
|
|
||||||
var v = par.firstChild.value;
|
|
||||||
var brOff = par.innerHTML.indexOf("<br>");
|
|
||||||
|
|
||||||
if(brOff > 0) {
|
|
||||||
par.innerHTML = par.innerHTML.substring(0, brOff).replace('"-"','"+"');
|
|
||||||
if(cmd) {
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
el.setAttribute('value', '-');
|
|
||||||
if(v.indexOf(":") < 0)
|
|
||||||
par.firstChild.value = v = "12:00";
|
|
||||||
var val = v.split(":");
|
|
||||||
|
|
||||||
for(var i = 0; i < 2; i++) {
|
|
||||||
par.appendChild(document.createElement('br'));
|
|
||||||
|
|
||||||
var sl = document.createElement('div');
|
|
||||||
sl.innerHTML = '<div class="slider" min="0" stp='+(i==0?1:5)+
|
|
||||||
' max='+(i==0?23:55)+
|
|
||||||
' cmd="js:FW_timeSet(slider,'+i+',%)"'+
|
|
||||||
'><div class="handle">'+val[i]+
|
|
||||||
'</div></div>';
|
|
||||||
par.appendChild(sl);
|
|
||||||
sl.setAttribute('class', par.getAttribute('class'));
|
|
||||||
|
|
||||||
FW_sliderCreate(sl.firstChild, val[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
FW_timeSelChange(name, devName, vArr)
|
|
||||||
{
|
|
||||||
if(vArr.length != 1 || vArr[0] != "time")
|
|
||||||
return undefined;
|
|
||||||
|
|
||||||
var o = new Object();
|
|
||||||
o.newEl = document.createElement('div');
|
|
||||||
o.newEl.innerHTML='<input name="'+name+'" type="text" size="5">'+
|
|
||||||
'<input type="button" value="+" onclick="FW_timeCreate(this)">';
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
FW_widgets['time'] = {
|
|
||||||
selChange:FW_timeSelChange
|
|
||||||
};
|
|
BIN
fhem/www/pgm2/images/ui-bg_flat_0_aaaaaa_40x100.png
Normal file
After Width: | Height: | Size: 180 B |
BIN
fhem/www/pgm2/images/ui-bg_flat_75_ffffff_40x100.png
Normal file
After Width: | Height: | Size: 178 B |
BIN
fhem/www/pgm2/images/ui-bg_glass_65_ffffff_1x400.png
Normal file
After Width: | Height: | Size: 105 B |
BIN
fhem/www/pgm2/images/ui-bg_glass_75_dadada_1x400.png
Normal file
After Width: | Height: | Size: 111 B |
BIN
fhem/www/pgm2/images/ui-bg_glass_75_e6e6e6_1x400.png
Normal file
After Width: | Height: | Size: 110 B |
BIN
fhem/www/pgm2/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Normal file
After Width: | Height: | Size: 101 B |
BIN
fhem/www/pgm2/images/ui-icons_222222_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
23
fhem/www/pgm2/jquery.knob.min.js
vendored
Executable file
@ -1,13 +1,12 @@
|
|||||||
var xmlns="http://www.w3.org/2000/svg";
|
"use strict";
|
||||||
var old_title;
|
var svgNS = "http://www.w3.org/2000/svg";
|
||||||
var old_sel;
|
var svg_b64 ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
var svgdoc;
|
var svg_initialized={};
|
||||||
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
||||||
var to;
|
|
||||||
|
|
||||||
// Base64 encode the xy points (12 bit x, 12 bit y).
|
// Base64 encode the xy points (12 bit x, 12 bit y).
|
||||||
function
|
function
|
||||||
compressPoints(pointList)
|
svg_compressPoints(pointList)
|
||||||
{
|
{
|
||||||
var i, x, y, lx = -1, ly, ret = "";
|
var i, x, y, lx = -1, ly, ret = "";
|
||||||
var pl_arr = pointList.replace(/^ */,'').split(/[, ]/);
|
var pl_arr = pointList.replace(/^ */,'').split(/[, ]/);
|
||||||
@ -17,24 +16,24 @@ compressPoints(pointList)
|
|||||||
if(pl_arr.length > 500 && lx != -1 && x-lx < 2) // Filter the data.
|
if(pl_arr.length > 500 && lx != -1 && x-lx < 2) // Filter the data.
|
||||||
continue;
|
continue;
|
||||||
ret = ret+
|
ret = ret+
|
||||||
b64.charAt((x&0xfc0)>>6)+
|
svg_b64.charAt((x&0xfc0)>>6)+
|
||||||
b64.charAt((x&0x3f))+
|
svg_b64.charAt((x&0x3f))+
|
||||||
b64.charAt((y&0xfc0)>>6)+
|
svg_b64.charAt((y&0xfc0)>>6)+
|
||||||
b64.charAt((y&0x3f));
|
svg_b64.charAt((y&0x3f));
|
||||||
lx = x; ly = y;
|
lx = x; ly = y;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
function
|
||||||
uncompressPoints(cmpData)
|
svg_uncompressPoints(cmpData)
|
||||||
{
|
{
|
||||||
var i = 0, ret = "";
|
var i = 0, ret = "";
|
||||||
while(i < cmpData.length) {
|
while(i < cmpData.length) {
|
||||||
var x = (b64.indexOf(cmpData.charAt(i++))<<6)+
|
var x = (svg_b64.indexOf(cmpData.charAt(i++))<<6)+
|
||||||
b64.indexOf(cmpData.charAt(i++));
|
svg_b64.indexOf(cmpData.charAt(i++));
|
||||||
var y = (b64.indexOf(cmpData.charAt(i++))<<6)+
|
var y = (svg_b64.indexOf(cmpData.charAt(i++))<<6)+
|
||||||
b64.indexOf(cmpData.charAt(i++));
|
svg_b64.indexOf(cmpData.charAt(i++));
|
||||||
ret += " "+x+","+y;
|
ret += " "+x+","+y;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -42,130 +41,245 @@ uncompressPoints(cmpData)
|
|||||||
|
|
||||||
|
|
||||||
function
|
function
|
||||||
get_cookie()
|
svg_getcookie()
|
||||||
{
|
{
|
||||||
var c = parent.document.cookie;
|
var c = document.cookie;
|
||||||
if(c == null)
|
if(c == null)
|
||||||
return "";
|
return [];
|
||||||
var results = c.match('fhemweb=(.*?)(;|$)' );
|
var results = c.match('fhemweb=(.*?)(;|$)' );
|
||||||
return (results ? unescape(results[1]) : "");
|
return (results ? unescape(results[1]).split(":") : []);
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
function
|
||||||
set_cookie(value)
|
svg_prepareHash(el)
|
||||||
{
|
{
|
||||||
parent.document.cookie="fhemweb="+escape(value);
|
var obj = { y_mul:0,y_h:0,y_min:0, decimals:0, x_mul:0,x_off:0,x_min:0 };
|
||||||
}
|
for(var name in obj)
|
||||||
|
obj[name] = parseFloat($(el).attr(name));
|
||||||
|
return obj;
|
||||||
function
|
|
||||||
svg_copy(evt)
|
|
||||||
{
|
|
||||||
var d = evt.target.ownerDocument;
|
|
||||||
var cp = d.getElementById("svg_copy");
|
|
||||||
cp.firstChild.nodeValue = " ";
|
|
||||||
set_cookie(old_sel.getAttribute("y_min")+":"+
|
|
||||||
old_sel.getAttribute("y_mul")+":"+
|
|
||||||
compressPoints(old_sel.getAttribute("points")));
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
svg_paste(evt)
|
|
||||||
{
|
|
||||||
var d = evt.target.ownerDocument;
|
|
||||||
var ps = d.getElementById("svg_paste");
|
|
||||||
ps.firstChild.nodeValue = " ";
|
|
||||||
|
|
||||||
var o=d.createElementNS(xmlns, "polyline");
|
|
||||||
o.setAttribute("class", "pasted");
|
|
||||||
var data = get_cookie().split(":", 3);
|
|
||||||
o.setAttribute("points", uncompressPoints(data[2]));
|
|
||||||
|
|
||||||
var h = parseFloat(old_sel.getAttribute("y_h"));
|
|
||||||
var ny_mul = parseFloat(data[1]);
|
|
||||||
var ny_min = parseInt(data[0]);
|
|
||||||
var y_mul = parseFloat(old_sel.getAttribute("y_mul"));
|
|
||||||
var y_min = parseInt(old_sel.getAttribute("y_min"));
|
|
||||||
var tr =
|
|
||||||
"translate(0,"+ (h/y_mul+y_min-h/ny_mul-ny_min)*y_mul +") "+
|
|
||||||
"scale(1, "+ (y_mul/ny_mul) +") ";
|
|
||||||
o.setAttribute("transform", tr);
|
|
||||||
d.documentElement.appendChild(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
showOtherLines(d, lid, currval, maxval)
|
|
||||||
{
|
|
||||||
for(var i=0; i < 9; i++) {
|
|
||||||
var id="line_"+i;
|
|
||||||
var el = d.getElementById(id);
|
|
||||||
if(el && id != lid) {
|
|
||||||
var h = parseFloat(el.getAttribute("y_h"));
|
|
||||||
el.setAttribute("transform", "translate(0,"+h*(1-currval)+") "+
|
|
||||||
"scale(1,"+currval+")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(currval != maxval) {
|
|
||||||
currval += (currval<maxval ? 0.02 : -0.02);
|
|
||||||
currval = Math.round(currval*100)/100;
|
|
||||||
to=setTimeout(function(){showOtherLines(d,lid,currval,maxval)},10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function
|
|
||||||
svg_labelselect(evt)
|
|
||||||
{
|
|
||||||
var d = evt.target.ownerDocument;
|
|
||||||
var lid = evt.target.getAttribute("line_id");
|
|
||||||
var sel = d.getElementById(lid);
|
|
||||||
var tl = d.getElementById("svg_title");
|
|
||||||
var cp = d.getElementById("svg_copy");
|
|
||||||
var ps = d.getElementById("svg_paste");
|
|
||||||
|
|
||||||
clearTimeout(to);
|
|
||||||
if(old_sel == sel) {
|
|
||||||
sel.setAttribute("stroke-width", 1);
|
|
||||||
old_sel = null;
|
|
||||||
tl.firstChild.nodeValue = old_title;
|
|
||||||
cp.firstChild.nodeValue = " ";
|
|
||||||
ps.firstChild.nodeValue = " ";
|
|
||||||
showOtherLines(d, lid, 0, 1);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if(old_sel == null)
|
|
||||||
old_title = tl.firstChild.nodeValue;
|
|
||||||
else
|
|
||||||
old_sel.setAttribute("stroke-width", 1);
|
|
||||||
sel.setAttribute("stroke-width", 3);
|
|
||||||
old_sel = sel;
|
|
||||||
if(sel.getAttribute("points") != null) {
|
|
||||||
tl.firstChild.nodeValue = evt.target.getAttribute("title");
|
|
||||||
cp.firstChild.nodeValue = "Copy";
|
|
||||||
ps.firstChild.nodeValue = (get_cookie()==""?" ":"Paste");
|
|
||||||
}
|
|
||||||
showOtherLines(d, lid, 1, 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
function
|
||||||
svg_click(evt)
|
svg_click(evt)
|
||||||
{
|
{
|
||||||
var t=evt.target;
|
var t = evt.target;
|
||||||
var y_mul = parseFloat(t.getAttribute("y_mul"));
|
var o = svg_prepareHash(t);
|
||||||
var y_h = parseFloat(t.getAttribute("y_h"));
|
|
||||||
var y_min = parseFloat(t.getAttribute("y_min"));
|
|
||||||
var y_fx = parseFloat(t.getAttribute("decimals"));
|
|
||||||
var y_org = (((y_h-evt.clientY)/y_mul)+y_min).toFixed(y_fx);
|
|
||||||
|
|
||||||
var x_mul = parseFloat(t.getAttribute("x_mul"));
|
var y_org = (((o.y_h-evt.clientY)/o.y_mul)+o.y_min).toFixed(o.decimals);
|
||||||
var x_off = parseFloat(t.getAttribute("x_off"));
|
var d = new Date((((evt.clientX-o.x_min)/o.x_mul)+o.x_off) * 1000);
|
||||||
var x_min = parseFloat(t.getAttribute("x_min"));
|
|
||||||
var d = new Date((((evt.clientX-x_min)/x_mul)+x_off) * 1000);
|
|
||||||
var ts = (d.getHours() < 10 ? '0' : '') + d.getHours() + ":"+
|
var ts = (d.getHours() < 10 ? '0' : '') + d.getHours() + ":"+
|
||||||
(d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
|
(d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
|
||||||
|
|
||||||
|
|
||||||
var tl = evt.target.ownerDocument.getElementById('svg_title');
|
var tl = t.ownerDocument.getElementById('svg_title');
|
||||||
tl.firstChild.nodeValue = t.getAttribute("title")+": "+y_org+" ("+ts+")";
|
tl.firstChild.nodeValue = t.getAttribute("title")+": "+y_org+" ("+ts+")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
sv_menu(evt, embed)
|
||||||
|
{
|
||||||
|
var label = evt.target;
|
||||||
|
var svg = $(label).closest("svg");
|
||||||
|
var svgNode = $(svg).get(0);
|
||||||
|
var lid = $(label).attr("line_id");
|
||||||
|
var data = svg_getcookie();
|
||||||
|
var sel = $(svg).find("#"+lid);
|
||||||
|
var selNode = $(sel).get(0);
|
||||||
|
var tl = $(svg).find("#svg_title");
|
||||||
|
var par = svgNode.par;
|
||||||
|
|
||||||
|
FW_menu(evt, label,
|
||||||
|
["Copy", "Paste",
|
||||||
|
svgNode.isSingle ? "Show all lines":"Hide other lines",
|
||||||
|
selNode.showVal ? "Stop displaying values" : "Display plot values" ],
|
||||||
|
[undefined, data.length==0, undefined, selNode.nodeName!="polyline"],
|
||||||
|
function(arg) {
|
||||||
|
|
||||||
|
//////////////////////////////////// copy
|
||||||
|
if(arg == 0) {
|
||||||
|
document.cookie="fhemweb="+
|
||||||
|
$(sel).attr("y_min")+":"+$(sel).attr("y_mul")+":"+
|
||||||
|
svg_compressPoints($(sel).attr("points"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////// paste
|
||||||
|
if(arg == 1) {
|
||||||
|
var doc = $(svg).get(0).ownerDocument;
|
||||||
|
var o=doc.createElementNS(svgNS, "polyline");
|
||||||
|
o.setAttribute("class", "pasted");
|
||||||
|
o.setAttribute("points", svg_uncompressPoints(data[2]));
|
||||||
|
|
||||||
|
var h = parseFloat($(sel).attr("y_h"));
|
||||||
|
var ny_mul = parseFloat(data[1]);
|
||||||
|
var ny_min = parseInt(data[0]);
|
||||||
|
var y_mul = parseFloat($(sel).attr("y_mul"));
|
||||||
|
var y_min = parseInt($(sel).attr("y_min"));
|
||||||
|
var tr =
|
||||||
|
"translate(0,"+ (h/y_mul+y_min-h/ny_mul-ny_min)*y_mul +") "+
|
||||||
|
"scale(1, "+ (y_mul/ny_mul) +") ";
|
||||||
|
o.setAttribute("transform", tr);
|
||||||
|
doc.documentElement.appendChild(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////// hide/show lines
|
||||||
|
if(arg == 2) {
|
||||||
|
if(svgNode.isSingle) {
|
||||||
|
delete(svgNode.isSingle);
|
||||||
|
$(sel).attr("stroke-width", 1);
|
||||||
|
$(tl).html($(tl).attr("hiddentitle"));
|
||||||
|
showOtherLines(0, 1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
svgNode.isSingle = 1;
|
||||||
|
$(sel).attr("stroke-width", 3);
|
||||||
|
$(tl).attr("hiddentitle", $(tl).html());
|
||||||
|
if($(sel).attr("points") != null)
|
||||||
|
$(tl).html($(label).attr("title"));
|
||||||
|
showOtherLines(1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////// value display
|
||||||
|
if(arg == 3) {
|
||||||
|
|
||||||
|
var hadShowVal = selNode.showVal;
|
||||||
|
$(svg).find("[id]").each(function(){delete($(this).get(0).showVal)});
|
||||||
|
$(svg).off("mousemove");
|
||||||
|
|
||||||
|
if(par && par.circle) {
|
||||||
|
$(par.circle).remove();
|
||||||
|
$(par.div).remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!hadShowVal) {
|
||||||
|
selNode.showVal = true;
|
||||||
|
$(svg).mousemove(mousemove);
|
||||||
|
svgNode.par = par = svg_prepareHash(selNode);
|
||||||
|
|
||||||
|
par.circle =
|
||||||
|
$(svg).get(0).ownerDocument.createElementNS(svgNS, "circle");
|
||||||
|
$(par.circle).attr("id", "svgmarker").attr("r", "8");
|
||||||
|
$(svg).append(par.circle);
|
||||||
|
|
||||||
|
par.div = $('<div id="svgmarker">');
|
||||||
|
par.divoffY = $(embed ? embed : svg).offset().top -
|
||||||
|
$("#content").offset().top-50;
|
||||||
|
$("#content").append(par.div);
|
||||||
|
|
||||||
|
var pl = selNode.points;
|
||||||
|
if(pl.length > 2)
|
||||||
|
mousemove({pageX:pl[pl.length-2].x});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}, embed);
|
||||||
|
|
||||||
|
function
|
||||||
|
mousemove(e)
|
||||||
|
{
|
||||||
|
var xRaw = e.pageX, pl = selNode.points, l = pl.length, i1;
|
||||||
|
if(!embed)
|
||||||
|
xRaw -= $(svg).offset().left;
|
||||||
|
for(i1=0; i1<l; i1++)
|
||||||
|
if(pl[i1].x > xRaw)
|
||||||
|
break;
|
||||||
|
if(i1==l || i1==0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var pp=pl[i1-1], pn=pl[i1];
|
||||||
|
var xR = (xRaw-pp.x)/(pn.x-pp.x); // Compute interim values
|
||||||
|
var yRaw = pp.y+xR*(pn.y-pp.y);
|
||||||
|
|
||||||
|
var y = (((par.y_h-yRaw)/par.y_mul)+par.y_min).toFixed(par.decimals);
|
||||||
|
|
||||||
|
var d = new Date((((xRaw-par.x_min)/par.x_mul)+par.x_off) * 1000);
|
||||||
|
var ts = (d.getHours() < 10 ? '0' : '') + d.getHours() + ":"+
|
||||||
|
(d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
|
||||||
|
|
||||||
|
$(par.circle).attr("cx", xRaw).attr("cy", yRaw);
|
||||||
|
var yd = Math.floor((yRaw+par.divoffY) / 20)*20;
|
||||||
|
$(par.div).html(ts+" "+y)
|
||||||
|
.css({ left:xRaw-20, top:yd });
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
showOtherLines(currval, maxval)
|
||||||
|
{
|
||||||
|
$(svg).find("[id]").each(function(){
|
||||||
|
var id = $(this).attr("id");
|
||||||
|
if(id.indexOf("line_") != 0 || id == lid)
|
||||||
|
return;
|
||||||
|
var h = parseFloat($(this).attr("y_h"));
|
||||||
|
$(this).attr("transform", "translate(0,"+h*(1-currval)+") "+
|
||||||
|
"scale(1,"+currval+")");
|
||||||
|
});
|
||||||
|
|
||||||
|
if(currval != maxval) {
|
||||||
|
currval += (currval<maxval ? 0.02 : -0.02);
|
||||||
|
currval = Math.round(currval*100)/100;
|
||||||
|
setTimeout(function(){ showOtherLines(currval,maxval) }, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
svg_init_one(embed, svg)
|
||||||
|
{
|
||||||
|
var sid = $(svg).attr("id");
|
||||||
|
if(svg_initialized[sid])
|
||||||
|
return;
|
||||||
|
svg_initialized[sid] = true;
|
||||||
|
$("text.legend", svg).click(function(e){sv_menu(e, embed)});
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
svg_init(par) // also called directly from perl, in race condition
|
||||||
|
{
|
||||||
|
$("embed").each(function(){
|
||||||
|
var e = this;
|
||||||
|
var src = $(e).attr("src");
|
||||||
|
var ed = e.getSVGDocument();
|
||||||
|
if(src.indexOf("SVG_showLog") < 0 || !ed)
|
||||||
|
return;
|
||||||
|
var sTag = $("svg", ed)[0];
|
||||||
|
if((par && $(sTag).attr("id") != par))
|
||||||
|
return;
|
||||||
|
svg_init_one(e, sTag);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function(){
|
||||||
|
svg_init(); // <embed><svg>
|
||||||
|
$("svg[id]").each(function(){ // <svg> (direct)
|
||||||
|
if($(this).attr("id").indexOf("SVGPLOT") == 0)
|
||||||
|
svg_init_one(undefined, this);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// longpollSVG code below
|
||||||
|
function
|
||||||
|
FW_svgUpdateDevs(devs)
|
||||||
|
{
|
||||||
|
// if matches, refresh the SVG by removing and readding the embed tag
|
||||||
|
var embArr = document.getElementsByTagName("embed");
|
||||||
|
for(var i = 0; i < embArr.length; i++) {
|
||||||
|
var svg = embArr[i].getSVGDocument();
|
||||||
|
if(!svg || !svg.firstChild || !svg.firstChild.nextSibling)
|
||||||
|
continue;
|
||||||
|
var flog = svg.firstChild.nextSibling.getAttribute("flog");
|
||||||
|
for(var j=0; j < devs.length; j++) {
|
||||||
|
if(flog !== null && flog.match(" "+devs[j]+" ")) {
|
||||||
|
var e = embArr[i];
|
||||||
|
var newE = document.createElement("embed");
|
||||||
|
for(var k=0; k<e.attributes.length; k++)
|
||||||
|
newE.setAttribute(e.attributes[k].name, e.attributes[k].value);
|
||||||
|
e.parentNode.insertBefore(newE, e);
|
||||||
|
e.parentNode.removeChild(e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FW_widgets.SVG = { updateDevs:FW_svgUpdateDevs };
|
||||||
|
@ -35,3 +35,5 @@ polyline { stroke:black; fill:none; }
|
|||||||
.l1fill_stripe {stroke:green; fill:url(#gr1_stripe);} text.l1fill_stripe {stroke:none; fill:green;}
|
.l1fill_stripe {stroke:green; fill:url(#gr1_stripe);} text.l1fill_stripe {stroke:none; fill:green;}
|
||||||
|
|
||||||
.l0fill_gyr {stroke:red; fill:url(#gr0_gyr);} text.l0fill_gyr {stroke:none; fill:red;}
|
.l0fill_gyr {stroke:red; fill:url(#gr0_gyr);} text.l0fill_gyr {stroke:none; fill:red;}
|
||||||
|
|
||||||
|
circle#svgmarker { fill:#278727; opacity:0.5; }
|
||||||
|