mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00
added support for groups
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@4331 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
f0ea032a86
commit
151e7f5d9e
1
CHANGED
1
CHANGED
@ -1,6 +1,7 @@
|
|||||||
# 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.
|
||||||
- SVN
|
- SVN
|
||||||
|
- feature: HUEBridge,HUEDevice: support for groups added
|
||||||
- feature: YAMAHA_AVR: new argument "toggle" for mute command
|
- feature: YAMAHA_AVR: new argument "toggle" for mute command
|
||||||
- feature: FB_CALLMONITOR: replace & to & at reverse search
|
- feature: FB_CALLMONITOR: replace & to & at reverse search
|
||||||
- feature: new module 33_readingsProxy to make (a subset of) a reading
|
- feature: new module 33_readingsProxy to make (a subset of) a reading
|
||||||
|
@ -37,6 +37,9 @@ HUEBridge_Read($@)
|
|||||||
{
|
{
|
||||||
my ($hash,$name,$id,$obj)= @_;
|
my ($hash,$name,$id,$obj)= @_;
|
||||||
|
|
||||||
|
if( $id =~ m/^G(\d.*)/ ) {
|
||||||
|
return HUEBridge_Call($hash, 'groups/' . $1, $obj);
|
||||||
|
}
|
||||||
return HUEBridge_Call($hash, 'lights/' . $id, $obj);
|
return HUEBridge_Call($hash, 'lights/' . $id, $obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +167,9 @@ HUEBridge_Set($@)
|
|||||||
$hash->{updatestate} = 3;
|
$hash->{updatestate} = 3;
|
||||||
$hash->{STATE} = "updating";
|
$hash->{STATE} = "updating";
|
||||||
return "starting update";
|
return "starting update";
|
||||||
|
} elsif($cmd eq 'autocreate') {
|
||||||
|
HUEBridge_Autocreate($hash);
|
||||||
|
return undef;
|
||||||
} else {
|
} else {
|
||||||
my $list = "statusRequest:noArg";
|
my $list = "statusRequest:noArg";
|
||||||
$list .= " swupdate:noArg" if( defined($hash->{updatestate}) && $hash->{updatestate} == 2 );
|
$list .= " swupdate:noArg" if( defined($hash->{updatestate}) && $hash->{updatestate} == 2 );
|
||||||
@ -203,6 +209,9 @@ HUEBridge_GetUpdate($)
|
|||||||
}
|
}
|
||||||
|
|
||||||
my $result = HUEBridge_Call($hash, 'config', undef);
|
my $result = HUEBridge_Call($hash, 'config', undef);
|
||||||
|
#my $result = HUEBridge_Call($hash, undef, undef);
|
||||||
|
#Log 3, Dumper $result;
|
||||||
|
#$result = $result->{config};
|
||||||
$hash->{name} = $result->{name};
|
$hash->{name} = $result->{name};
|
||||||
$hash->{swversion} = $result->{swversion};
|
$hash->{swversion} = $result->{swversion};
|
||||||
|
|
||||||
@ -232,35 +241,18 @@ HUEBridge_Autocreate($)
|
|||||||
}
|
}
|
||||||
|
|
||||||
my $result = HUEBridge_Call($hash, 'lights', undef);
|
my $result = HUEBridge_Call($hash, 'lights', undef);
|
||||||
|
foreach my $key ( keys %$result ) {
|
||||||
my @defined = ();
|
|
||||||
foreach my $d (keys %defs) {
|
|
||||||
next if($defs{$d}{TYPE} ne "HUEDevice");
|
|
||||||
if(defined($defs{$d}{fhem}) && defined($defs{$d}{fhem}{id})) {
|
|
||||||
push(@defined,$defs{$d}{fhem}{id});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach my $key ( keys %$result )
|
|
||||||
{
|
|
||||||
my $id= $key;
|
my $id= $key;
|
||||||
|
|
||||||
my $found = 0;
|
if( defined($modules{HUEDevice}{defptr}{$id}) ) {
|
||||||
foreach my $d (keys %defs) {
|
Log3 $name, 5, "$name: id '$id' already defined as '$modules{HUEDevice}{defptr}{$id}->{NAME}'";
|
||||||
next if($defs{$d}{TYPE} ne "HUEDevice");
|
next;
|
||||||
if(defined($defs{$d}{fhem}) &&
|
|
||||||
defined($defs{$d}{fhem}{id}) && $defs{$d}{fhem}{id} eq $id) {
|
|
||||||
Log3 $name, 5, "$name id '$id' already defined as '$defs{$d}{NAME}'";
|
|
||||||
$found = 1;
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !$found ) {
|
|
||||||
my $devname= "HUEDevice" . $id;
|
my $devname= "HUEDevice" . $id;
|
||||||
my $define= "$devname HUEDevice $id";
|
my $define= "$devname HUEDevice $id";
|
||||||
|
|
||||||
Log3 $name, 5, "$name create new device '$devname' for address '$id'";
|
Log3 $name, 5, "$name: create new device '$devname' for address '$id'";
|
||||||
|
|
||||||
my $cmdret= CommandDefine(undef,$define);
|
my $cmdret= CommandDefine(undef,$define);
|
||||||
if($cmdret) {
|
if($cmdret) {
|
||||||
@ -270,6 +262,29 @@ HUEBridge_Autocreate($)
|
|||||||
$cmdret= CommandAttr(undef,"$devname room HUEDevice");
|
$cmdret= CommandAttr(undef,"$devname room HUEDevice");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$result = HUEBridge_Call($hash, 'groups', undef);
|
||||||
|
$result->{0} = { name => "Lightset 0", };
|
||||||
|
foreach my $key ( keys %$result ) {
|
||||||
|
my $id= $key;
|
||||||
|
|
||||||
|
if( defined($modules{HUEDevice}{defptr}{'G'.$id}) ) {
|
||||||
|
Log3 $name, 5, "$name: id '$id' already defined as '$modules{HUEDevice}{defptr}{'G'.$id}->{NAME}'";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $devname= "HUEGroup" . $id;
|
||||||
|
my $define= "$devname HUEDevice group $id";
|
||||||
|
|
||||||
|
Log3 $name, 5, "$name: create new group '$devname' for address '$id'";
|
||||||
|
|
||||||
|
my $cmdret= CommandDefine(undef,$define);
|
||||||
|
if($cmdret) {
|
||||||
|
Log3 $name, 1, "$name: Autocreate: An error occurred while creating device for id '$id': $cmdret";
|
||||||
|
} else {
|
||||||
|
$cmdret= CommandAttr(undef,"$devname alias ".$result->{$id}{name});
|
||||||
|
$cmdret= CommandAttr(undef,"$devname room HUEDevice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
@ -471,13 +486,13 @@ HUEBridge_HTTP_Request($$$@)
|
|||||||
The actual hue bulbs, living colors or living whites devices are defined as <a href="#HUEDevice">HUEDevice</a> devices.
|
The actual hue bulbs, living colors or living whites devices are defined as <a href="#HUEDevice">HUEDevice</a> devices.
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
All newly found devices are autocreated at startup and added to the room HUEDevice.
|
All newly found devices and groups are autocreated at startup and added to the room HUEDevice.
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
Notes:
|
Notes:
|
||||||
<ul>
|
<ul>
|
||||||
<li>This module needs <code>JSON</code>.<br>
|
<li>This module needs <code>JSON</code>.<br>
|
||||||
Pleease install with '<code>cpan install JSON</code>' or your method of choice.</li>
|
Please install with '<code>cpan install JSON</code>' or your method of choice.</li>
|
||||||
<li>autocreate only works for the first bridge. devices on other bridges have to be manualy defined.</li>
|
<li>autocreate only works for the first bridge. devices on other bridges have to be manualy defined.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ HUEDevice_devStateIcon($)
|
|||||||
$hash = $defs{$hash} if( ref($hash) ne 'HASH' );
|
$hash = $defs{$hash} if( ref($hash) ne 'HASH' );
|
||||||
|
|
||||||
return undef if( !$hash );
|
return undef if( !$hash );
|
||||||
|
return undef if( $hash->{fhem}->{group} );
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
@ -116,20 +117,32 @@ sub HUEDevice_Define($$)
|
|||||||
|
|
||||||
my @args = split("[ \t]+", $def);
|
my @args = split("[ \t]+", $def);
|
||||||
|
|
||||||
return "Usage: define <name> HUEDevice <id> [interval]" if(@args < 3);
|
$hash->{fhem}->{group} = "";
|
||||||
|
if( $args[2] eq "group" ) {
|
||||||
|
$hash->{fhem}->{group} = "G";
|
||||||
|
splice( @args, 2, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return "Usage: define <name> HUEDevice [group] <id> [interval]" if(@args < 3);
|
||||||
|
|
||||||
my ($name, $type, $id, $interval) = @args;
|
my ($name, $type, $id, $interval) = @args;
|
||||||
|
|
||||||
$interval= 60 unless defined($interval);
|
$interval= 60 unless defined($interval);
|
||||||
if( $interval < 10 ) { $interval = 60; }
|
if( $interval < 10 ) { $interval = 60; }
|
||||||
|
|
||||||
|
|
||||||
$hash->{STATE} = 'Initialized';
|
$hash->{STATE} = 'Initialized';
|
||||||
$hash->{fhem}{interfaces}= "dimmer";
|
$hash->{fhem}{interfaces}= "dimmer";
|
||||||
|
|
||||||
$hash->{ID} = $id;
|
$hash->{ID} = $hash->{fhem}->{group}.$id;
|
||||||
$hash->{fhem}{id} = $id;
|
|
||||||
|
|
||||||
|
return "HUEDevice device $hash->{ID} already used for $modules{HUEDevice}{defptr}{$hash->{ID}}->{NAME}."
|
||||||
|
if( defined($modules{HUEDevice}{defptr}{$hash->{ID}})
|
||||||
|
&& $modules{HUEDevice}{defptr}{$hash->{ID}}->{NAME} ne $name );
|
||||||
|
|
||||||
|
$modules{HUEDevice}{defptr}{$hash->{ID}} = $hash;
|
||||||
|
|
||||||
|
if( !$hash->{fhem}->{group} ) {
|
||||||
$hash->{INTERVAL} = $interval;
|
$hash->{INTERVAL} = $interval;
|
||||||
|
|
||||||
$hash->{fhem}{on} = -1;
|
$hash->{fhem}{on} = -1;
|
||||||
@ -147,6 +160,9 @@ sub HUEDevice_Define($$)
|
|||||||
|
|
||||||
|
|
||||||
$attr{$name}{devStateIcon} = '{(HUEDevice_devStateIcon($name),"toggle")}' if( !defined( $attr{$name}{devStateIcon} ) );
|
$attr{$name}{devStateIcon} = '{(HUEDevice_devStateIcon($name),"toggle")}' if( !defined( $attr{$name}{devStateIcon} ) );
|
||||||
|
} else {
|
||||||
|
$attr{$name}{webCmd} = 'on:off' if( !defined( $attr{$name}{webCmd} ) );
|
||||||
|
}
|
||||||
|
|
||||||
AssignIoPort($hash);
|
AssignIoPort($hash);
|
||||||
if(defined($hash->{IODev}->{NAME})) {
|
if(defined($hash->{IODev}->{NAME})) {
|
||||||
@ -155,7 +171,7 @@ sub HUEDevice_Define($$)
|
|||||||
Log3 $name, 1, "$name: no I/O device";
|
Log3 $name, 1, "$name: no I/O device";
|
||||||
}
|
}
|
||||||
|
|
||||||
#HUEDevice_GetUpdate($hash);
|
RemoveInternalTimer($hash);
|
||||||
InternalTimer(gettimeofday()+10, "HUEDevice_GetUpdate", $hash, 0);
|
InternalTimer(gettimeofday()+10, "HUEDevice_GetUpdate", $hash, 0);
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
@ -167,7 +183,7 @@ sub HUEDevice_Undefine($$)
|
|||||||
|
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
|
|
||||||
delete($hash->{fhem}{id});
|
delete($modules{HUEDevice}{defptr}{$hash->{ID}});
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -322,22 +338,28 @@ HUEDevice_Set($@)
|
|||||||
|
|
||||||
|
|
||||||
if( scalar keys %obj ) {
|
if( scalar keys %obj ) {
|
||||||
my $result = HUEDevice_ReadFromServer($hash,$hash->{ID}."/state",\%obj);
|
my $result;
|
||||||
|
if( $hash->{fhem}->{group} ) {
|
||||||
|
$result = HUEDevice_ReadFromServer($hash,$hash->{ID}."/action",\%obj);
|
||||||
|
} else {
|
||||||
|
$result = HUEDevice_ReadFromServer($hash,$hash->{ID}."/state",\%obj);
|
||||||
|
}
|
||||||
if( $result->{'error'} ) {
|
if( $result->{'error'} ) {
|
||||||
$hash->{STATE} = $result->{'error'}->{'description'};
|
$hash->{STATE} = $result->{'error'}->{'description'};
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
$hash->{LOCAL} = 1;
|
if( !$hash->{fhem}->{group} ) {
|
||||||
HUEDevice_GetUpdate($hash);
|
RemoveInternalTimer($hash);
|
||||||
delete $hash->{LOCAL};
|
InternalTimer(gettimeofday()+1, "HUEDevice_GetUpdate", $hash, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $list = "off:noArg on:noArg toggle:noArg statusRequest:noArg";
|
my $list = "off:noArg on:noArg toggle:noArg statusRequest:noArg";
|
||||||
$list .= " pct:slider,0,1,100 bri:slider,0,1,254 alert:none,select,lselect" if( AttrVal($name, "subType", "colordimmer") =~ m/dimmer/ );
|
$list .= " pct:slider,0,1,100 bri:slider,0,1,254 alert:none,select,lselect" if( AttrVal($name, "subType", "colordimmer") =~ m/dimmer/ );
|
||||||
$list .= " dimUp:noArg dimDown:noArg" if( AttrVal($name, "subType", "colordimmer") =~ m/dimmer/ );
|
$list .= " dimUp:noArg dimDown:noArg" if( !$hash->{fhem}->{group} && AttrVal($name, "subType", "colordimmer") =~ m/dimmer/ );
|
||||||
#$list .= " dim06% dim12% dim18% dim25% dim31% dim37% dim43% dim50% dim56% dim62% dim68% dim75% dim81% dim87% dim93% dim100%" if( AttrVal($hash->{NAME}, "subType", "colordimmer") =~ m/dimmer/ );
|
#$list .= " dim06% dim12% dim18% dim25% dim31% dim37% dim43% dim50% dim56% dim62% dim68% dim75% dim81% dim87% dim93% dim100%" if( AttrVal($hash->{NAME}, "subType", "colordimmer") =~ m/dimmer/ );
|
||||||
$list .= " rgb:colorpicker,RGB color:slider,2000,1,6500 ct:slider,154,1,500 hue:slider,0,1,65535 sat:slider,0,1,254 xy effect:none,colorloop" if( AttrVal($hash->{NAME}, "subType", "colordimmer") =~ m/color/ );
|
$list .= " rgb:colorpicker,RGB color:slider,2000,1,6500 ct:slider,154,1,500 hue:slider,0,1,65535 sat:slider,0,1,254 xy effect:none,colorloop" if( AttrVal($hash->{NAME}, "subType", "colordimmer") =~ m/color/ );
|
||||||
return SetExtensions($hash, $list, $name, @aa);
|
return SetExtensions($hash, $list, $name, @aa);
|
||||||
@ -517,6 +539,22 @@ HUEDevice_GetUpdate($)
|
|||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
if( $hash->{fhem}->{group} ) {
|
||||||
|
my $result = HUEDevice_ReadFromServer($hash,$hash->{ID});
|
||||||
|
|
||||||
|
if( !defined($result) ) {
|
||||||
|
$hash->{STATE} = "unknown";
|
||||||
|
return;
|
||||||
|
} elsif( $result->{'error'} ) {
|
||||||
|
$hash->{STATE} = $result->{'error'}->{'description'};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash->{lights} = join( ",", @{$result->{lights}} );
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
if(!$hash->{LOCAL}) {
|
if(!$hash->{LOCAL}) {
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "HUEDevice_GetUpdate", $hash, 1);
|
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "HUEDevice_GetUpdate", $hash, 1);
|
||||||
@ -547,7 +585,7 @@ HUEDevice_GetUpdate($)
|
|||||||
$attr{$name}{webCmd} = 'rgb:rgb ff0000:rgb 98FF23:rgb 0000ff:toggle:on:off' if( $attr{$name}{subType} eq "colordimmer" );
|
$attr{$name}{webCmd} = 'rgb:rgb ff0000:rgb 98FF23:rgb 0000ff:toggle:on:off' if( $attr{$name}{subType} eq "colordimmer" );
|
||||||
$attr{$name}{webCmd} = 'rgb:rgb ff0000:rgb DEFF26:rgb 0000ff:toggle:on:off' if( AttrVal($name, "model", "") eq "LCT001" );
|
$attr{$name}{webCmd} = 'rgb:rgb ff0000:rgb DEFF26:rgb 0000ff:toggle:on:off' if( AttrVal($name, "model", "") eq "LCT001" );
|
||||||
$attr{$name}{webCmd} = 'pct:toggle:on:off' if( $attr{$name}{subType} eq "dimmer" );
|
$attr{$name}{webCmd} = 'pct:toggle:on:off' if( $attr{$name}{subType} eq "dimmer" );
|
||||||
$attr{$name}{webCmd} = 'toggle:on:off' if( $attr{$name}{subType} eq "switch" );
|
$attr{$name}{webCmd} = 'toggle:on:off' if( $attr{$name}{subType} eq "switch" || $hash->{fhem}->{group} );
|
||||||
}
|
}
|
||||||
|
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
@ -640,19 +678,20 @@ HUEDevice_GetUpdate($)
|
|||||||
<a name="HUEDevice_Define"></a>
|
<a name="HUEDevice_Define"></a>
|
||||||
<b>Define</b>
|
<b>Define</b>
|
||||||
<ul>
|
<ul>
|
||||||
<code>define <name> HUEDevice <id> [<interval>]</code><br>
|
<code>define <name> HUEDevice [group] <id> [<interval>]</code><br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
Defines a device connected to a <a href="#HUEBridge">HUEBridge</a>.<br><br>
|
Defines a device connected to a <a href="#HUEBridge">HUEBridge</a>.<br><br>
|
||||||
|
|
||||||
This can be a hue bulb, a living colors light or a living whites bulb or dimmer plug.<br><br>
|
This can be a hue bulb, a living colors light or a living whites bulb or dimmer plug.<br><br>
|
||||||
|
|
||||||
The device status will be updated every <interval> seconds. The default and minimum is 60.<br><br>
|
The device status will be updated every <interval> seconds. The default and minimum is 60. Groups are updated only on definition and statusRequest<br><br>
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
<ul>
|
<ul>
|
||||||
<code>define bulb HUEDevice 1</code><br>
|
<code>define bulb HUEDevice 1</code><br>
|
||||||
<code>define LC HUEDevice 2</code><br>
|
<code>define LC HUEDevice 2</code><br>
|
||||||
|
<code>define allLights HUEDevice group 0</code><br>
|
||||||
</ul>
|
</ul>
|
||||||
</ul><br>
|
</ul><br>
|
||||||
|
|
||||||
@ -680,6 +719,7 @@ HUEDevice_GetUpdate($)
|
|||||||
<br>
|
<br>
|
||||||
Notes:
|
Notes:
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>groups have no readings.</li>
|
||||||
<li>not all readings show the actual device state. all readings not related to the current colormode have to be ignored.</li>
|
<li>not all readings show the actual device state. all readings not related to the current colormode have to be ignored.</li>
|
||||||
<li>the actual state of a device controlled by a living colors or living whites remote can be different and will
|
<li>the actual state of a device controlled by a living colors or living whites remote can be different and will
|
||||||
be updated after some time.</li>
|
be updated after some time.</li>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user