Compare commits
	
		
			2 Commits
		
	
	
		
			298bf70d93
			...
			7c45784c1f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7c45784c1f | |||
| deeecfec7e | 
@@ -267,7 +267,7 @@ sub Initialize {
 | 
				
			|||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "release_status": "stable",
 | 
					  "release_status": "stable",
 | 
				
			||||||
  "license": "GPL_2",
 | 
					  "license": "GPL_2",
 | 
				
			||||||
  "version": "v2.0.2",
 | 
					  "version": "v2.1.0",
 | 
				
			||||||
  "x_apiversion": "1.13.0",
 | 
					  "x_apiversion": "1.13.0",
 | 
				
			||||||
  "author": [
 | 
					  "author": [
 | 
				
			||||||
    "Marko Oldenburg <leongaultier@gmail.com>"
 | 
					    "Marko Oldenburg <leongaultier@gmail.com>"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -271,7 +271,7 @@ sub Initialize {
 | 
				
			|||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "release_status": "stable",
 | 
					  "release_status": "stable",
 | 
				
			||||||
  "license": "GPL_2",
 | 
					  "license": "GPL_2",
 | 
				
			||||||
  "version": "v2.0.2",
 | 
					  "version": "v2.1.0",
 | 
				
			||||||
  "author": [
 | 
					  "author": [
 | 
				
			||||||
    "Marko Oldenburg <leongaultier@gmail.com>"
 | 
					    "Marko Oldenburg <leongaultier@gmail.com>"
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
UPD 2021-12-17_12:18:33 10358 FHEM/73_NUKIBridge.pm
 | 
					UPD 2025-10-14_10:40:53 10358 FHEM/73_NUKIBridge.pm
 | 
				
			||||||
UPD 2021-12-17_12:44:59 11100 FHEM/74_NUKIDevice.pm
 | 
					UPD 2025-10-14_10:41:09 11100 FHEM/74_NUKIDevice.pm
 | 
				
			||||||
UPD 2022-09-26_11:59:12 42767 lib/FHEM/Devices/Nuki/Bridge.pm
 | 
					UPD 2025-10-14_10:42:11 42820 lib/FHEM/Devices/Nuki/Bridge.pm
 | 
				
			||||||
UPD 2021-12-17_12:18:33 16338 lib/FHEM/Devices/Nuki/Device.pm
 | 
					UPD 2025-10-14_10:42:04 16698 lib/FHEM/Devices/Nuki/Device.pm
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,8 @@ package FHEM::Devices::Nuki::Bridge;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use strict;
 | 
					use strict;
 | 
				
			||||||
use warnings;
 | 
					use warnings;
 | 
				
			||||||
use experimental qw( switch );
 | 
					
 | 
				
			||||||
 | 
					#use experimental qw( switch );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use FHEM::Meta;
 | 
					use FHEM::Meta;
 | 
				
			||||||
use HttpUtils;
 | 
					use HttpUtils;
 | 
				
			||||||
@@ -422,59 +423,59 @@ sub Set {
 | 
				
			|||||||
    my $endpoint;
 | 
					    my $endpoint;
 | 
				
			||||||
    my $param;
 | 
					    my $param;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $cmd = lc($cmd);
 | 
					    $cmd = lc $cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    given ($cmd) {
 | 
					    my %handlers = (
 | 
				
			||||||
        when ('getdevicelist') {
 | 
					        getdevicelist => sub {
 | 
				
			||||||
            return 'usage: getDeviceList' if ($arg);
 | 
					            return 'usage: getDeviceList' if $arg;
 | 
				
			||||||
            $endpoint = 'list';
 | 
					            $endpoint = 'list';
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
        when ('info') {
 | 
					        info => sub {
 | 
				
			||||||
            return 'usage: info' if ($arg);
 | 
					            return 'usage: info' if $arg;
 | 
				
			||||||
            $endpoint = 'info';
 | 
					            $endpoint = 'info';
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
        when ('fwupdate') {
 | 
					        fwupdate => sub {
 | 
				
			||||||
            return 'usage: fwUpdate' if ($arg);
 | 
					            return 'usage: fwUpdate' if $arg;
 | 
				
			||||||
            $endpoint = 'fwupdate';
 | 
					            $endpoint = 'fwupdate';
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
        when ('reboot') {
 | 
					        reboot => sub {
 | 
				
			||||||
            return 'usage: freboot' if ($arg);
 | 
					            return 'usage: reboot' if $arg;
 | 
				
			||||||
            $endpoint = 'reboot';
 | 
					            $endpoint = 'reboot';
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
        when ('clearlog') {
 | 
					        clearlog => sub {
 | 
				
			||||||
            return 'usage: clearLog' if ($arg);
 | 
					            return 'usage: clearLog' if $arg;
 | 
				
			||||||
            $endpoint = 'clearlog';
 | 
					            $endpoint = 'clearlog';
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
        when ('factoryreset') {
 | 
					        factoryreset => sub {
 | 
				
			||||||
            return 'usage: factoryReset' if ($arg);
 | 
					            return 'usage: factoryReset' if $arg;
 | 
				
			||||||
            $endpoint = 'factoryreset';
 | 
					            $endpoint = 'factoryreset';
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
 | 
					        callbackremove => sub {
 | 
				
			||||||
        when ('callbackremove') {
 | 
					 | 
				
			||||||
            return 'usage: callbackRemove'
 | 
					            return 'usage: callbackRemove'
 | 
				
			||||||
              if ( split( m{\s+}xms, $arg ) > 1 );
 | 
					              if ( split( m{\s+}xms, $arg ) > 1 );
 | 
				
			||||||
            my $id = ( defined($arg) ? $arg : 0 );
 | 
					            my $id = defined $arg ? $arg : 0;
 | 
				
			||||||
            $endpoint = 'callback/remove';
 | 
					            $endpoint = 'callback/remove';
 | 
				
			||||||
            $param    = '{"param":"' . $id . '"}';
 | 
					            $param    = '{"param":"' . $id . '"}';
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
 | 
					        configauth => sub {
 | 
				
			||||||
        when ('configauth') {
 | 
					            return 'usage: configAuth'
 | 
				
			||||||
            return 'usage: configAuth' if ( split( m{\s+}xms, $arg ) > 1 );
 | 
					              if ( split( m{\s+}xms, $arg ) > 1 );
 | 
				
			||||||
            $endpoint = 'clearlog';
 | 
					 | 
				
			||||||
            my $configAuth = 'enable=' . ( $arg eq 'enable' ? 1 : 0 );
 | 
					            my $configAuth = 'enable=' . ( $arg eq 'enable' ? 1 : 0 );
 | 
				
			||||||
            $endpoint = 'configAuth';
 | 
					            $endpoint = 'configAuth';
 | 
				
			||||||
            $param    = '{"param":"' . $configAuth . '"}';
 | 
					            $param    = '{"param":"' . $configAuth . '"}';
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        default {
 | 
					    if ( exists $handlers{$cmd} ) {
 | 
				
			||||||
            my $list = '';
 | 
					        my $result = $handlers{$cmd}->();
 | 
				
			||||||
            $list .= 'info:noArg getDeviceList:noArg ';
 | 
					        return $result if defined $result && length $result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        my $list = 'info:noArg getDeviceList:noArg ';
 | 
				
			||||||
        $list .=
 | 
					        $list .=
 | 
				
			||||||
'clearLog:noArg fwUpdate:noArg reboot:noArg factoryReset:noArg configAuth:enable,disable'
 | 
					'clearLog:noArg fwUpdate:noArg reboot:noArg factoryReset:noArg configAuth:enable,disable'
 | 
				
			||||||
              if ( ::ReadingsVal( $name, 'bridgeType', 'Software' ) eq
 | 
					          if ( ::ReadingsVal( $name, 'bridgeType', 'Software' ) eq 'Hardware' );
 | 
				
			||||||
                'Hardware' );
 | 
					        return "Unknown argument $cmd, choose one of $list";
 | 
				
			||||||
            return ( 'Unknown argument ' . $cmd . ', choose one of ' . $list );
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Write( $hash, $endpoint, $param )
 | 
					    Write( $hash, $endpoint, $param )
 | 
				
			||||||
@@ -486,30 +487,34 @@ sub Set {
 | 
				
			|||||||
sub Get {
 | 
					sub Get {
 | 
				
			||||||
    my $hash = shift;
 | 
					    my $hash = shift;
 | 
				
			||||||
    my $name = shift;
 | 
					    my $name = shift;
 | 
				
			||||||
    my $cmd  = shift // return "set $name needs at least one argument !";
 | 
					    my $cmd  = shift // return "get $name needs at least one argument !";
 | 
				
			||||||
    my $arg  = shift;
 | 
					    my $arg  = shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    my $endpoint;
 | 
					    my $endpoint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $cmd = lc($cmd);
 | 
					    $cmd = lc $cmd;
 | 
				
			||||||
    given ($cmd) {
 | 
					 | 
				
			||||||
        when ( $cmd eq 'logfile' ) {
 | 
					 | 
				
			||||||
            return 'usage: logFile' if ( defined($arg) );
 | 
					 | 
				
			||||||
            $endpoint = 'log';
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        when ( $cmd eq 'callbacklist' ) {
 | 
					 | 
				
			||||||
            return 'usage: callbackList' if ( defined($arg) );
 | 
					 | 
				
			||||||
            $endpoint = 'callback/list';
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        default {
 | 
					 | 
				
			||||||
            my $list = '';
 | 
					 | 
				
			||||||
            $list .= 'callbackList:noArg ';
 | 
					 | 
				
			||||||
            $list .= 'logFile:noArg'
 | 
					 | 
				
			||||||
              if ( ::ReadingsVal( $name, 'bridgeType', 'Software' ) eq
 | 
					 | 
				
			||||||
                'Hardware' );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return 'Unknown argument ' . $cmd . ', choose one of ' . $list;
 | 
					    my %handlers = (
 | 
				
			||||||
 | 
					        logfile => sub {
 | 
				
			||||||
 | 
					            return 'usage: logFile' if defined $arg;
 | 
				
			||||||
 | 
					            $endpoint = 'log';
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        callbacklist => sub {
 | 
				
			||||||
 | 
					            return 'usage: callbackList' if defined $arg;
 | 
				
			||||||
 | 
					            $endpoint = 'callback/list';
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( exists $handlers{$cmd} ) {
 | 
				
			||||||
 | 
					        my $result = $handlers{$cmd}->();
 | 
				
			||||||
 | 
					        return $result if defined $result && length $result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        my $list = 'callbackList:noArg ';
 | 
				
			||||||
 | 
					        $list .= 'logFile:noArg'
 | 
				
			||||||
 | 
					          if ( ::ReadingsVal( $name, 'bridgeType', 'Software' ) eq 'Hardware' );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return "Unknown argument $cmd, choose one of $list";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Write( $hash, $endpoint, undef );
 | 
					    return Write( $hash, $endpoint, undef );
 | 
				
			||||||
@@ -765,7 +770,7 @@ sub DistributionErrHandle2 {
 | 
				
			|||||||
        ::asyncOutput( $param->{cl}, "Request Error: $err\r\n" )
 | 
					        ::asyncOutput( $param->{cl}, "Request Error: $err\r\n" )
 | 
				
			||||||
          if ( $param->{cl} && $param->{cl}{canAsyncOutput} );
 | 
					          if ( $param->{cl} && $param->{cl}{canAsyncOutput} );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return ('received http code '
 | 
					        return ( 'received http code '
 | 
				
			||||||
              . $param->{code}
 | 
					              . $param->{code}
 | 
				
			||||||
              . ' without any data after requesting' );
 | 
					              . ' without any data after requesting' );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,8 @@ package FHEM::Devices::Nuki::Device;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use strict;
 | 
					use strict;
 | 
				
			||||||
use warnings;
 | 
					use warnings;
 | 
				
			||||||
use experimental qw( switch );
 | 
					
 | 
				
			||||||
 | 
					#use experimental qw( switch );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use FHEM::Meta;
 | 
					use FHEM::Meta;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -355,7 +356,7 @@ sub Set {
 | 
				
			|||||||
        GetUpdate($hash);
 | 
					        GetUpdate($hash);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    elsif ($cmd eq 'lock'
 | 
					    elsif ( $cmd eq 'lock'
 | 
				
			||||||
        || lc($cmd) eq 'deactivaterto'
 | 
					        || lc($cmd) eq 'deactivaterto'
 | 
				
			||||||
        || $cmd eq 'unlock'
 | 
					        || $cmd eq 'unlock'
 | 
				
			||||||
        || lc($cmd) eq 'activaterto'
 | 
					        || lc($cmd) eq 'activaterto'
 | 
				
			||||||
@@ -534,20 +535,21 @@ sub WriteReadings {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    ::readingsBeginUpdate($hash);
 | 
					    ::readingsBeginUpdate($hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    my $t;
 | 
					    my ( $t, $v );
 | 
				
			||||||
    my $v;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( defined( $decode_json->{lastKnownState} )
 | 
					    # falls lastKnownState als Hash vorliegt, direkt integrieren
 | 
				
			||||||
 | 
					    if ( defined $decode_json->{lastKnownState}
 | 
				
			||||||
        && ref( $decode_json->{lastKnownState} ) eq 'HASH' )
 | 
					        && ref( $decode_json->{lastKnownState} ) eq 'HASH' )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        while ( ( $t, $v ) = each %{ $decode_json->{lastKnownState} } ) {
 | 
					        while ( ( $t, $v ) = each %{ $decode_json->{lastKnownState} } ) {
 | 
				
			||||||
            $decode_json->{$t} = $v;
 | 
					            $decode_json->{$t} = $v;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        delete $decode_json->{lastKnownState};
 | 
					        delete $decode_json->{lastKnownState};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while ( ( $t, $v ) = each %{$decode_json} ) {
 | 
					    while ( ( $t, $v ) = each %{$decode_json} ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # generische readings (alles außer spezielle Felder)
 | 
				
			||||||
        ::readingsBulkUpdate( $hash, $t, $v )
 | 
					        ::readingsBulkUpdate( $hash, $t, $v )
 | 
				
			||||||
          if ( $t ne 'state'
 | 
					          if ( $t ne 'state'
 | 
				
			||||||
            && $t ne 'mode'
 | 
					            && $t ne 'mode'
 | 
				
			||||||
@@ -560,42 +562,48 @@ sub WriteReadings {
 | 
				
			|||||||
            && $t ne 'doorsensorState'
 | 
					            && $t ne 'doorsensorState'
 | 
				
			||||||
            && $t ne 'doorsensorStateName' );
 | 
					            && $t ne 'doorsensorStateName' );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        given ($t) {
 | 
					        # Dispatch-Tabelle für Spezialfälle
 | 
				
			||||||
            when ('state') {
 | 
					        my %handlers = (
 | 
				
			||||||
                ::readingsBulkUpdate(
 | 
					            state => sub {
 | 
				
			||||||
                    $hash, $t,
 | 
					                my $val =
 | 
				
			||||||
                    (
 | 
					                  ( $v =~ m{\A[0-9]\z}xms )
 | 
				
			||||||
                          $v =~ m{\A[0-9]\z}xms
 | 
					 | 
				
			||||||
                  ? $lockStates{$v}->{ $hash->{DEVICETYPEID} }
 | 
					                  ? $lockStates{$v}->{ $hash->{DEVICETYPEID} }
 | 
				
			||||||
                        : $v
 | 
					                  : $v;
 | 
				
			||||||
                    )
 | 
					                ::readingsBulkUpdate( $hash, 'state', $val );
 | 
				
			||||||
                );
 | 
					            },
 | 
				
			||||||
            }
 | 
					            mode => sub {
 | 
				
			||||||
            when ('mode') {
 | 
					                ::readingsBulkUpdate( $hash, 'mode',
 | 
				
			||||||
                ::readingsBulkUpdate( $hash, $t,
 | 
					 | 
				
			||||||
                    $modes{$v}{ $hash->{DEVICETYPEID} } );
 | 
					                    $modes{$v}{ $hash->{DEVICETYPEID} } );
 | 
				
			||||||
            }
 | 
					            },
 | 
				
			||||||
            when ('deviceType') {
 | 
					            devicetype => sub {
 | 
				
			||||||
                ::readingsBulkUpdate( $hash, $t, $deviceTypes{$v} );
 | 
					                ::readingsBulkUpdate( $hash, 'deviceType', $deviceTypes{$v} );
 | 
				
			||||||
            }
 | 
					            },
 | 
				
			||||||
            when ('doorsensorState') {
 | 
					            doorsensorstate => sub {
 | 
				
			||||||
                ::readingsBulkUpdate( $hash, $t, $doorsensorStates{$v} );
 | 
					                ::readingsBulkUpdate( $hash, 'doorsensorState',
 | 
				
			||||||
            }
 | 
					                    $doorsensorStates{$v} );
 | 
				
			||||||
            when ('paired') {
 | 
					            },
 | 
				
			||||||
                ::readingsBulkUpdate( $hash, $t,
 | 
					            paired => sub {
 | 
				
			||||||
 | 
					                ::readingsBulkUpdate( $hash, 'paired',
 | 
				
			||||||
                    ( $v == 1 ? 'true' : 'false' ) );
 | 
					                    ( $v == 1 ? 'true' : 'false' ) );
 | 
				
			||||||
            }
 | 
					            },
 | 
				
			||||||
            when ('batteryCharging') {
 | 
					            batterycharging => sub {
 | 
				
			||||||
                ::readingsBulkUpdate( $hash, $t,
 | 
					                ::readingsBulkUpdate( $hash, 'batteryCharging',
 | 
				
			||||||
                    ( $v == 1 ? 'true' : 'false' ) );
 | 
					                    ( $v == 1 ? 'true' : 'false' ) );
 | 
				
			||||||
            }
 | 
					            },
 | 
				
			||||||
            when ('batteryCritical') {
 | 
					            batterycritical => sub {
 | 
				
			||||||
                ::readingsBulkUpdate( $hash, 'batteryState',
 | 
					                ::readingsBulkUpdate( $hash, 'batteryState',
 | 
				
			||||||
                    ( $v == 1 ? 'low' : 'ok' ) );
 | 
					                    ( $v == 1 ? 'low' : 'ok' ) );
 | 
				
			||||||
            }
 | 
					            },
 | 
				
			||||||
            when ('batteryChargeState') {
 | 
					            batterychargestate => sub {
 | 
				
			||||||
                ::readingsBulkUpdate( $hash, 'batteryPercent', $v )
 | 
					                ::readingsBulkUpdate( $hash, 'batteryPercent', $v );
 | 
				
			||||||
            }
 | 
					            },
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        my $key =
 | 
				
			||||||
 | 
					          lc $t;    # damit Vergleiche robust gegen Groß-/Kleinschreibung sind
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ( exists $handlers{$key} ) {
 | 
				
			||||||
 | 
					            $handlers{$key}->();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user