Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
8524d188d7 | |||
7c45784c1f | |||
deeecfec7e | |||
298bf70d93 | |||
a95cbbcaba | |||
0caa0ecad3 | |||
d1171bd14a |
@@ -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>"
|
||||||
|
@@ -160,7 +160,6 @@ sub Initialize {
|
|||||||
<li>disable - disables the Nuki device</li>
|
<li>disable - disables the Nuki device</li>
|
||||||
<br>
|
<br>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
=end html
|
=end html
|
||||||
@@ -251,7 +250,6 @@ sub Initialize {
|
|||||||
<li>disable - disables the Nuki device</li>
|
<li>disable - disables the Nuki device</li>
|
||||||
<br>
|
<br>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
=end html_DE
|
=end html_DE
|
||||||
@@ -273,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_11:56:40 10358 FHEM/73_NUKIBridge.pm
|
UPD 2025-10-14_11:00:54 10358 FHEM/73_NUKIBridge.pm
|
||||||
UPD 2021-12-17_11:56:38 11116 FHEM/74_NUKIDevice.pm
|
UPD 2025-10-14_11:00:54 11100 FHEM/74_NUKIDevice.pm
|
||||||
UPD 2021-12-11_19:37:43 42761 lib/FHEM/Devices/Nuki/Bridge.pm
|
UPD 2025-10-14_11:00:54 42820 lib/FHEM/Devices/Nuki/Bridge.pm
|
||||||
UPD 2021-12-11_19:37:43 16338 lib/FHEM/Devices/Nuki/Device.pm
|
UPD 2025-10-15_06:43:51 16775 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;
|
||||||
@@ -54,7 +55,7 @@ BEGIN {
|
|||||||
defs
|
defs
|
||||||
modules
|
modules
|
||||||
data
|
data
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
$list .=
|
}
|
||||||
|
else {
|
||||||
|
my $list = 'info:noArg getDeviceList:noArg ';
|
||||||
|
$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 );
|
||||||
@@ -750,7 +755,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;
|
return $json;
|
||||||
}
|
}
|
||||||
|
|
||||||
::readingsBulkUpdate( $hash, 'lastError',
|
::readingsBulkUpdate( $hash, 'lastError',
|
||||||
@@ -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,8 +28,9 @@ package FHEM::Devices::Nuki::Device;
|
|||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use experimental qw( switch );
|
|
||||||
|
|
||||||
|
#use experimental qw( switch );
|
||||||
|
use Encode;
|
||||||
use FHEM::Meta;
|
use FHEM::Meta;
|
||||||
|
|
||||||
use GPUtils qw(GP_Import);
|
use GPUtils qw(GP_Import);
|
||||||
@@ -41,7 +42,7 @@ BEGIN {
|
|||||||
qw( init_done
|
qw( init_done
|
||||||
defs
|
defs
|
||||||
modules
|
modules
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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,21 +535,23 @@ 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} ) {
|
||||||
::readingsBulkUpdate( $hash, $t, $v )
|
|
||||||
|
# generische readings (alles außer spezielle Felder)
|
||||||
|
::readingsBulkUpdate( $hash, $t,
|
||||||
|
Encode::is_utf8($v) ? Encode::encode( "UTF-8", $v ) : $v )
|
||||||
if ( $t ne 'state'
|
if ( $t ne 'state'
|
||||||
&& $t ne 'mode'
|
&& $t ne 'mode'
|
||||||
&& $t ne 'deviceType'
|
&& $t ne 'deviceType'
|
||||||
@@ -560,42 +563,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 {
|
||||||
}
|
::readingsBulkUpdate( $hash, 'mode',
|
||||||
when ('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