From b1c1da0c6303798ad33e579f25e36946b3810157 Mon Sep 17 00:00:00 2001 From: justme-1968 Date: Thu, 19 Dec 2013 17:21:19 +0000 Subject: [PATCH] fix for multiple bridges git-svn-id: https://svn.fhem.de/fhem/trunk@4418 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/30_HUEBridge.pm | 65 +++++++++++--- fhem/FHEM/31_HUEDevice.pm | 176 +++++++++++++++++++++----------------- 2 files changed, 150 insertions(+), 91 deletions(-) diff --git a/fhem/FHEM/30_HUEBridge.pm b/fhem/FHEM/30_HUEBridge.pm index 1671f4c1e..fb1e1989b 100644 --- a/fhem/FHEM/30_HUEBridge.pm +++ b/fhem/FHEM/30_HUEBridge.pm @@ -26,6 +26,7 @@ sub HUEBridge_Initialize($) #Consumer $hash->{DefFn} = "HUEBridge_Define"; + $hash->{NotifyFn} = "HUEBridge_Notify"; $hash->{SetFn} = "HUEBridge_Set"; $hash->{GetFn} = "HUEBridge_Get"; $hash->{UndefFn} = "HUEBridge_Undefine"; @@ -43,7 +44,8 @@ HUEBridge_Read($@) return HUEBridge_Call($hash, 'lights/' . $id, $obj); } -sub HUEBridge_Define($$) +sub +HUEBridge_Define($$) { my ($hash, $def) = @_; @@ -83,8 +85,37 @@ sub HUEBridge_Define($$) $attr{$name}{"key"} = join "",map { unpack "H*", chr(rand(256)) } 1..16 unless defined( AttrVal($name, "key", undef) ); - #HUEBridge_OpenDev($hash); - InternalTimer(gettimeofday()+10, "HUEBridge_OpenDev", $hash, 0); + if( !defined($hash->{helper}{count}) ) { + $modules{$hash->{TYPE}}{helper}{count} = 0 if( !defined($modules{$hash->{TYPE}}{helper}{count}) ); + $hash->{helper}{count} = $modules{$hash->{TYPE}}{helper}{count}++; + } + + if( $init_done ) { + delete $modules{$hash->{TYPE}}{NotifyFn}; + HUEBridge_OpenDev( $hash ); + } + + return undef; +} +sub +HUEBridge_Notify($$) +{ + my ($hash,$dev) = @_; + my $name = $hash->{NAME}; + my $type = $hash->{TYPE}; + + return if($dev->{NAME} ne "global"); + return if(!grep(m/^INITIALIZED|REREADCFG$/, @{$dev->{CHANGED}})); + + return if($attr{$name} && $attr{$name}{disable}); + + delete $modules{$type}{NotifyFn}; + delete $hash->{NTFY_ORDER} if($hash->{NTFY_ORDER}); + + foreach my $d (keys %defs) { + next if($defs{$d}{TYPE} ne "$type"); + HUEBridge_OpenDev($defs{$d}); + } return undef; } @@ -252,15 +283,17 @@ HUEBridge_Autocreate($) foreach my $key ( keys %$result ) { my $id= $key; - if( defined($modules{HUEDevice}{defptr}{$id}) ) { - Log3 $name, 5, "$name: id '$id' already defined as '$modules{HUEDevice}{defptr}{$id}->{NAME}'"; - next; + my $code = $name ."-". $id; + if( defined($modules{HUEDevice}{defptr}{$code}) ) { + Log3 $name, 4, "$name: id '$id' already defined as '$modules{HUEDevice}{defptr}{$code}->{NAME}'"; + next; } - my $devname= "HUEDevice" . $id; - my $define= "$devname HUEDevice $id"; + my $devname = "HUEDevice" . $id; + $devname = $name ."_". $devname if( $hash->{helper}{count} ); + my $define= "$devname HUEDevice $id IODev=$name"; - Log3 $name, 5, "$name: create new device '$devname' for address '$id'"; + Log3 $name, 4, "$name: create new device '$devname' for address '$id'"; my $cmdret= CommandDefine(undef,$define); if($cmdret) { @@ -268,6 +301,7 @@ HUEBridge_Autocreate($) } else { $cmdret= CommandAttr(undef,"$devname alias ".$result->{$id}{name}); $cmdret= CommandAttr(undef,"$devname room HUEDevice"); + $cmdret= CommandAttr(undef,"$devname IODev $name"); } } @@ -276,15 +310,17 @@ HUEBridge_Autocreate($) 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 $code = $name ."-G". $id; + if( defined($modules{HUEDevice}{defptr}{$code}) ) { + Log3 $name, 4, "$name: id '$id' already defined as '$modules{HUEDevice}{defptr}{$code}->{NAME}'"; + next; } my $devname= "HUEGroup" . $id; - my $define= "$devname HUEDevice group $id"; + $devname = $name ."_". $devname if( $hash->{helper}{count} ); + my $define= "$devname HUEDevice group $id IODev=$name"; - Log3 $name, 5, "$name: create new group '$devname' for address '$id'"; + Log3 $name, 4, "$name: create new group '$devname' for address '$id'"; my $cmdret= CommandDefine(undef,$define); if($cmdret) { @@ -292,6 +328,7 @@ HUEBridge_Autocreate($) } else { $cmdret= CommandAttr(undef,"$devname alias ".$result->{$id}{name}); $cmdret= CommandAttr(undef,"$devname room HUEDevice"); + $cmdret= CommandAttr(undef,"$devname IODev $name"); } } diff --git a/fhem/FHEM/31_HUEDevice.pm b/fhem/FHEM/31_HUEDevice.pm index 126e7afe3..78b85803c 100644 --- a/fhem/FHEM/31_HUEDevice.pm +++ b/fhem/FHEM/31_HUEDevice.pm @@ -78,11 +78,11 @@ HUEDevice_devStateIcon($) $hash = $defs{$hash} if( ref($hash) ne 'HASH' ); return undef if( !$hash ); - return undef if( $hash->{fhem}->{group} ); + return undef if( $hash->{helper}->{group} ); my $name = $hash->{NAME}; - return ".*:light_question" if( !$hash->{fhem}{reachable} && AttrVal($name, "color-icons", 0) != 0 ); + return ".*:light_question" if( !$hash->{helper}{reachable} && AttrVal($name, "color-icons", 0) != 0 ); return ".*:off:toggle" if( ReadingsVal($name,"state","off") eq "off" || ReadingsVal($name,"bri","0") eq 0 ); @@ -119,12 +119,23 @@ sub HUEDevice_Define($$) my @args = split("[ \t]+", $def); - $hash->{fhem}->{group} = ""; + $hash->{helper}->{group} = ""; if( $args[2] eq "group" ) { - $hash->{fhem}->{group} = "G"; + $hash->{helper}->{group} = "G"; splice( @args, 2, 1 ); } + my $iodev; + my $i = 0; + foreach my $param ( @args ) { + if( $param =~ m/IODev=(.*)/ ) { + $iodev = $1; + splice( @args, $i, 1 ); + last; + } + $i++; + } + return "Usage: define HUEDevice [group] [interval]" if(@args < 3); @@ -134,45 +145,53 @@ sub HUEDevice_Define($$) if( $interval < 10 ) { $interval = 60; } $hash->{STATE} = 'Initialized'; - $hash->{fhem}{interfaces}= "dimmer"; + $hash->{helper}{interfaces}= "dimmer"; - $hash->{ID} = $hash->{fhem}->{group}.$id; + $hash->{ID} = $hash->{helper}->{group}.$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->{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} ) ); - } else { - $attr{$name}{webCmd} = 'on:off' if( !defined( $attr{$name}{webCmd} ) ); - } - - AssignIoPort($hash); + AssignIoPort($hash,$iodev) if( !$hash->{IODev} ); if(defined($hash->{IODev}->{NAME})) { Log3 $name, 3, "$name: I/O device is " . $hash->{IODev}->{NAME}; } else { Log3 $name, 1, "$name: no I/O device"; } + my $code = $hash->{ID}; + $code = $hash->{IODev}->{NAME} ."-". $code if( defined($hash->{IODev}->{NAME}) ); + my $d = $modules{HUEDevice}{defptr}{$code}; + return "HUEDevice device $hash->{ID} on HUEBridge $d->{IODev}->{NAME} already defined as $d->{NAME}." + if( defined($d) + && $d->{IODev} == $hash->{IODev} + && $d->{NAME} ne $name ); + + $modules{HUEDevice}{defptr}{$code} = $hash; + + $args[3] = "" if( !defined( $args[3] ) ); + if( !$hash->{helper}->{group} ) { + $hash->{DEF} = "$id $args[3]"; + + $hash->{INTERVAL} = $interval; + + $hash->{helper}{on} = -1; + $hash->{helper}{reachable} = ''; + $hash->{helper}{colormode} = ''; + $hash->{helper}{bri} = -1; + $hash->{helper}{ct} = -1; + $hash->{helper}{hue} = -1; + $hash->{helper}{sat} = -1; + $hash->{helper}{xy} = ''; + $hash->{helper}{alert} = ''; + $hash->{helper}{effect} = ''; + + $hash->{helper}{percent} = -1; + + + $attr{$name}{devStateIcon} = '{(HUEDevice_devStateIcon($name),"toggle")}' if( !defined( $attr{$name}{devStateIcon} ) ); + } else { + $hash->{DEF} = "group $id $args[3]"; + $attr{$name}{webCmd} = 'on:off' if( !defined( $attr{$name}{webCmd} ) ); + } + RemoveInternalTimer($hash); InternalTimer(gettimeofday()+10, "HUEDevice_GetUpdate", $hash, 0); @@ -185,7 +204,10 @@ sub HUEDevice_Undefine($$) RemoveInternalTimer($hash); - delete($modules{HUEDevice}{defptr}{$hash->{ID}}); + my $code = $hash->{ID}; + $code = $hash->{IODev}->{NAME} ."-". $code if( defined($hash->{IODev}->{NAME}) ); + + delete($modules{HUEDevice}{defptr}{$code}); return undef; } @@ -236,7 +258,7 @@ HUEDevice_SetParam($$@) $obj->{'bri'} = 0+$bri; $obj->{'transitiontime'} = 1; #$obj->{'transitiontime'} = $value / 10 if( defined($value) ); - $defs{$name}->{fhem}->{update_timeout} = 0; + $defs{$name}->{helper}->{update_timeout} = 0; } elsif($cmd eq "dimDown") { my $bri = ReadingsVal($name,"bri","0"); $bri -= 25; @@ -245,7 +267,7 @@ HUEDevice_SetParam($$@) $obj->{'bri'} = 0+$bri; $obj->{'transitiontime'} = 1; #$obj->{'transitiontime'} = $value / 10 if( defined($value) ); - $defs{$name}->{fhem}->{update_timeout} = 0; + $defs{$name}->{helper}->{update_timeout} = 0; } elsif($cmd eq "ct") { $obj->{'on'} = JSON::true; $obj->{'ct'} = 0+$value; @@ -310,11 +332,11 @@ HUEDevice_SetParam($$@) } elsif( $cmd eq "transitiontime" ) { $obj->{'transitiontime'} = 0+$value; } elsif( $cmd eq "delayedUpdate" ) { - $defs{$name}->{fhem}->{update_timeout} = 1; + $defs{$name}->{helper}->{update_timeout} = 1; } elsif( $cmd eq "immediateUpdate" ) { - $defs{$name}->{fhem}->{update_timeout} = 0; + $defs{$name}->{helper}->{update_timeout} = 0; } elsif( $cmd eq "noUpdate" ) { - $defs{$name}->{fhem}->{update_timeout} = -1; + $defs{$name}->{helper}->{update_timeout} = -1; } else { return 0; } @@ -329,7 +351,7 @@ HUEDevice_Set($@) my %obj; - $defs{$name}->{fhem}->{update_timeout} = AttrVal($name, "delayedUpdate", 0); + $defs{$name}->{helper}->{update_timeout} = AttrVal($name, "delayedUpdate", 0); if( (my $joined = join(" ", @aa)) =~ /:/ ) { my @cmds = split(":", $joined); @@ -348,22 +370,22 @@ HUEDevice_Set($@) HUEDevice_SetParam($name, \%obj, $cmd, $value, $value2); } -# if( $defs{$name}->{fhem}->{update_timeout} == -1 ) { +# if( $defs{$name}->{helper}->{update_timeout} == -1 ) { # my $diff; # my ($seconds, $microseconds) = gettimeofday(); -# if( $defs{$name}->{fhem}->{timestamp} ) { -# my ($seconds2, $microseconds2) = @{$defs{$name}->{fhem}->{timestamp}}; +# if( $defs{$name}->{helper}->{timestamp} ) { +# my ($seconds2, $microseconds2) = @{$defs{$name}->{helper}->{timestamp}}; # # $diff = (($seconds-$seconds2)*1000000 + $microseconds-$microseconds2)/1000; # } -# $defs{$name}->{fhem}->{timestamp} = [$seconds, $microseconds]; +# $defs{$name}->{helper}->{timestamp} = [$seconds, $microseconds]; # # return undef if( $diff < 100 ); # } if( scalar keys %obj ) { my $result; - if( $hash->{fhem}->{group} ) { + if( $hash->{helper}->{group} ) { $result = HUEDevice_ReadFromServer($hash,$hash->{ID}."/action",\%obj); } else { $result = HUEDevice_ReadFromServer($hash,$hash->{ID}."/state",\%obj); @@ -373,9 +395,9 @@ HUEDevice_Set($@) return undef; } - if( $defs{$name}->{fhem}->{update_timeout} == -1 ) { - } elsif( $defs{$name}->{fhem}->{update_timeout} - && !$hash->{fhem}->{group} ) { + if( $defs{$name}->{helper}->{update_timeout} == -1 ) { + } elsif( $defs{$name}->{helper}->{update_timeout} + && !$hash->{helper}->{group} ) { RemoveInternalTimer($hash); InternalTimer(gettimeofday()+1, "HUEDevice_GetUpdate", $hash, 1); } else { @@ -388,7 +410,7 @@ HUEDevice_Set($@) 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( !$hash->{fhem}->{group} && AttrVal($name, "subType", "colordimmer") =~ m/dimmer/ ); + $list .= " dimUp:noArg dimDown:noArg" if( !$hash->{helper}->{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); @@ -568,7 +590,7 @@ HUEDevice_GetUpdate($) my ($hash) = @_; my $name = $hash->{NAME}; - if( $hash->{fhem}->{group} ) { + if( $hash->{helper}->{group} ) { my $result = HUEDevice_ReadFromServer($hash,$hash->{ID}); if( !defined($result) ) { @@ -614,7 +636,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" || $hash->{fhem}->{group} ); + $attr{$name}{webCmd} = 'toggle:on:off' if( $attr{$name}{subType} eq "switch" || $hash->{helper}->{group} ); } readingsBeginUpdate($hash); @@ -633,9 +655,9 @@ HUEDevice_GetUpdate($) my $alert = $state->{alert}; my $effect = $state->{effect}; - if( defined($colormode) && $colormode ne $hash->{fhem}{colormode} ) {readingsBulkUpdate($hash,"colormode",$colormode);} - if( defined($bri) && $bri != $hash->{fhem}{bri} ) {readingsBulkUpdate($hash,"bri",$bri);} - if( defined($ct) && $ct != $hash->{fhem}{ct} ) { + if( defined($colormode) && $colormode ne $hash->{helper}{colormode} ) {readingsBulkUpdate($hash,"colormode",$colormode);} + if( defined($bri) && $bri != $hash->{helper}{bri} ) {readingsBulkUpdate($hash,"bri",$bri);} + if( defined($ct) && $ct != $hash->{helper}{ct} ) { if( $ct == 0 ) { readingsBulkUpdate($hash,"ct",$ct); } @@ -643,19 +665,19 @@ HUEDevice_GetUpdate($) readingsBulkUpdate($hash,"ct",$ct . " (".int(1000000/$ct)."K)"); } } - if( defined($hue) && $hue != $hash->{fhem}{hue} ) {readingsBulkUpdate($hash,"hue",$hue);} - if( defined($sat) && $sat != $hash->{fhem}{sat} ) {readingsBulkUpdate($hash,"sat",$sat);} - if( defined($xy) && $xy ne $hash->{fhem}{xy} ) {readingsBulkUpdate($hash,"xy",$xy);} - if( defined($reachable) && $reachable ne $hash->{fhem}{reachable} ) {readingsBulkUpdate($hash,"reachable",$reachable);} - if( defined($alert) && $alert ne $hash->{fhem}{alert} ) {readingsBulkUpdate($hash,"alert",$alert);} - if( defined($effect) && $effect ne $hash->{fhem}{effect} ) {readingsBulkUpdate($hash,"effect",$effect);} + if( defined($hue) && $hue != $hash->{helper}{hue} ) {readingsBulkUpdate($hash,"hue",$hue);} + if( defined($sat) && $sat != $hash->{helper}{sat} ) {readingsBulkUpdate($hash,"sat",$sat);} + if( defined($xy) && $xy ne $hash->{helper}{xy} ) {readingsBulkUpdate($hash,"xy",$xy);} + if( defined($reachable) && $reachable ne $hash->{helper}{reachable} ) {readingsBulkUpdate($hash,"reachable",$reachable);} + if( defined($alert) && $alert ne $hash->{helper}{alert} ) {readingsBulkUpdate($hash,"alert",$alert);} + if( defined($effect) && $effect ne $hash->{helper}{effect} ) {readingsBulkUpdate($hash,"effect",$effect);} my $s = ''; my $percent; if( $on ) { $s = 'on'; - if( $on != $hash->{fhem}{on} ) {readingsBulkUpdate($hash,"onoff",1);} + if( $on != $hash->{helper}{on} ) {readingsBulkUpdate($hash,"onoff",1);} $percent = int( $bri * 100 / 254 ); if( $percent > 0 @@ -668,11 +690,11 @@ HUEDevice_GetUpdate($) { $s = 'off'; $percent = 0; - if( $on != $hash->{fhem}{on} ) {readingsBulkUpdate($hash,"onoff",0);} + if( $on != $hash->{helper}{on} ) {readingsBulkUpdate($hash,"onoff",0);} } - if( $percent != $hash->{fhem}{percent} ) {readingsBulkUpdate($hash,"level", $percent . ' %');} - if( $percent != $hash->{fhem}{percent} ) {readingsBulkUpdate($hash,"pct", $percent);} + if( $percent != $hash->{helper}{percent} ) {readingsBulkUpdate($hash,"level", $percent . ' %');} + if( $percent != $hash->{helper}{percent} ) {readingsBulkUpdate($hash,"pct", $percent);} $s = 'off' if( !$reachable ); @@ -681,18 +703,18 @@ HUEDevice_GetUpdate($) CommandTrigger( "", "$name RGB: ".CommandGet("","$name rgb") ); - $hash->{fhem}{on} = $on; - $hash->{fhem}{reachable} = $reachable; - $hash->{fhem}{colormode} = $colormode; - $hash->{fhem}{bri} = $bri; - $hash->{fhem}{ct} = $ct; - $hash->{fhem}{hue} = $hue; - $hash->{fhem}{sat} = $sat; - $hash->{fhem}{xy} = $xy; - $hash->{fhem}{alert} = $alert; - $hash->{fhem}{effect} = $effect; + $hash->{helper}{on} = $on; + $hash->{helper}{reachable} = $reachable; + $hash->{helper}{colormode} = $colormode; + $hash->{helper}{bri} = $bri; + $hash->{helper}{ct} = $ct; + $hash->{helper}{hue} = $hue; + $hash->{helper}{sat} = $sat; + $hash->{helper}{xy} = $xy; + $hash->{helper}{alert} = $alert; + $hash->{helper}{effect} = $effect; - $hash->{fhem}{percent} = $percent; + $hash->{helper}{percent} = $percent; } 1;