diff --git a/73_NUKIBridge.pm b/73_NUKIBridge.pm index 15863a8..0359b73 100755 --- a/73_NUKIBridge.pm +++ b/73_NUKIBridge.pm @@ -46,17 +46,25 @@ use JSON; use HttpUtils; -my $version = "0.6.4"; -my $bridgeapi = "1.6"; +my $version = "0.6.5"; +my $bridgeapi = "1.9"; -my %lockActions = ( - 'unlock' => 1, - 'lock' => 2, - 'unlatch' => 3, - 'locknGo' => 4, - 'locknGoWithUnlatch' => 5 +my %lockActionsSmartLock = ( + 'unlock' => 1, + 'lock' => 2, + 'unlatch' => 3, + 'locknGo' => 4, + 'locknGoWithUnlatch' => 5 +); + +my %lockActionsOpener = ( + 'activateRto' => 1, + 'deactivateRto' => 2, + 'electricStrikeActuation' => 3, + 'activateContinuousMode' => 4, + 'deactivateContinuousMode' => 5 ); @@ -72,7 +80,7 @@ sub NUKIBridge_Set($@); sub NUKIBridge_Get($@); sub NUKIBridge_GetCheckBridgeAlive($); sub NUKIBridge_firstRun($); -sub NUKIBridge_Call($$$$$); +sub NUKIBridge_Call($$$$$$); sub NUKIBridge_Distribution($$$); sub NUKIBridge_ResponseProcessing($$$); sub NUKIBridge_CGI(); @@ -117,8 +125,8 @@ sub NUKIBridge_Initialize($) { sub NUKIBridge_Read($@) { - my ($hash,$chash,$name,$path,$lockAction,$nukiId)= @_; - NUKIBridge_Call($hash,$chash,$path,$lockAction,$nukiId ); + my ($hash,$chash,$name,$path,$lockAction,$nukiId,$deviceType)= @_; + NUKIBridge_Call($hash,$chash,$path,$lockAction,$nukiId,$deviceType ); } @@ -252,7 +260,7 @@ sub NUKIBridge_Attr(@) { my $url = "http://$webhookHttpHostname" . ":" . $hash->{WEBHOOK_PORT} . $hash->{WEBHOOK_URI}; Log3 $name, 3, "NUKIBridge ($name) - URL ist: $url"; - NUKIBridge_Call($hash,$hash,"callback/add",$url,undef ) if( $init_done ); + NUKIBridge_Call($hash,$hash,"callback/add",$url,undef,undef ) if( $init_done ); $hash->{WEBHOOK_REGISTER} = "sent"; } else { @@ -297,14 +305,14 @@ sub NUKIBridge_Set($@) { if($cmd eq 'autocreate') { return "usage: autocreate" if( @args != 0 ); - NUKIBridge_Call($hash,$hash,"list",undef,undef) if( !IsDisabled($name) ); + NUKIBridge_Call($hash,$hash,"list",undef,undef,undef) if( !IsDisabled($name) ); return undef; } elsif($cmd eq 'info') { return "usage: statusRequest" if( @args != 0 ); - NUKIBridge_Call($hash,$hash,"info",undef,undef) if( !IsDisabled($name) ); + NUKIBridge_Call($hash,$hash,"info",undef,undef,undef) if( !IsDisabled($name) ); return undef; @@ -384,7 +392,7 @@ sub NUKIBridge_GetCheckBridgeAlive($) { if( !IsDisabled($name) ) { - NUKIBridge_Call($hash,$hash,'info',undef,undef); + NUKIBridge_Call($hash,$hash,'info',undef,undef,undef); Log3 $name, 4, "NUKIBridge ($name) - run NUKIBridge_Call"; } @@ -401,15 +409,15 @@ sub NUKIBridge_firstRun($) { RemoveInternalTimer($hash); - NUKIBridge_Call($hash,$hash,'list',undef,undef) if( !IsDisabled($name) ); + NUKIBridge_Call($hash,$hash,'list',undef,undef,undef) if( !IsDisabled($name) ); InternalTimer( gettimeofday()+15, 'NUKIBridge_GetCheckBridgeAlive', $hash, 1 ); return undef; } -sub NUKIBridge_Call($$$$$) { +sub NUKIBridge_Call($$$$$$) { - my ($hash,$chash,$path,$lockAction,$nukiId) = @_; + my ($hash,$chash,$path,$lockAction,$nukiId,$deviceType) = @_; my $name = $hash->{NAME}; my $host = $hash->{HOST}; @@ -420,9 +428,11 @@ sub NUKIBridge_Call($$$$$) { my $uri = "http://" . $hash->{HOST} . ":" . $port; $uri .= "/" . $path if( defined $path); $uri .= "?token=" . $token if( defined($token) ); - $uri .= "&action=" . $lockActions{$lockAction} if( defined($lockAction) and $path ne "callback/add" ); + $uri .= "&action=" . $lockActionsSmartLock{$lockAction} if( defined($lockAction) and $path ne "callback/add" and $chash->{DEVICETYPE} == 0 ); + $uri .= "&action=" . $lockActionsOpener{$lockAction} if( defined($lockAction) and $path ne "callback/add" and $chash->{DEVICETYPE} == 2 ); $uri .= "&url=" . $lockAction if( defined($lockAction) and $path eq "callback/add" ); $uri .= "&nukiId=" . $nukiId if( defined($nukiId) ); + $uri .= "&deviceType=" . $deviceType if( defined($deviceType) ); HttpUtils_NonblockingGet( @@ -566,7 +576,7 @@ sub NUKIBridge_ResponseProcessing($$$) { if( ref($decode_json) eq "ARRAY" and scalar(@{$decode_json}) > 0 and $path eq "list" ) { NUKIBridge_Autocreate($hash,$decode_json); - NUKIBridge_Call($hash,$hash,"info",undef,undef) if( !IsDisabled($name) ); + NUKIBridge_Call($hash,$hash,"info",undef,undef,undef) if( !IsDisabled($name) ); } elsif( $path eq "info" ) { @@ -616,6 +626,8 @@ sub NUKIBridge_CGI() { return "NUKIBridge ($name) - invalid json detected: $json"; } + Log3 $name, 5, "NUKIBridge ($name) - Webhook received with JSON: $json"; + my $decode_json = eval{decode_json($json)}; if($@){ Log3 $name, 3, "NUKIBridge ($name) - JSON error while request: $@"; @@ -624,6 +636,9 @@ sub NUKIBridge_CGI() { if( ref($decode_json) eq "HASH" ) { + $hash->{WEBHOOK_COUNTER}++; + $hash->{WEBHOOK_LAST} = TimeNow(); + if ( defined( $modules{NUKIDevice}{defptr} ) ) { while ( my ( $key, $value ) = each %{ $modules{NUKIDevice}{defptr} } ) { @@ -632,8 +647,6 @@ sub NUKIBridge_CGI() { $nukiId = InternalVal( $name, "NUKIID", undef ); next if ( !$nukiId or $nukiId ne $decode_json->{nukiId} ); - $hash->{WEBHOOK_COUNTER}++; - $hash->{WEBHOOK_LAST} = TimeNow(); Log3 $name, 4, "NUKIBridge ($name) - Received webhook for matching NukiId at device $name"; @@ -668,6 +681,7 @@ sub NUKIBridge_Autocreate($$;$) { my $autocreated = 0; my $nukiSmartlock; my $nukiId; + my $nukiType; my $nukiName; readingsBeginUpdate($hash); @@ -675,6 +689,7 @@ sub NUKIBridge_Autocreate($$;$) { foreach $nukiSmartlock (@{$decode_json}) { $nukiId = $nukiSmartlock->{nukiId}; + $nukiType = $nukiSmartlock->{deviceType}; $nukiName = $nukiSmartlock->{name}; @@ -685,7 +700,8 @@ sub NUKIBridge_Autocreate($$;$) { } my $devname = "NUKIDevice" . $nukiId; - my $define= "$devname NUKIDevice $nukiId IODev=$name"; + my $define= "$devname NUKIDevice $nukiId IODev=$name $nukiType"; + Log3 $name, 3, "NUKIDevice ($name) - create new device '$devname' for address '$nukiId'"; my $cmdret= CommandDefine(undef,$define); diff --git a/74_NUKIDevice.pm b/74_NUKIDevice.pm index c948898..0d1c561 100755 --- a/74_NUKIDevice.pm +++ b/74_NUKIDevice.pm @@ -33,7 +33,7 @@ use warnings; use JSON; -my $version = "0.6.4"; +my $version = "0.6.5"; @@ -86,18 +86,19 @@ sub NUKIDevice_Define($$) { foreach my $param ( @a ) { if( $param =~ m/IODev=([^\s]*)/ ) { $iodev = $1; - splice( @a, $i, 3 ); + splice( @a, $i, 1 ); last; } $i++; } - return "too few parameters: define NUKIDevice " if( @a < 2 ); + return "too few parameters: define NUKIDevice " if( @a < 2 ); - my ($name,$nukiId) = @a; + my ($name,$nukiId,$deviceType) = @a; $hash->{NUKIID} = $nukiId; + $hash->{DEVICETYPE} = (defined $deviceType) ? $deviceType : 0; $hash->{VERSION} = $version; $hash->{STATE} = 'Initialized'; @@ -203,33 +204,40 @@ sub NUKIDevice_Set($$@) { NUKIDevice_GetUpdate($hash); return undef; - } elsif( $cmd eq 'lock' ) { + } elsif( $cmd eq 'lock' or $cmd eq 'deactivateRto' ) { $lockAction = $cmd; - } elsif( $cmd eq 'unlock' ) { + } elsif( $cmd eq 'unlock' or $cmd eq 'activateRto' ) { $lockAction = $cmd; - } elsif( $cmd eq 'unlatch' ) { + } elsif( $cmd eq 'unlatch' or $cmd eq 'electricStrikeActuation' ) { $lockAction = $cmd; - } elsif( $cmd eq 'locknGo' ) { + } elsif( $cmd eq 'locknGo' or $cmd eq 'activateContinuousMode' ) { $lockAction = $cmd; - } elsif( $cmd eq 'locknGoWithUnlatch' ) { + } elsif( $cmd eq 'locknGoWithUnlatch' or $cmd eq 'deactivateContinuousMode' ) { $lockAction = $cmd; } elsif( $cmd eq 'unpair' ) { - NUKIDevice_ReadFromNUKIBridge($hash,"$cmd",undef,$hash->{NUKIID} ) if( !IsDisabled($name) ); + NUKIDevice_ReadFromNUKIBridge($hash,"$cmd",undef,$hash->{NUKIID},$hash->{DEVICETYPE} ) if( !IsDisabled($name) ); return undef; } else { - my $list = "statusRequest:noArg unlock:noArg lock:noArg unlatch:noArg locknGo:noArg locknGoWithUnlatch:noArg unpair:noArg"; + my $list = ''; + + if ( $hash->{DEVICETYPE} == 0 ) { + $list= "statusRequest:noArg unlock:noArg lock:noArg unlatch:noArg locknGo:noArg locknGoWithUnlatch:noArg unpair:noArg"; + } elsif ( $hash->{DEVICETYPE} == 2 ) { + $list= "statusRequest:noArg activateRto:noArg deactivateRto:noArg electricStrikeActuation:noArg activateContinuousMode:noArg deactivateContinuousMode:noArg unpair:noArg"; + } + return "Unknown argument $cmd, choose one of $list"; } $hash->{helper}{lockAction} = $lockAction; - NUKIDevice_ReadFromNUKIBridge($hash,"lockAction",$lockAction,$hash->{NUKIID} ) if( !IsDisabled($name) ); + NUKIDevice_ReadFromNUKIBridge($hash,"lockAction",$lockAction,$hash->{NUKIID},$hash->{DEVICETYPE} ) if( !IsDisabled($name) ); return undef; } @@ -241,7 +249,7 @@ sub NUKIDevice_GetUpdate($) { RemoveInternalTimer($hash); - NUKIDevice_ReadFromNUKIBridge($hash, "lockState", undef, $hash->{NUKIID} ) if( !IsDisabled($name) ); + NUKIDevice_ReadFromNUKIBridge($hash, "lockState", undef, $hash->{NUKIID}, $hash->{DEVICETYPE} ) if( !IsDisabled($name) ); Log3 $name, 5, "NUKIDevice ($name) - NUKIDevice_GetUpdate Call NUKIDevice_ReadFromNUKIBridge" if( !IsDisabled($name) ); return undef; @@ -435,17 +443,19 @@ sub NUKIDevice_WriteReadings($$) {
    NUKIDevice - Controls the Nuki Smartlock
    - The Nuki module connects FHEM over the Nuki Bridge with a Nuki Smartlock. After that, it´s possible to lock and unlock the Smartlock.
    + The Nuki module connects FHEM over the Nuki Bridge with a Nuki Smartlock or Nuki Opener. After that, it´s possible to lock and unlock the Smartlock.
    Normally the Nuki devices are automatically created by the bridge module.

    Define

      - define <name> NUKIDevice <Nuki-Id> <IODev-Device> + define <name> NUKIDevice <Nuki-Id> <IODev-Device> <Device-Type> +

      + Device-Type is 0 for the Smartlock and 2 for the Opener.

      Example:

        - define Frontdoor NUKIDevice 1 NBridge1
        + define Frontdoor NUKIDevice 1 NBridge1 0

      This statement creates a NUKIDevice with the name Frontdoor, the NukiId 1 and the IODev device NBridge1.
      @@ -494,17 +504,19 @@ sub NUKIDevice_WriteReadings($$) {
        NUKIDevice - Steuert das Nuki Smartlock
        - Das Nuki Modul verbindet FHEM über die Nuki Bridge mit einem Nuki Smartlock. Es ist dann möglich das Schloss zu ver- und entriegeln.
        + Das Nuki Modul verbindet FHEM über die Nuki Bridge mit einem Nuki Smartlock oder Nuki Opener. Es ist dann möglich das Schloss zu ver- und entriegeln.
        In der Regel werden die Nuki Devices automatisch durch das Bridgemodul angelegt.

        Define

          - define <name> NUKIDevice <Nuki-Id> <IODev-Device> + define <name> NUKIDevice <Nuki-Id> <IODev-Device> <Device-Type> +

          + Device-Type ist 0 für das Smartlock und 2 f&üuml;r den Opener.

          Beispiel:

            - define Haustür NUKIDevice 1 NBridge1
            + define Haustür NUKIDevice 1 NBridge1 0

          Diese Anweisung erstellt ein NUKIDevice mit Namen Haustür, der NukiId 1 sowie dem IODev Device NBridge1.
          diff --git a/Bridge-API-v1.5.pdf b/Bridge-API-v1.5.pdf deleted file mode 100644 index ac657e8..0000000 Binary files a/Bridge-API-v1.5.pdf and /dev/null differ diff --git a/Bridge-API-v1.9.pdf b/Bridge-API-v1.9.pdf new file mode 100644 index 0000000..f84cb86 Binary files /dev/null and b/Bridge-API-v1.9.pdf differ