2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-26 10:34:52 +00:00

30_HUEBridge.pm, 31_HUEDevice.pm: addedcreateGroupReadings attribute

git-svn-id: https://svn.fhem.de/fhem/trunk@16081 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
justme-1968 2018-02-04 14:05:45 +00:00
parent f3173f8974
commit 0889f33abe
3 changed files with 178 additions and 50 deletions

View File

@ -1,5 +1,6 @@
# 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: 30_HUEBridge, 31_HUEDevice: added createGroupReadings attribute
- feature: f18: implement dragging / dashboard - feature: f18: implement dragging / dashboard
- change: 93_DbLog: V3.8.3, configCheck improved, execute cache only every - change: 93_DbLog: V3.8.3, configCheck improved, execute cache only every
syncInterval/2 if cacheLimit reached, error-handling syncInterval/2 if cacheLimit reached, error-handling

View File

@ -33,7 +33,7 @@ sub HUEBridge_Initialize($)
$hash->{GetFn} = "HUEBridge_Get"; $hash->{GetFn} = "HUEBridge_Get";
$hash->{AttrFn} = "HUEBridge_Attr"; $hash->{AttrFn} = "HUEBridge_Attr";
$hash->{UndefFn} = "HUEBridge_Undefine"; $hash->{UndefFn} = "HUEBridge_Undefine";
$hash->{AttrList} = "key disable:1 disabledForIntervals httpUtils:1,0 noshutdown:1,0 pollDevices:1,2,0 queryAfterSet:1,0 $readingFnAttributes"; $hash->{AttrList} = "key disable:1 disabledForIntervals createGroupReadings:1,0 httpUtils:1,0 noshutdown:1,0 pollDevices:1,2,0 queryAfterSet:1,0 $readingFnAttributes";
} }
sub sub
@ -1004,6 +1004,112 @@ HUEBridge_GetUpdate($)
return undef; return undef;
} }
my %dim_values = (
0 => "dim06%",
1 => "dim12%",
2 => "dim18%",
3 => "dim25%",
4 => "dim31%",
5 => "dim37%",
6 => "dim43%",
7 => "dim50%",
8 => "dim56%",
9 => "dim62%",
10 => "dim68%",
11 => "dim75%",
12 => "dim81%",
13 => "dim87%",
14 => "dim93%",
);
sub
HUEBridge_updateGroups($$)
{
my($hash,$lights) = @_;
my $name = $hash->{NAME};
my $createGroupReadings = AttrVal($hash->{NAME},"createGroupReadings",undef);
return if( !defined($createGroupReadings) );
$createGroupReadings = ($createGroupReadings eq "1");
my $groups = {};
foreach my $light ( split(',', $lights) ) {
foreach my $chash ( values %{$modules{HUEDevice}{defptr}} ) {
next if( !$chash->{IODev} );
next if( !$chash->{lights} );
next if( $chash->{IODev}{NAME} ne $name );
next if( $chash->{helper}{devtype} ne 'G' );
next if( ",$chash->{lights}," !~ m/,$light,/ );
next if( $createGroupReadings && !AttrVal($chash->{NAME},"createGroupReadings", 1) );
next if( !$createGroupReadings && !AttrVal($chash->{NAME},"createGroupReadings", undef) );
$groups->{$chash->{ID}} = $chash;
}
}
foreach my $chash ( values %{$groups} ) {
my $count = 0;
my %readings;
foreach my $light ( split(',', $chash->{lights}) ) {
next if( !$light );
my $current = $modules{HUEDevice}{defptr}{"$name-$light"}{helper};
$readings{ct} += $current->{ct};
$readings{bri} += $current->{bri};
$readings{pct} += $current->{pct};
$readings{sat} += $current->{sat};
$readings{on} |= $current->{on};
$readings{reachable} |= $current->{reachable};
if( !defined($readings{alert}) ) {
$readings{alert} = $current->{alert};
} elsif( $readings{alert} ne $current->{alert} ) {
$readings{alert} = "nonuniform";
}
if( !defined($readings{colormode}) ) {
$readings{colormode} = $current->{colormode};
} elsif( $readings{colormode} ne $current->{colormode} ) {
$readings{colormode} = "nonuniform";
}
if( !defined($readings{effect}) ) {
$readings{effect} = $current->{effect};
} elsif( $readings{effect} ne $current->{effect} ) {
$readings{effect} = "nonuniform";
}
++$count;
}
$readings{ct} = int($readings{ct} / $count + 0.5);
$readings{bri} = int($readings{bri} / $count + 0.5);
$readings{pct} = int($readings{pct} / $count + 0.5);
$readings{sat} = int($readings{sat} / $count + 0.5);
if( $readings{on} ) {
if( $readings{pct} > 0
&& $readings{pct} < 100 ) {
$readings{state} = $dim_values{int($readings{pct}/7)};
}
$readings{state} = 'off' if( $readings{pct} == 0 );
$readings{state} = 'on' if( $readings{pct} == 100 );
} else {
$readings{pct} = 0;
$readings{state} = 'off';
}
readingsBeginUpdate($chash);
foreach my $key ( keys %readings ) {
if( defined($readings{$key}) ) {
my $reading = $key;
$reading = 'onoff' if( $reading eq 'on' );
readingsBulkUpdate($chash, $reading, $readings{$key}, 1) if( !defined($chash->{helper}{$key}) || $chash->{helper}{$key} ne $readings{$key} );
$chash->{helper}{$key} = $readings{$key};
}
}
readingsEndUpdate($chash,1);
}
}
sub sub
HUEBridge_Parse($$) HUEBridge_Parse($$)
{ {
@ -1147,7 +1253,8 @@ HUEBridge_Autocreate($;$)
return "created $autocreated devices"; return "created $autocreated devices";
} }
sub HUEBridge_ProcessResponse($$) sub
HUEBridge_ProcessResponse($$)
{ {
my ($hash,$obj) = @_; my ($hash,$obj) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -1155,14 +1262,12 @@ sub HUEBridge_ProcessResponse($$)
#Log3 $name, 3, ref($obj); #Log3 $name, 3, ref($obj);
#Log3 $name, 3, "Receiving: " . Dumper $obj; #Log3 $name, 3, "Receiving: " . Dumper $obj;
if( ref($obj) eq 'ARRAY' ) if( ref($obj) eq 'ARRAY' ) {
{ if( defined($obj->[0]->{error})) {
if( defined($obj->[0]->{error})) my $error = $obj->[0]->{error}->{'description'};
{
my $error = $obj->[0]->{error}->{'description'};
readingsSingleUpdate($hash, 'lastError', $error, 1 ); readingsSingleUpdate($hash, 'lastError', $error, 1 );
} }
if( !AttrVal( $name,'queryAfterSet', 1 ) ) { if( !AttrVal( $name,'queryAfterSet', 1 ) ) {
my $successes; my $successes;
@ -1187,7 +1292,6 @@ sub HUEBridge_ProcessResponse($$)
$successes++; $successes++;
} }
} }
} }
} }
@ -1198,23 +1302,26 @@ sub HUEBridge_ProcessResponse($$)
} }
} }
my $changed = "";
foreach my $id ( keys %json ) { foreach my $id ( keys %json ) {
my $code = $name ."-". $id; my $code = $name ."-". $id;
if( my $chash = $modules{HUEDevice}{defptr}{$code} ) { if( my $chash = $modules{HUEDevice}{defptr}{$code} ) {
#$json{$id}->{state}->{reachable} = 1; #$json{$id}->{state}->{reachable} = 1;
HUEDevice_Parse( $chash, $json{$id} ); if( HUEDevice_Parse( $chash, $json{$id} ) ) {
$changed .= "," if( $changed );
$changed .= $chash->{ID};
}
} }
} }
HUEBridge_updateGroups($hash, $changed) if( $changed );
} }
#return undef if( !$errors && $successes ); #return undef if( !$errors && $successes );
return ($obj->[0]); return ($obj->[0]);
} } elsif( ref($obj) eq 'HASH' ) {
elsif( ref($obj) eq 'HASH' ) return $obj;
{ }
return $obj;
}
return undef; return undef;
} }
@ -1439,21 +1546,20 @@ HUEBridge_dispatch($$$;$)
my $type = $param->{type}; my $type = $param->{type};
if( ref($json) eq 'ARRAY' ) if( ref($json) eq 'ARRAY' ) {
{ HUEBridge_ProcessResponse($hash,$json) if( !$queryAfterSet );
HUEBridge_ProcessResponse($hash,$json) if( !$queryAfterSet );
if( defined($json->[0]->{error})) if( defined($json->[0]->{error}))
{ {
my $error = $json->[0]->{error}->{'description'}; my $error = $json->[0]->{error}->{'description'};
readingsSingleUpdate($hash, 'lastError', $error, 1 ); readingsSingleUpdate($hash, 'lastError', $error, 1 );
Log3 $name, 3, $error; Log3 $name, 3, $error;
} }
#return ($json->[0]); #return ($json->[0]);
} }
if( $hash == $param->{chash} ) { if( $hash == $param->{chash} ) {
if( !defined($type) ) { if( !defined($type) ) {
@ -1492,17 +1598,22 @@ HUEBridge_dispatch($$$;$)
} }
if( $type eq 'lights' ) { if( $type eq 'lights' ) {
my $changed = "";
my $lights = $json; my $lights = $json;
foreach my $id ( keys %{$lights} ) { foreach my $id ( keys %{$lights} ) {
my $code = $name ."-". $id; my $code = $name ."-". $id;
my $chash = $modules{HUEDevice}{defptr}{$code}; my $chash = $modules{HUEDevice}{defptr}{$code};
if( defined($chash) ) { if( defined($chash) ) {
HUEDevice_Parse($chash,$lights->{$id}); if( HUEDevice_Parse($chash,$lights->{$id}) ) {
$changed .= "," if( $changed );
$changed .= $chash->{ID};
}
} else { } else {
Log3 $name, 2, "$name: message for unknow device received: $code"; Log3 $name, 2, "$name: message for unknow device received: $code";
} }
} }
HUEBridge_updateGroups($hash, $changed) if( $changed );
} elsif( $type =~ m/^config$/ ) { } elsif( $type =~ m/^config$/ ) {
HUEBridge_Parse($hash,$json); HUEBridge_Parse($hash,$json);
@ -1514,7 +1625,9 @@ HUEBridge_dispatch($$$;$)
} }
} elsif( $type =~ m/^lights\/(\d*)$/ ) { } elsif( $type =~ m/^lights\/(\d*)$/ ) {
HUEDevice_Parse($param->{chash},$json); if( HUEDevice_Parse($param->{chash},$json) ) {
HUEBridge_updateGroups($hash, $param->{chash}{ID});
}
} elsif( $type =~ m/^groups\/(\d*)$/ ) { } elsif( $type =~ m/^groups\/(\d*)$/ ) {
HUEDevice_Parse($param->{chash},$json); HUEDevice_Parse($param->{chash},$json);
@ -1828,6 +1941,11 @@ HUEBridge_Attr($$$)
1 -> the bridge will poll all lights in one go instead of each device polling itself independently<br> 1 -> the bridge will poll all lights in one go instead of each device polling itself independently<br>
2 -> the bridge will poll all devices in one go instead of each device polling itself independently<br> 2 -> the bridge will poll all devices in one go instead of each device polling itself independently<br>
default is 1.</li> default is 1.</li>
<li>createGroupReadings<br>
create 'artificial' readings for group devices.</li>
0 -> create readings only for group devices where createGroupReadings ist set to 1
1 -> create readings for all group devices where createGroupReadings ist not set or set to 1
undef -> do nothing
<li>queryAfterSet<br> <li>queryAfterSet<br>
the bridge will request the real device state after a set command. default is 1.</li> the bridge will request the real device state after a set command. default is 1.</li>
<li>noshutdown<br> <li>noshutdown<br>

View File

@ -165,7 +165,6 @@ sub HUEDevice_Initialize($)
$hash->{GetFn} = "HUEDevice_Get"; $hash->{GetFn} = "HUEDevice_Get";
$hash->{AttrFn} = "HUEDevice_Attr"; $hash->{AttrFn} = "HUEDevice_Attr";
$hash->{AttrList} = "IODev ". $hash->{AttrList} = "IODev ".
"createActionReadings:1,0 ".
"delayedUpdate:1 ". "delayedUpdate:1 ".
"ignoreReachable:1,0 ". "ignoreReachable:1,0 ".
"realtimePicker:1,0 ". "realtimePicker:1,0 ".
@ -194,6 +193,24 @@ HUEDevice_devStateIcon($)
my $name = $hash->{NAME}; my $name = $hash->{NAME};
if( $hash->{helper}->{devtype} && $hash->{helper}->{devtype} eq 'G' ) { if( $hash->{helper}->{devtype} && $hash->{helper}->{devtype} eq 'G' ) {
if( $hash->{IODev} ) {
my $createGroupReadings = AttrVal($hash->{IODev}{NAME},"createGroupReadings",undef);
if( defined($createGroupReadings) ) {
return undef if( $createGroupReadings && !AttrVal($hash->{NAME},"createGroupReadings", 1) );
return undef if( !$createGroupReadings && !AttrVal($hash->{NAME},"createGroupReadings", undef) );
return ".*:light_question:toggle" if( !$hash->{helper}{reachable} );
return ".*:off:toggle" if( ReadingsVal($name,"onoff","0") eq "0" );
my $pct = ReadingsVal($name,"pct","100");
my $s = $dim_values{int($pct/7)};
$s="on" if( $pct eq "100" );
return ".*:$s:toggle";
}
}
#return ".*:off:toggle" if( !ReadingsVal($name,'any_on',0) ); #return ".*:off:toggle" if( !ReadingsVal($name,'any_on',0) );
#return ".*:on:toggle" if( ReadingsVal($name,'any_on',0) ); #return ".*:on:toggle" if( ReadingsVal($name,'any_on',0) );
@ -337,6 +354,9 @@ sub HUEDevice_Define($$)
my $icon_path = AttrVal("WEB", "iconPath", "default:fhemSVG:openautomation" ); my $icon_path = AttrVal("WEB", "iconPath", "default:fhemSVG:openautomation" );
$attr{$name}{'color-icons'} = 2 if( !defined( $attr{$name}{'color-icons'} ) && $icon_path =~ m/openautomation/ ); $attr{$name}{'color-icons'} = 2 if( !defined( $attr{$name}{'color-icons'} ) && $icon_path =~ m/openautomation/ );
addToDevAttrList($name, "createActionReadings:1,0");
addToDevAttrList($name, "createGroupReadings,0");
} elsif( $hash->{helper}->{devtype} eq 'S' ) { } elsif( $hash->{helper}->{devtype} eq 'S' ) {
$hash->{DEF} = "sensor $id $args[3] IODev=$iodev" if( $iodev ); $hash->{DEF} = "sensor $id $args[3] IODev=$iodev" if( $iodev );
@ -983,8 +1003,10 @@ sub
HUEDevice_ReadFromServer($@) HUEDevice_ReadFromServer($@)
{ {
my ($hash,@a) = @_; my ($hash,@a) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
#return if(IsDummy($name) || IsIgnored($name));
no strict "refs"; no strict "refs";
my $ret; my $ret;
unshift(@a,$name); unshift(@a,$name);
@ -992,22 +1014,6 @@ HUEDevice_ReadFromServer($@)
$ret = IOWrite($hash,$hash,@a); $ret = IOWrite($hash,$hash,@a);
use strict "refs"; use strict "refs";
return $ret; return $ret;
return if(IsDummy($name) || IsIgnored($name));
my $iohash = $hash->{IODev};
if(!$iohash ||
!$iohash->{TYPE} ||
!$modules{$iohash->{TYPE}} ||
!$modules{$iohash->{TYPE}}{WriteFn}) {
Log3 $name, 5, "No I/O device or WriteFn found for $name";
return;
}
no strict "refs";
#my $ret;
unshift(@a,$name);
$ret = &{$modules{$iohash->{TYPE}}{WriteFn}}($iohash, @a);
use strict "refs";
return $ret;
} }
sub sub
@ -1051,6 +1057,7 @@ HUEDevice_GetUpdate($)
} }
HUEDevice_Parse($hash,$result); HUEDevice_Parse($hash,$result);
HUEBridge_updateGroups($hash->{IODev}, $hash->{ID});
} }
sub sub
@ -1104,7 +1111,7 @@ HUEDevice_Parse($$)
if( $hash->{helper}->{devtype} eq 'G' ) { if( $hash->{helper}->{devtype} eq 'G' ) {
if( $result->{lights} ) { if( $result->{lights} ) {
$hash->{lights} = join( ",", @{$result->{lights}} ); $hash->{lights} = join( ",", sort { $a <=> $b } @{$result->{lights}} );
} else { } else {
$hash->{lights} = ''; $hash->{lights} = '';
} }
@ -1626,6 +1633,8 @@ HUEDevice_Attr($$$;$)
2 -> use lamp color scaled to full brightness as icon color and dim state as icon shape</li> 2 -> use lamp color scaled to full brightness as icon color and dim state as icon shape</li>
<li>createActionReadings<br> <li>createActionReadings<br>
create readings for the last action in group devices</li> create readings for the last action in group devices</li>
<li>createGroupReadings<br>
create 'artificial' readings for group devices. default depends on the createGroupReadings setting in the bridge device.</li>
<li>ignoreReachable<br> <li>ignoreReachable<br>
ignore the reachable state that is reported by the hue bridge. assume the device is allways reachable.</li> ignore the reachable state that is reported by the hue bridge. assume the device is allways reachable.</li>
<li>setList<br> <li>setList<br>