diff --git a/fhem/CHANGED b/fhem/CHANGED index 7df229d34..292241967 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,6 +1,7 @@ # 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. - SVN + - feature: HUEBridge,HUEDevice: support for groups added - feature: YAMAHA_AVR: new argument "toggle" for mute command - feature: FB_CALLMONITOR: replace & to & at reverse search - feature: new module 33_readingsProxy to make (a subset of) a reading diff --git a/fhem/FHEM/30_HUEBridge.pm b/fhem/FHEM/30_HUEBridge.pm index 5a23c8b0a..523a2baea 100644 --- a/fhem/FHEM/30_HUEBridge.pm +++ b/fhem/FHEM/30_HUEBridge.pm @@ -37,6 +37,9 @@ HUEBridge_Read($@) { my ($hash,$name,$id,$obj)= @_; + if( $id =~ m/^G(\d.*)/ ) { + return HUEBridge_Call($hash, 'groups/' . $1, $obj); + } return HUEBridge_Call($hash, 'lights/' . $id, $obj); } @@ -164,6 +167,9 @@ HUEBridge_Set($@) $hash->{updatestate} = 3; $hash->{STATE} = "updating"; return "starting update"; + } elsif($cmd eq 'autocreate') { + HUEBridge_Autocreate($hash); + return undef; } else { my $list = "statusRequest:noArg"; $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, undef, undef); + #Log 3, Dumper $result; + #$result = $result->{config}; $hash->{name} = $result->{name}; $hash->{swversion} = $result->{swversion}; @@ -232,43 +241,49 @@ HUEBridge_Autocreate($) } my $result = HUEBridge_Call($hash, 'lights', undef); + foreach my $key ( keys %$result ) { + my $id= $key; - 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}); + if( defined($modules{HUEDevice}{defptr}{$id}) ) { + Log3 $name, 5, "$name: id '$id' already defined as '$modules{HUEDevice}{defptr}{$id}->{NAME}'"; + next; + } + + my $devname= "HUEDevice" . $id; + my $define= "$devname HUEDevice $id"; + + Log3 $name, 5, "$name: create new device '$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"); } } - foreach my $key ( keys %$result ) - { - my $id= $key; + $result = HUEBridge_Call($hash, 'groups', undef); + $result->{0} = { name => "Lightset 0", }; + foreach my $key ( keys %$result ) { + my $id= $key; - my $found = 0; - foreach my $d (keys %defs) { - next if($defs{$d}{TYPE} ne "HUEDevice"); - 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( defined($modules{HUEDevice}{defptr}{'G'.$id}) ) { + Log3 $name, 5, "$name: id '$id' already defined as '$modules{HUEDevice}{defptr}{'G'.$id}->{NAME}'"; + next; } - if( !$found ) { - my $devname= "HUEDevice" . $id; - my $define= "$devname HUEDevice $id"; + my $devname= "HUEGroup" . $id; + my $define= "$devname HUEDevice group $id"; - Log3 $name, 5, "$name create new device '$devname' for address '$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"); - } + 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"); } } @@ -471,13 +486,13 @@ HUEBridge_HTTP_Request($$$@) The actual hue bulbs, living colors or living whites devices are defined as HUEDevice devices.

- 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.

Notes: diff --git a/fhem/FHEM/31_HUEDevice.pm b/fhem/FHEM/31_HUEDevice.pm index c6fc5e5bc..2ab601139 100644 --- a/fhem/FHEM/31_HUEDevice.pm +++ b/fhem/FHEM/31_HUEDevice.pm @@ -76,6 +76,7 @@ HUEDevice_devStateIcon($) $hash = $defs{$hash} if( ref($hash) ne 'HASH' ); return undef if( !$hash ); + return undef if( $hash->{fhem}->{group} ); my $name = $hash->{NAME}; @@ -116,37 +117,52 @@ sub HUEDevice_Define($$) my @args = split("[ \t]+", $def); - return "Usage: define HUEDevice [interval]" if(@args < 3); + $hash->{fhem}->{group} = ""; + if( $args[2] eq "group" ) { + $hash->{fhem}->{group} = "G"; + splice( @args, 2, 1 ); + } + + + return "Usage: define HUEDevice [group] [interval]" if(@args < 3); my ($name, $type, $id, $interval) = @args; $interval= 60 unless defined($interval); if( $interval < 10 ) { $interval = 60; } - $hash->{STATE} = 'Initialized'; $hash->{fhem}{interfaces}= "dimmer"; - $hash->{ID} = $id; - $hash->{fhem}{id} = $id; + $hash->{ID} = $hash->{fhem}->{group}.$id; - $hash->{INTERVAL} = $interval; + 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 ); - $hash->{fhem}{on} = -1; - $hash->{fhem}{reachable} = ''; - $hash->{fhem}{colormode} = ''; - $hash->{fhem}{bri} = -1; - $hash->{fhem}{ct} = -1; - $hash->{fhem}{hue} = -1; - $hash->{fhem}{sat} = -1; - $hash->{fhem}{xy} = ''; - $hash->{fhem}{alert} = ''; - $hash->{fhem}{effect} = ''; + $modules{HUEDevice}{defptr}{$hash->{ID}} = $hash; - $hash->{fhem}{percent} = -1; + if( !$hash->{fhem}->{group} ) { + $hash->{INTERVAL} = $interval; + + $hash->{fhem}{on} = -1; + $hash->{fhem}{reachable} = ''; + $hash->{fhem}{colormode} = ''; + $hash->{fhem}{bri} = -1; + $hash->{fhem}{ct} = -1; + $hash->{fhem}{hue} = -1; + $hash->{fhem}{sat} = -1; + $hash->{fhem}{xy} = ''; + $hash->{fhem}{alert} = ''; + $hash->{fhem}{effect} = ''; + + $hash->{fhem}{percent} = -1; - $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); if(defined($hash->{IODev}->{NAME})) { @@ -155,7 +171,7 @@ sub HUEDevice_Define($$) Log3 $name, 1, "$name: no I/O device"; } - #HUEDevice_GetUpdate($hash); + RemoveInternalTimer($hash); InternalTimer(gettimeofday()+10, "HUEDevice_GetUpdate", $hash, 0); return undef; @@ -167,7 +183,7 @@ sub HUEDevice_Undefine($$) RemoveInternalTimer($hash); - delete($hash->{fhem}{id}); + delete($modules{HUEDevice}{defptr}{$hash->{ID}}); return undef; } @@ -322,22 +338,28 @@ HUEDevice_Set($@) 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'} ) { $hash->{STATE} = $result->{'error'}->{'description'}; return undef; } - $hash->{LOCAL} = 1; - HUEDevice_GetUpdate($hash); - delete $hash->{LOCAL}; + if( !$hash->{fhem}->{group} ) { + RemoveInternalTimer($hash); + InternalTimer(gettimeofday()+1, "HUEDevice_GetUpdate", $hash, 1); + } return undef; } 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 .= " 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 .= " 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); @@ -517,6 +539,22 @@ HUEDevice_GetUpdate($) my ($hash) = @_; 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}) { RemoveInternalTimer($hash); 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 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} = '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); @@ -640,19 +678,20 @@ HUEDevice_GetUpdate($) Define
    - define <name> HUEDevice <id> [<interval>]
    + define <name> HUEDevice [group] <id> [<interval>]

    Defines a device connected to a HUEBridge.

    This can be a hue bulb, a living colors light or a living whites bulb or dimmer plug.

    - The device status will be updated every <interval> seconds. The default and minimum is 60.

    + The device status will be updated every <interval> seconds. The default and minimum is 60. Groups are updated only on definition and statusRequest

    Examples:
      define bulb HUEDevice 1
      define LC HUEDevice 2
      + define allLights HUEDevice group 0

@@ -680,6 +719,7 @@ HUEDevice_GetUpdate($)
Notes:
    +
  • groups have no readings.
  • not all readings show the actual device state. all readings not related to the current colormode have to be ignored.
  • 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.
  • @@ -693,7 +733,7 @@ HUEDevice_GetUpdate($)
  • off [<ramp-time>]
  • toggle [<ramp-time>]
  • statusRequest
    - Request device status update.
  • + Request device status update.
  • pct <value> [<ramp-time>]
    dim to <value>
    Note: the FS20 compatible dimXX% commands are also accepted.