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

LightScene: add html overview of all configured scenes in detail view.

allow usage of overview in a weblink.


git-svn-id: https://svn.fhem.de/fhem/trunk@3404 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
justme-1968 2013-07-11 15:05:17 +00:00
parent cfe8635b7b
commit 0c7508fc3c
2 changed files with 210 additions and 35 deletions

View File

@ -1,5 +1,7 @@
# Add changes at the top of the list. Keep it in ASCII
- SVN
- feature: LightScene: add html overview of all configured scenes in
detail view. allow usage of overview in a weblink.
- feature: FLOORPLAN: enhanced detail-screen for floorplans in fhemweb,
arrange-mode has delete-button, new command
"get <floorplan-name> config"

View File

@ -6,6 +6,8 @@ use warnings;
use POSIX;
use JSON;
use vars qw(%FW_webArgs); # all arguments specified in the GET
sub LightScene_Initialize($)
{
my ($hash) = @_;
@ -15,6 +17,8 @@ sub LightScene_Initialize($)
$hash->{UndefFn} = "LightScene_Undefine";
$hash->{SetFn} = "LightScene_Set";
$hash->{GetFn} = "LightScene_Get";
$hash->{FW_detailFn} = "LightScene_detailFn";
}
sub LightScene_Define($$)
@ -26,7 +30,7 @@ sub LightScene_Define($$)
return "Usage: define <name> LightScene <device>+" if(@args < 3);
my $name = shift(@args);
my $tyoe = shift(@args);
my $type = shift(@args);
my %list;
foreach my $a (@args) {
@ -55,6 +59,102 @@ sub LightScene_Undefine($$)
return undef;
}
sub
LightScene_2html($)
{
my($hash) = @_;
$hash = $defs{$hash} if( ref($hash) ne 'HASH' );
return undef if( !$hash );
my $name = $hash->{NAME};
my $room = $FW_webArgs{room};
my $show_heading = 1;
my $row = 1;
my $ret = "";
$ret .= "<table>";
$ret .= "<tr><td><div class=\"devType\"><a href=\"$FW_ME$FW_subdir?detail=$name\">".AttrVal($name, "alias", $name)."</a></div></td></tr>" if( $show_heading );
$ret .= "<tr><td><table class=\"block wide\">";
$ret .= sprintf("<tr class=\"%s\">", ($row&1)?"odd":"even");
$row++;
$ret .= "<td><div></div></td>";
foreach my $d (sort keys %{ $hash->{CONTENT} }) {
$ret .= "<td><div class=\"col2\"><a href=\"$FW_ME$FW_subdir?detail=$d\">". AttrVal($d, "alias", $d) ."</a></div></td>";
}
if( defined($FW_webArgs{detail}) ) {
$room = "&detail=$FW_webArgs{detail}";
$ret .= sprintf("<tr class=\"%s\">", ($row&1)?"odd":"even");
$row++;
$ret .= "<td><div></div></td>";
foreach my $d (sort keys %{ $hash->{CONTENT} }) {
my %extPage = ();
my ($allSets, $cmdlist, $txt) = FW_devState($d, $room, \%extPage);
$ret .= "<td id=\"$d\">$txt</td>";
}
}
foreach my $scene (sort keys %{ $hash->{SCENES} }) {
$ret .= sprintf("<tr class=\"%s\">", ($row&1)?"odd":"even");
$row++;
my $srf = $room ? "&room=$room" : "";
$srf = $room if( $room && $room =~ m/^&/ );
my $link = "cmd=set $name scene $scene";
my $txt = $scene;
if( AttrVal($FW_wname, "longpoll", 1)) {
$txt = "<a onClick=\"FW_cmd('$FW_ME$FW_subdir?XHR=1&$link')\">$txt</a>";
} else {
$txt = "<a href=\"$FW_ME$FW_subdir?$link$srf\">$txt</a>";
}
$ret .= "<td><div>$txt</div></td>";
foreach my $d (sort keys %{ $hash->{CONTENT} }) {
if( !defined($hash->{SCENES}{$scene}{$d} ) ) {
$ret .= "<td><div></div></td>";
next;
}
my $icon;
my $state = $hash->{SCENES}{$scene}{$d};
$icon = $state->{icon} if( ref($state) eq 'HASH' );
$state = $state->{state} if( ref($state) eq 'HASH' );
my ($isHtml);
$isHtml = 0;
if( !$icon ) {
my ($link);
($icon, $link, $isHtml) = FW_dev2image($d, $state);
}
$icon = FW_iconName($state) if( !$icon );
if( $icon ) {
$ret .= "<td><div class=\"col2\">". ($isHtml ? $icon : FW_makeImage($icon, $state)) ."</div></td>";
} else {
$ret .= "<td><div>". $state ."</div></td>";
}
}
}
$ret .= "</table></td></tr>";
$ret .= "</table>";
$ret .= "</br>";
return $ret;
}
sub
LightScene_detailFn()
{
my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn.
return LightScene_2html($d);
}
sub
LightScene_Notify($$)
{
@ -69,6 +169,43 @@ LightScene_Notify($$)
LightScene_Save();
}
my $max = int(@{$dev->{CHANGED}});
for (my $i = 0; $i < $max; $i++) {
my $s = $dev->{CHANGED}[$i];
$s = "" if(!defined($s));
if($s =~ m/^RENAMED ([^ ]*) ([^ ]*)$/) {
my ($old, $new) = ($1, $2);
if( defined($hash->{CONTENT}{$old}) ) {
$hash->{DEF} =~ s/(\s*)$old(\s*)/$1$new$2/;
foreach my $scene (keys %{ $hash->{SCENES} }) {
$hash->{SCENES}{$scene}{$new} = $hash->{SCENES}{$scene}{$old} if( defined($hash->{SCENES}{$scene}{$old}) );
delete( $hash->{SCENES}{$scene}{$old} );
}
delete( $hash->{CONTENT}{$old} );
$hash->{CONTENT}{$new} = 1;
}
} elsif($s =~ m/^DELETED ([^ ]*)$/) {
my ($name) = ($1);
if( defined($hash->{CONTENT}{$name}) ) {
$hash->{DEF} =~ s/(\s*)$name(\s*)/ /;
$hash->{DEF} =~ s/^ //;
$hash->{DEF} =~ s/ $//;
foreach my $scene (keys %{ $hash->{SCENES} }) {
delete( $hash->{SCENES}{$scene}{$name} );
}
delete( $hash->{CONTENT}{$name} );
}
}
}
return undef;
}
@ -85,7 +222,7 @@ LightScene_Save()
{
my $time_now = TimeNow();
return if( $time_now eq $LightScene_LastSaveTime);
$LightScene_LastSaveTime = $time_now ;
$LightScene_LastSaveTime = $time_now;
return "No statefile specified" if(!$attr{global}{statefile});
my $statefile = myStatefileName();
@ -154,7 +291,7 @@ LightScene_Set($@)
if( !defined($cmd) ){ return "$name: set needs at least one parameter" };
if( $cmd eq "?" ){ return "Unknown argument ?, choose one of remove save set scene:".join(",", sort keys %{$hash->{SCENES}}) };
if( $cmd eq "?" ){ return "Unknown argument ?, choose one of remove:".join(",", sort keys %{$hash->{SCENES}}) ." save set scene:".join(",", sort keys %{$hash->{SCENES}})};
if( $cmd eq "save" && !defined( $scene ) ) { return "Usage: set $name save <scene_name>" };
if( $cmd eq "scene" && !defined( $scene ) ) { return "Usage: set $name scene <scene_name>" };
@ -167,13 +304,11 @@ LightScene_Set($@)
my ($d, @args) = @a;
if( !defined( $scene ) || !defined( $d ) || !@args ) { return "Usage: set $name set <scene_name> <device> <cmd>" };
return "no stored scene >$scene<" if( !defined($hash->{SCENES}{$scene} ) );
return "device >$d< is not a member of scene >$scene<" if( !defined($hash->{CONTENT}{$d} ) );
if( defined($hash->{SCENES}{$scene})
&& defined($hash->{SCENES}{$scene}{$d}) )
{
$hash->{SCENES}{$scene}{$d} = join(" ", @args);
return undef;
}
$hash->{SCENES}{$scene}{$d} = join(" ", @args);
return undef;
}
@ -187,54 +322,74 @@ LightScene_Set($@)
}
if( $cmd eq "save" ) {
my $status = "";
if( $defs{$d}{TYPE} eq 'CUL_HM' ) {
my $state = "";
my $type = $defs{$d}->{TYPE};
$type = "" if( !defined($type) );
if( $type eq 'CUL_HM' ) {
my $subtype = AttrVal($d,"subType","");
if( $subtype eq "switch" ) {
$status = Value($d);
$state = Value($d);
} elsif( $subtype eq "dimmer" ) {
$status = Value($d);
$state = Value($d);
} else {
$status = Value($d);
$state = Value($d);
}
} elsif( $defs{$d}{TYPE} eq 'FS20' ) {
$status = Value($d);
} elsif( $defs{$d}{TYPE} eq 'HUEDevice' ) {
} elsif( $type eq 'FS20' ) {
$state = Value($d);
} elsif( $type eq 'SWAP_0000002200000003' ) {
$state = Value($d);
$state = "rgb ". $state if( $state ne "off" );
} elsif( $type eq 'HUEDevice' ) {
my $subtype = AttrVal($d,"subType","");
if( $subtype eq "switch" || Value($d) eq "off" ) {
$status = Value($d);
$state = Value($d);
} elsif( $subtype eq "dimmer" ) {
$status = "bri ". ReadingsVal($d,'bri',"0");
$state = "bri ". ReadingsVal($d,'bri',"0");
} elsif( $subtype eq "colordimmer" ) {
if( ReadingsVal($d,"colormode","") eq "ct" ) {
ReadingsVal($d,"ct","") =~ m/(\d+) .*/;
$status = "bri ". ReadingsVal($d,'bri',"0") ." : ct ". $1;
$state = "bri ". ReadingsVal($d,'bri',"0") ." : ct ". $1;
} else {
$status = "bri ". ReadingsVal($d,'bri',"0") ." : xy ". ReadingsVal($d,'xy',"");
$state = "bri ". ReadingsVal($d,'bri',"0") ." : xy ". ReadingsVal($d,'xy',"");
}
}
} elsif( $defs{$d}{TYPE} eq 'IT' ) {
} elsif( $type eq 'IT' ) {
my $subtype = AttrVal($d,"model","");
if( $subtype eq "itswitch" ) {
$status = Value($d);
$state = Value($d);
} elsif( $subtype eq "itdimmer" ) {
$status = Value($d);
$state = Value($d);
} else {
$status = Value($d);
$state = Value($d);
}
} elsif( $defs{$d}{TYPE} eq 'TRX_LIGHT' ) {
$status = Value($d);
} elsif( $type eq 'TRX_LIGHT' ) {
$state = Value($d);
} else {
$status = Value($d);
$state = Value($d);
}
$hash->{SCENES}{$scene}{$d} = $status;
$ret .= $d .": ". $status ."\n";
if( $type eq "SWAP_0000002200000003" || $type eq "HUEDevice" ) {
my %desc;
$desc{state} = $state;
my ($icon, $link, $isHtml) = FW_dev2image($d);
$desc{icon} = $icon;
$hash->{SCENES}{$scene}{$d} = \%desc;
} else {
$hash->{SCENES}{$scene}{$d} = $state;
}
$ret .= $d .": ". $state ."\n" if( defined($FW_webArgs{room}) && $FW_webArgs{room} eq "all" ); #only if telnet
} elsif ( $cmd eq "scene" ) {
$hash->{STATE} = $scene;
next if( !defined($hash->{SCENES}{$scene}{$d}));
my $state = $hash->{SCENES}{$scene}{$d};
$state = $state->{state} if( ref($state) eq 'HASH' );
$ret .= " " if( $ret );
$ret .= CommandSet(undef,"$d $hash->{SCENES}{$scene}{$d}");
$ret .= CommandSet(undef,"$d $state");
} else {
$ret = "Unknown argument $cmd, choose one of save scene";
}
@ -260,7 +415,9 @@ LightScene_Get($@)
if( $cmd eq "scene" && @a < 3 ) { return "Usage: get scene <scene_name>" };
my $ret = "";
if( $cmd eq "scenes" ) {
if( $cmd eq "html" ) {
return LightScene_2html($hash);
} elsif( $cmd eq "scenes" ) {
foreach my $scene (sort keys %{ $hash->{SCENES} }) {
$ret .= $scene ."\n";
}
@ -270,7 +427,12 @@ LightScene_Get($@)
my $scene = $a[2];
if( defined($hash->{SCENES}{$scene}) ) {
foreach my $d (sort keys %{ $hash->{SCENES}{$scene} }) {
$ret .= $d .": ". $hash->{SCENES}{$scene}{$d} ."\n";
next if( !defined($hash->{SCENES}{$scene}{$d}));
my $state = $hash->{SCENES}{$scene}{$d};
$state = $state->{state} if( ref($state) eq 'HASH' );
$ret .= $d .": ". $state ."\n";
}
} else {
$ret = "no scene <$scene> defined";
@ -278,7 +440,7 @@ LightScene_Get($@)
return $ret;
}
return "Unknown argument $cmd, choose one of scenes scene";
return "Unknown argument $cmd, choose one of html scenes scene";
}
1;
@ -303,9 +465,20 @@ LightScene_Get($@)
<ul>
<code>define light_group LightScene Lampe1 Lampe2 Dimmer1</code><br>
<code>define kino_group LightScene LampeDecke LampeFernseher Fernseher Verstaerker</code><br>
<code>define Wohnzimmer LightScene Leinwand Beamer TV Leselampe Deckenlampe</code><br>
</ul>
</ul><br>
The device detail view will show an html overview of the current state of all included devices and all
configured scenes with the device states for each. The column heading with the device names is clickable
to go to detail view of this device. The first row that displays the current device state is clickable
and should react like a click on the device icon in a room overview would. this can be used to interactively
configure a new scene and save it with the command menu of the detail view. The first column of the table with
the scene names ic clickable to activate the scene.<br><br>
A weblink with a scene overview that can be included in any room or a floorplan can be created with:
<ul><code>define wlScene weblink htmlCode {LightScene_2html("Scene")}</code></ul>
<a name="LightScene_Set"></a>
<b>Set</b>
<ul>
@ -326,7 +499,7 @@ LightScene_Get($@)
<li>scene &lt;scene_name&gt;</li>
</ul><br>
</ul><br>
</ul>
=end html
=cut