2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-26 04:24:53 +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

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

@ -33,7 +33,7 @@ sub HUEBridge_Initialize($)
$hash->{GetFn} = "HUEBridge_Get";
$hash->{AttrFn} = "HUEBridge_Attr";
$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
@ -1004,6 +1004,112 @@ HUEBridge_GetUpdate($)
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
HUEBridge_Parse($$)
{
@ -1147,7 +1253,8 @@ HUEBridge_Autocreate($;$)
return "created $autocreated devices";
}
sub HUEBridge_ProcessResponse($$)
sub
HUEBridge_ProcessResponse($$)
{
my ($hash,$obj) = @_;
my $name = $hash->{NAME};
@ -1155,14 +1262,12 @@ sub HUEBridge_ProcessResponse($$)
#Log3 $name, 3, ref($obj);
#Log3 $name, 3, "Receiving: " . Dumper $obj;
if( ref($obj) eq 'ARRAY' )
{
if( defined($obj->[0]->{error}))
{
my $error = $obj->[0]->{error}->{'description'};
if( ref($obj) eq 'ARRAY' ) {
if( defined($obj->[0]->{error})) {
my $error = $obj->[0]->{error}->{'description'};
readingsSingleUpdate($hash, 'lastError', $error, 1 );
}
readingsSingleUpdate($hash, 'lastError', $error, 1 );
}
if( !AttrVal( $name,'queryAfterSet', 1 ) ) {
my $successes;
@ -1187,7 +1292,6 @@ sub HUEBridge_ProcessResponse($$)
$successes++;
}
}
}
}
@ -1198,23 +1302,26 @@ sub HUEBridge_ProcessResponse($$)
}
}
my $changed = "";
foreach my $id ( keys %json ) {
my $code = $name ."-". $id;
if( my $chash = $modules{HUEDevice}{defptr}{$code} ) {
#$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]);
}
elsif( ref($obj) eq 'HASH' )
{
return $obj;
}
return ($obj->[0]);
} elsif( ref($obj) eq 'HASH' ) {
return $obj;
}
return undef;
}
@ -1439,21 +1546,20 @@ HUEBridge_dispatch($$$;$)
my $type = $param->{type};
if( ref($json) eq 'ARRAY' )
{
HUEBridge_ProcessResponse($hash,$json) if( !$queryAfterSet );
if( ref($json) eq 'ARRAY' ) {
HUEBridge_ProcessResponse($hash,$json) if( !$queryAfterSet );
if( defined($json->[0]->{error}))
{
my $error = $json->[0]->{error}->{'description'};
if( defined($json->[0]->{error}))
{
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( !defined($type) ) {
@ -1492,17 +1598,22 @@ HUEBridge_dispatch($$$;$)
}
if( $type eq 'lights' ) {
my $changed = "";
my $lights = $json;
foreach my $id ( keys %{$lights} ) {
my $code = $name ."-". $id;
my $chash = $modules{HUEDevice}{defptr}{$code};
if( defined($chash) ) {
HUEDevice_Parse($chash,$lights->{$id});
if( HUEDevice_Parse($chash,$lights->{$id}) ) {
$changed .= "," if( $changed );
$changed .= $chash->{ID};
}
} else {
Log3 $name, 2, "$name: message for unknow device received: $code";
}
}
HUEBridge_updateGroups($hash, $changed) if( $changed );
} elsif( $type =~ m/^config$/ ) {
HUEBridge_Parse($hash,$json);
@ -1514,7 +1625,9 @@ HUEBridge_dispatch($$$;$)
}
} 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*)$/ ) {
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>
2 -> the bridge will poll all devices in one go instead of each device polling itself independently<br>
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>
the bridge will request the real device state after a set command. default is 1.</li>
<li>noshutdown<br>

@ -165,7 +165,6 @@ sub HUEDevice_Initialize($)
$hash->{GetFn} = "HUEDevice_Get";
$hash->{AttrFn} = "HUEDevice_Attr";
$hash->{AttrList} = "IODev ".
"createActionReadings:1,0 ".
"delayedUpdate:1 ".
"ignoreReachable:1,0 ".
"realtimePicker:1,0 ".
@ -194,6 +193,24 @@ HUEDevice_devStateIcon($)
my $name = $hash->{NAME};
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 ".*:on:toggle" if( ReadingsVal($name,'any_on',0) );
@ -337,6 +354,9 @@ sub HUEDevice_Define($$)
my $icon_path = AttrVal("WEB", "iconPath", "default:fhemSVG: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' ) {
$hash->{DEF} = "sensor $id $args[3] IODev=$iodev" if( $iodev );
@ -983,8 +1003,10 @@ sub
HUEDevice_ReadFromServer($@)
{
my ($hash,@a) = @_;
my $name = $hash->{NAME};
#return if(IsDummy($name) || IsIgnored($name));
no strict "refs";
my $ret;
unshift(@a,$name);
@ -992,22 +1014,6 @@ HUEDevice_ReadFromServer($@)
$ret = IOWrite($hash,$hash,@a);
use strict "refs";
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
@ -1051,6 +1057,7 @@ HUEDevice_GetUpdate($)
}
HUEDevice_Parse($hash,$result);
HUEBridge_updateGroups($hash->{IODev}, $hash->{ID});
}
sub
@ -1104,7 +1111,7 @@ HUEDevice_Parse($$)
if( $hash->{helper}->{devtype} eq 'G' ) {
if( $result->{lights} ) {
$hash->{lights} = join( ",", @{$result->{lights}} );
$hash->{lights} = join( ",", sort { $a <=> $b } @{$result->{lights}} );
} else {
$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>
<li>createActionReadings<br>
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>
ignore the reachable state that is reported by the hue bridge. assume the device is allways reachable.</li>
<li>setList<br>