diff --git a/fhem/FHEM/30_HUEBridge.pm b/fhem/FHEM/30_HUEBridge.pm index 905396577..28d7efbab 100644 --- a/fhem/FHEM/30_HUEBridge.pm +++ b/fhem/FHEM/30_HUEBridge.pm @@ -472,15 +472,15 @@ HUEBridge_Set($@) return "usage: createrule " if( $cmd eq 'createrule' && @args < 2 ); return "usage: updaterule " if( $cmd eq 'updaterule' && @args != 2 ); - @args[@args-1] = ' + $args[@args-1] = ' { "name":"Wall Switch Rule", "conditions":[ {"address":"/sensors/1/state/lastupdated","operator":"dx"} ], "actions":[ {"address":"/groups/0/action","method":"PUT", "body":{"scene":"S3"}} -]}' if( 0 || !@args[@args-1] ); - my $json = @args[@args-1]; +]}' if( 0 || !$args[@args-1] ); + my $json = $args[@args-1]; my $obj = eval { decode_json($json) }; if( $@ ) { Log3 $name, 2, "$name: json error: $@ in $json"; @@ -489,7 +489,7 @@ HUEBridge_Set($@) my $result; if( $cmd eq 'updaterule' ) { - $result = HUEBridge_Call($hash, undef, "rules/@args[0]", $obj, 'PUT'); + $result = HUEBridge_Call($hash, undef, "rules/$args[0]", $obj, 'PUT'); } else { $obj->{name} = join( ' ', @args[0..@args-2]); $result = HUEBridge_Call($hash, undef, 'rules', $obj, 'POST'); @@ -513,13 +513,13 @@ HUEBridge_Set($@) } elsif($cmd eq 'createsensor') { return "usage: createsensor " if( @args < 5 ); - return "usage: type must be one of: Switch OpenClose Presence Temperature Humidity GenericFlag GenericStatus " if( @args[@args-4] !~ m/Switch|OpenClose|Presence|Temperature|Humidity|GenericFlag|GenericStatus/ ); + return "usage: type must be one of: Switch OpenClose Presence Temperature Humidity GenericFlag GenericStatus " if( $args[@args-4] !~ m/Switch|OpenClose|Presence|Temperature|Humidity|GenericFlag|GenericStatus/ ); my $obj = { 'name' => join( ' ', @args[0..@args-5]), - 'type' => "CLIP@args[@args-4]", - 'uniqueid' => @args[@args-3], - 'swversion' => @args[@args-2], - 'modelid' => @args[@args-1], + 'type' => "CLIP$args[@args-4]", + 'uniqueid' => $args[@args-3], + 'swversion' => $args[@args-2], + 'modelid' => $args[@args-1], 'manufacturername' => 'FHEM-HUE', }; @@ -547,12 +547,12 @@ HUEBridge_Set($@) return "usage: deletesensor " if( @args != 1 ); if( defined $defs{$arg} && $defs{$arg}{TYPE} eq 'HUEDevice' ) { - return "$arg is not a hue sensors" if( $defs{$arg}{ID} != m/^G/ ); - $defs{$arg}{ID} =~ m/G(.*)/; + return "$arg is not a hue sensors" if( $defs{$arg}{ID} !~ m/^S/ ); + $defs{$arg}{ID} =~ m/S(.*)/; $arg = $1; } - my $code = $name ."-G". $arg; + my $code = $name ."-S". $arg; if( defined($modules{HUEDevice}{defptr}{$code}) ) { CommandDelete( undef, "$modules{HUEDevice}{defptr}{$code}{NAME}" ); CommandSave(undef,undef) if( AttrVal( "autocreate", "autosave", 1 ) ); @@ -565,13 +565,43 @@ HUEBridge_Set($@) return undef; + } elsif($cmd eq 'configsensor') { + return "usage: configsensor " if( @args < 2 ); + + my $id = $args[0]; + if( defined $defs{$id} && $defs{$id}{TYPE} eq 'HUEDevice' ) { + return "$arg is not a hue sensors" if( $defs{$id}{ID} !~ m/^S/ ); + $defs{$id}{ID} =~ m/S(.*)/; + $id = $1; + } + + return "$id is not a hue sensors number" if( $id !~ m/^\d+$/ ); + + my $config = join( ' ', @args[1..@args-1]); + my $decoded = eval { decode_json($config) }; + if( $@ ) { + Log3 $name, 2, "$name: json error: $@ in $config"; + return undef; + } + $config = $decoded; + + my $result = HUEBridge_Call($hash, undef, "sensors/$id/config", $config, 'PUT'); + return $result->{error}{description} if( $result->{error} ); + + my $code = $name ."-S". $id; + if( my $chash = $modules{HUEDevice}{defptr}{$code} ) { + HUEDevice_GetUpdate($chash); + } + + return undef; + } elsif($cmd eq 'setsensor') { return "usage: setsensor " if( @args < 2 ); my $id = $args[0]; - if( defined $defs{$arg} && $defs{$arg}{TYPE} eq 'HUEDevice' ) { - return "$arg is not a hue sensors" if( $defs{$id}{ID} != m/^G/ ); - $defs{$arg}{ID} =~ m/G(.*)/; + if( defined $defs{$id} && $defs{$id}{TYPE} eq 'HUEDevice' ) { + return "$arg is not a hue sensors" if( $defs{$id}{ID} !~ m/^S/ ); + $defs{$id}{ID} =~ m/S(.*)/; $id = $1; } @@ -588,6 +618,11 @@ HUEBridge_Set($@) my $result = HUEBridge_Call($hash, undef, "sensors/$id/state", $state, 'PUT'); return $result->{error}{description} if( $result->{error} ); + my $code = $name ."-S". $id; + if( my $chash = $modules{HUEDevice}{defptr}{$code} ) { + HUEDevice_GetUpdate($chash); + } + return undef; } elsif($cmd eq 'deletewhitelist') { @@ -624,7 +659,7 @@ HUEBridge_Set($@) } else { - my $list = "delete creategroup deletegroup savescene deletescene modifyscene scene createrule updaterule deleterule createsensor deletesensor setsensor deletewhitelist touchlink:noArg checkforupdate:noArg autodetect:noArg autocreate:noArg statusRequest:noArg"; + my $list = "delete creategroup deletegroup savescene deletescene modifyscene scene createrule updaterule deleterule createsensor deletesensor configsensor setsensor deletewhitelist touchlink:noArg checkforupdate:noArg autodetect:noArg autocreate:noArg statusRequest:noArg"; $list .= " swupdate:noArg" if( defined($hash->{updatestate}) && $hash->{updatestate} =~ '^2' ); return "Unknown argument $cmd, choose one of $list"; } @@ -1545,8 +1580,10 @@ HUEBridge_Attr($$$) Creates a new CLIP (IP) sensor in the bridge.
  • deletesensor <id>
    Deletes the given sensor in the bridge and deletes the associated fhem device.
  • +
  • configsensor <id> <json>
    + Write sensor config data.
  • setsensor <id> <json>
    - Deletes the given key from the whitelist in the bridge.
  • + Write CLIP sensor status data.
  • deletewhitelist <key>
    Deletes the given key from the whitelist in the bridge.
  • touchlink
    diff --git a/fhem/FHEM/31_HUEDevice.pm b/fhem/FHEM/31_HUEDevice.pm index 1e5f61d7f..ab0edc7e7 100644 --- a/fhem/FHEM/31_HUEDevice.pm +++ b/fhem/FHEM/31_HUEDevice.pm @@ -1061,25 +1061,50 @@ HUEDevice_Parse($$) $hash->{modelid} = $result->{modelid} if( defined($result->{modelid}) ); $hash->{productid} = $result->{productid} if( defined($result->{productid}) ); - $hash->{manufacturername} = $result->{manufacturername} if( defined($result->{manufacturername}) ); - $hash->{luminaireuniqueid} = $result->{luminaireuniqueid} if( defined($result->{luminaireuniqueid}) ); $hash->{swversion} = $result->{swversion} if( defined($result->{swversion}) ); $hash->{swconfigid} = $result->{swconfigid} if( defined($result->{swconfigid}) ); + $hash->{manufacturername} = $result->{manufacturername} if( defined($result->{manufacturername}) ); + $hash->{luminaireuniqueid} = $result->{luminaireuniqueid} if( defined($result->{luminaireuniqueid}) ); if( $hash->{helper}->{devtype} eq 'S' ) { + if( my $config = $result->{config} ) { + $hash->{on} = $config->{on}?1:0 if( defined($config->{on}) ); + $hash->{url} = $config->{url} if( defined($config->{url}) ); + $hash->{battery} = $config->{battery} if( defined($config->{battery}) ); + $hash->{reachable} = $config->{reachable} if( defined($config->{reachable}) ); - if( $result->{state} ) { - if( $result->{state}{lastupdated} ne 'none' ) { - substr( $result->{state}{lastupdated}, 10, 1, ' ' ); - if( $result->{state}{buttonevent} - && ReadingsTimestamp($name,"state","") ne $result->{state}{lastupdated} ) { - readingsBeginUpdate($hash); - $hash->{".updateTimestamp"} = $result->{state}{lastupdated}; - $hash->{CHANGETIME}[0] = $result->{state}{lastupdated}; - readingsBulkUpdate($hash, "state", $result->{state}{buttonevent}, 1); - readingsEndUpdate($hash,1); - delete $hash->{CHANGETIME}; + $hash->{lat} = $config->{lat} if( defined($config->{lat}) ); + $hash->{long} = $config->{long} if( defined($config->{long}) ); + $hash->{sunriseoffset} = $config->{sunriseoffset} if( defined($config->{sunriseoffset}) ); + $hash->{sunsetoffset} = $config->{sunsetoffset} if( defined($config->{sunsetoffset}) ); + } + + if( my $state = $result->{state} ) { + return undef if( $state->{lastupdated} eq 'none' ); + + substr( $state->{lastupdated}, 10, 1, ' ' ); + return undef if( ReadingsTimestamp($name,'state','') eq $state->{lastupdated} ); + + my %readings; + + $readings{state} = $state->{buttonevent} if( defined($state->{buttonevent}) ); + $readings{state} = $state->{open}?'open':'closed' if( defined($state->{open}) ); + $readings{state} = $state->{presence}?'present':'absent' if( defined($state->{presence}) ); + $readings{temperature} = $state->{temperature} if( defined($state->{temperature}) ); + $readings{humidity} = $state->{humidity} if( defined($state->{humidity}) ); + $readings{daylight} = $state->{daylight}?'1':'0' if( defined($state->{daylight}) ); + $readings{flag} = $state->{flag}?'1':'0' if( defined($state->{flag}) ); + $readings{status} = $state->{status} if( defined($state->{status}) ); + + if( scalar keys %readings ) { + readingsBeginUpdate($hash); + $hash->{'.updateTimestamp'} = $state->{lastupdated}; + $hash->{CHANGETIME}[0] = $state->{lastupdated}; + foreach my $key ( keys %readings ) { + readingsBulkUpdate($hash, $key, $readings{$key}, 1) if( defined($readings{$key}) ); } + readingsEndUpdate($hash,1); + delete $hash->{CHANGETIME}; } }