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