74_NUKIDevice.pm 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. ###############################################################################
  2. #
  3. # Developed with Kate
  4. #
  5. # (c) 2016-2017 Copyright: Marko Oldenburg (leongaultier at gmail dot com)
  6. # All rights reserved
  7. #
  8. # This script is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # any later version.
  12. #
  13. # The GNU General Public License can be found at
  14. # http://www.gnu.org/copyleft/gpl.html.
  15. # A copy is found in the textfile GPL.txt and important notices to the license
  16. # from the author is found in LICENSE.txt distributed with these scripts.
  17. #
  18. # This script is distributed in the hope that it will be useful,
  19. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. # GNU General Public License for more details.
  22. #
  23. #
  24. # $Id: 74_NUKIDevice.pm 16973 2018-07-11 10:48:36Z CoolTux $
  25. #
  26. ###############################################################################
  27. package main;
  28. use strict;
  29. use warnings;
  30. use JSON;
  31. my $version = "0.6.3";
  32. # Declare functions
  33. sub NUKIDevice_Initialize($);
  34. sub NUKIDevice_Define($$);
  35. sub NUKIDevice_Undef($$);
  36. sub NUKIDevice_Attr(@);
  37. sub NUKIDevice_addExtension($$$);
  38. sub NUKIDevice_removeExtension($);
  39. sub NUKIDevice_Set($$@);
  40. sub NUKIDevice_GetUpdate($);
  41. sub NUKIDevice_ReadFromNUKIBridge($@);
  42. sub NUKIDevice_Parse($$);
  43. sub NUKIDevice_WriteReadings($$);
  44. sub NUKIDevice_CGI();
  45. sub NUKIDevice_Initialize($) {
  46. my ($hash) = @_;
  47. $hash->{SetFn} = "NUKIDevice_Set";
  48. $hash->{DefFn} = "NUKIDevice_Define";
  49. $hash->{UndefFn} = "NUKIDevice_Undef";
  50. $hash->{AttrFn} = "NUKIDevice_Attr";
  51. my $webhookFWinstance = join( ",", devspec2array('TYPE=FHEMWEB:FILTER=TEMPORARY!=1') );
  52. $hash->{AttrList} = "IODev ".
  53. "disable:1 ".
  54. "webhookFWinstance:$webhookFWinstance ".
  55. "webhookHttpHostname ".
  56. $readingFnAttributes;
  57. foreach my $d(sort keys %{$modules{NUKIDevice}{defptr}}) {
  58. my $hash = $modules{NUKIDevice}{defptr}{$d};
  59. $hash->{VERSION} = $version;
  60. }
  61. }
  62. sub NUKIDevice_Define($$) {
  63. my ( $hash, $def ) = @_;
  64. my @a = split( "[ \t]+", $def );
  65. splice( @a, 1, 1 );
  66. my $iodev;
  67. my $i = 0;
  68. foreach my $param ( @a ) {
  69. if( $param =~ m/IODev=([^\s]*)/ ) {
  70. $iodev = $1;
  71. splice( @a, $i, 3 );
  72. last;
  73. }
  74. $i++;
  75. }
  76. return "too few parameters: define <name> NUKIDevice <nukiId>" if( @a < 2 );
  77. my ($name,$nukiId) = @a;
  78. $hash->{NUKIID} = $nukiId;
  79. $hash->{VERSION} = $version;
  80. $hash->{STATE} = 'Initialized';
  81. my $infix = "NUKIDevice";
  82. AssignIoPort($hash,$iodev) if( !$hash->{IODev} );
  83. if(defined($hash->{IODev}->{NAME})) {
  84. Log3 $name, 3, "NUKIDevice ($name) - I/O device is " . $hash->{IODev}->{NAME};
  85. } else {
  86. Log3 $name, 1, "NUKIDevice ($name) - no I/O device";
  87. }
  88. $iodev = $hash->{IODev}->{NAME};
  89. my $code = $hash->{NUKIID};
  90. $code = $iodev ."-". $code if( defined($iodev) );
  91. my $d = $modules{NUKIDevice}{defptr}{$code};
  92. return "NUKIDevice device $hash->{NUKIID} on NUKIBridge $iodev already defined as $d->{NAME}."
  93. if( defined($d)
  94. && $d->{IODev} == $hash->{IODev}
  95. && $d->{NAME} ne $name );
  96. $modules{NUKIDevice}{defptr}{$code} = $hash;
  97. Log3 $name, 3, "NUKIDevice ($name) - defined with Code: $code";
  98. Log3 $name, 1, "NUKIDevice ($name) - reading battery a deprecated and will be remove in future";
  99. $attr{$name}{room} = "NUKI" if( !defined( $attr{$name}{room} ) );
  100. if ( NUKIDevice_addExtension( $name, "NUKIDevice_CGI", $infix ) ) {
  101. $hash->{fhem}{infix} = $infix;
  102. }
  103. $hash->{WEBHOOK_REGISTER} = "unregistered";
  104. if( $init_done ) {
  105. InternalTimer( gettimeofday()+int(rand(10)), "NUKIDevice_GetUpdate", $hash, 0 );
  106. } else {
  107. InternalTimer( gettimeofday()+15+int(rand(5)), "NUKIDevice_GetUpdate", $hash, 0 );
  108. }
  109. return undef;
  110. }
  111. sub NUKIDevice_Undef($$) {
  112. my ( $hash, $arg ) = @_;
  113. my $nukiId = $hash->{NUKIID};
  114. my $name = $hash->{NAME};
  115. if ( defined( $hash->{fhem}{infix} ) ) {
  116. NUKIDevice_removeExtension( $hash->{fhem}{infix} );
  117. }
  118. RemoveInternalTimer($hash);
  119. my $code = $hash->{NUKIID};
  120. $code = $hash->{IODev}->{NAME} ."-". $code if( defined($hash->{IODev}->{NAME}) );
  121. Log3 $name, 3, "NUKIDevice ($name) - undefined with Code: $code";
  122. delete($modules{NUKIDevice}{defptr}{$code});
  123. return undef;
  124. }
  125. sub NUKIDevice_Attr(@) {
  126. my ( $cmd, $name, $attrName, $attrVal ) = @_;
  127. my $hash = $defs{$name};
  128. my $token = $hash->{IODev}->{TOKEN};
  129. if( $attrName eq "disable" ) {
  130. if( $cmd eq "set" and $attrVal eq "1" ) {
  131. readingsSingleUpdate ( $hash, "state", "disabled", 1 );
  132. Log3 $name, 3, "NUKIDevice ($name) - disabled";
  133. }
  134. elsif( $cmd eq "del" ) {
  135. readingsSingleUpdate ( $hash, "state", "active", 1 );
  136. Log3 $name, 3, "NUKIDevice ($name) - enabled";
  137. }
  138. }
  139. if( $attrName eq "disabledForIntervals" ) {
  140. if( $cmd eq "set" ) {
  141. Log3 $name, 3, "NUKIDevice ($name) - enable disabledForIntervals";
  142. readingsSingleUpdate ( $hash, "state", "Unknown", 1 );
  143. }
  144. elsif( $cmd eq "del" ) {
  145. readingsSingleUpdate ( $hash, "state", "active", 1 );
  146. Log3 $name, 3, "NUKIDevice ($name) - delete disabledForIntervals";
  147. }
  148. }
  149. ######################
  150. #### webhook #########
  151. return "Invalid value for attribute $attrName: can only by FQDN or IPv4 or IPv6 address" if ( $attrVal && $attrName eq "webhookHttpHostname" && $attrVal !~ /^([A-Za-z_.0-9]+\.[A-Za-z_.0-9]+)|[0-9:]+$/ );
  152. return "Invalid value for attribute $attrName: FHEMWEB instance $attrVal not existing" if ( $attrVal && $attrName eq "webhookFWinstance" && ( !defined( $defs{$attrVal} ) || $defs{$attrVal}{TYPE} ne "FHEMWEB" ) );
  153. return "Invalid value for attribute $attrName: needs to be an integer value" if ( $attrVal && $attrName eq "webhookPort" && $attrVal !~ /^\d+$/ );
  154. if ( $attrName =~ /^webhook.*/ ) {
  155. my $webhookHttpHostname = ( $attrName eq "webhookHttpHostname" ? $attrVal : AttrVal( $name, "webhookHttpHostname", "" ) );
  156. my $webhookFWinstance = ( $attrName eq "webhookFWinstance" ? $attrVal : AttrVal( $name, "webhookFWinstance", "" ) );
  157. $hash->{WEBHOOK_URI} = "/" . AttrVal( $webhookFWinstance, "webname", "fhem" ) . "/NUKIDevice";
  158. $hash->{WEBHOOK_PORT} = ( $attrName eq "webhookPort" ? $attrVal : AttrVal( $name, "webhookPort", InternalVal( $webhookFWinstance, "PORT", "" )) );
  159. $hash->{WEBHOOK_URL} = "";
  160. $hash->{WEBHOOK_COUNTER} = "0";
  161. if ( $webhookHttpHostname ne "" && $hash->{WEBHOOK_PORT} ne "" ) {
  162. $hash->{WEBHOOK_URL} = "http://" . $webhookHttpHostname . ":" . $hash->{WEBHOOK_PORT} . $hash->{WEBHOOK_URI} . "-" . $hash->{NUKIID};
  163. my $url = "http://$webhookHttpHostname" . ":" . $hash->{WEBHOOK_PORT} . $hash->{WEBHOOK_URI} . "-" . $hash->{NUKIID};
  164. Log3 $name, 3, "NUKIDevice ($name) - URL ist: $url";
  165. NUKIDevice_ReadFromNUKIBridge($hash,"callback/add",$url,undef ) if( $init_done );
  166. $hash->{WEBHOOK_REGISTER} = "sent";
  167. } else {
  168. $hash->{WEBHOOK_REGISTER} = "incomplete_attributes";
  169. }
  170. }
  171. return undef;
  172. }
  173. sub NUKIDevice_addExtension($$$) {
  174. my ( $name, $func, $link ) = @_;
  175. my $url = "/$link";
  176. return 0 if ( defined( $data{FWEXT}{$url} ) && $data{FWEXT}{$url}{deviceName} ne $name );
  177. Log3 $name, 2, "NUKIDevice ($name) - Registering NUKIDevice for webhook URI $url ...";
  178. $data{FWEXT}{$url}{deviceName} = $name;
  179. $data{FWEXT}{$url}{FUNC} = $func;
  180. $data{FWEXT}{$url}{LINK} = $link;
  181. return 1;
  182. }
  183. sub NUKIDevice_removeExtension($) {
  184. my ($link) = @_;
  185. my $url = "/$link";
  186. my $name = $data{FWEXT}{$url}{deviceName};
  187. Log3 $name, 2, "NUKIDevice ($name) - Unregistering NUKIDevice for webhook URL $url...";
  188. delete $data{FWEXT}{$url};
  189. }
  190. sub NUKIDevice_Set($$@) {
  191. my ($hash, $name, @aa) = @_;
  192. my ($cmd, @args) = @aa;
  193. my $lockAction;
  194. if( $cmd eq 'statusRequest' ) {
  195. return "usage: statusRequest" if( @args != 0 );
  196. NUKIDevice_GetUpdate($hash);
  197. return undef;
  198. } elsif( $cmd eq 'lock' ) {
  199. $lockAction = $cmd;
  200. } elsif( $cmd eq 'unlock' ) {
  201. $lockAction = $cmd;
  202. } elsif( $cmd eq 'unlatch' ) {
  203. $lockAction = $cmd;
  204. } elsif( $cmd eq 'locknGo' ) {
  205. $lockAction = $cmd;
  206. } elsif( $cmd eq 'locknGoWithUnlatch' ) {
  207. $lockAction = $cmd;
  208. } elsif( $cmd eq 'unpair' ) {
  209. NUKIDevice_ReadFromNUKIBridge($hash,"$cmd",undef,$hash->{NUKIID} ) if( !IsDisabled($name) );
  210. return undef;
  211. } else {
  212. my $list = "statusRequest:noArg unlock:noArg lock:noArg unlatch:noArg locknGo:noArg locknGoWithUnlatch:noArg unpair:noArg";
  213. return "Unknown argument $cmd, choose one of $list";
  214. }
  215. $hash->{helper}{lockAction} = $lockAction;
  216. NUKIDevice_ReadFromNUKIBridge($hash,"lockAction",$lockAction,$hash->{NUKIID} ) if( !IsDisabled($name) );
  217. return undef;
  218. }
  219. sub NUKIDevice_GetUpdate($) {
  220. my ($hash) = @_;
  221. my $name = $hash->{NAME};
  222. RemoveInternalTimer($hash);
  223. NUKIDevice_ReadFromNUKIBridge($hash, "lockState", undef, $hash->{NUKIID} ) if( !IsDisabled($name) );
  224. Log3 $name, 5, "NUKIDevice ($name) - NUKIDevice_GetUpdate Call NUKIDevice_ReadFromNUKIBridge" if( !IsDisabled($name) );
  225. return undef;
  226. }
  227. sub NUKIDevice_ReadFromNUKIBridge($@) {
  228. my ($hash,@a) = @_;
  229. my $name = $hash->{NAME};
  230. Log3 $name, 4, "NUKIDevice ($name) - NUKIDevice_ReadFromNUKIBridge check Bridge connected";
  231. return "IODev $hash->{IODev} is not connected" if( ReadingsVal($hash->{IODev}->{NAME},"state","not connected") eq "not connected" );
  232. no strict "refs";
  233. my $ret;
  234. unshift(@a,$name);
  235. Log3 $name, 4, "NUKIDevice ($name) - NUKIDevice_ReadFromNUKIBridge Bridge is connected call IOWrite";
  236. $ret = IOWrite($hash,$hash,@a);
  237. use strict "refs";
  238. return $ret;
  239. return if(IsDummy($name) || IsIgnored($name));
  240. my $iohash = $hash->{IODev};
  241. if(!$iohash ||
  242. !$iohash->{TYPE} ||
  243. !$modules{$iohash->{TYPE}} ||
  244. !$modules{$iohash->{TYPE}}{ReadFn}) {
  245. Log3 $name, 3, "NUKIDevice ($name) - No I/O device or ReadFn found for $name";
  246. return;
  247. }
  248. no strict "refs";
  249. unshift(@a,$name);
  250. $ret = &{$modules{$iohash->{TYPE}}{ReadFn}}($iohash, @a);
  251. use strict "refs";
  252. return $ret;
  253. }
  254. sub NUKIDevice_Parse($$) {
  255. my($hash,$result) = @_;
  256. my $name = $hash->{NAME};
  257. Log3 $name, 5, "NUKIDevice ($name) - Parse with result: $result";
  258. #########################################
  259. ####### Errorhandling #############
  260. if( !$result ) {
  261. Log3 $name, 3, "NUKIDevice ($name) - empty answer received";
  262. return undef;
  263. } elsif( $result =~ m'HTTP/1.1 200 OK' ) {
  264. Log3 $name, 4, "NUKIDevice ($name) - empty answer received";
  265. return undef;
  266. } elsif( $result !~ m/^[\[{].*[}\]]$/ ) {
  267. Log3 $name, 3, "NUKIDevice ($name) - invalid json detected: $result";
  268. return "NUKIDevice ($name) - invalid json detected: $result";
  269. }
  270. if( $result =~ /\d{3}/ ) {
  271. if( $result eq 400 ) {
  272. readingsSingleUpdate( $hash, "state", "action is undefined", 1 );
  273. Log3 $name, 3, "NUKIDevice ($name) - action is undefined";
  274. return;
  275. }
  276. if( $result eq 404 ) {
  277. readingsSingleUpdate( $hash, "state", "nukiId is not known", 1 );
  278. Log3 $name, 3, "NUKIDevice ($name) - nukiId is not known";
  279. return;
  280. }
  281. if( $result eq 503 ) {
  282. readingsSingleUpdate( $hash, "state", "smartlock is offline", 1 );
  283. Log3 $name, 3, "NUKIDevice ($name) - smartlock is offline";
  284. return;
  285. }
  286. }
  287. #########################################
  288. #### verarbeiten des JSON Strings #######
  289. my $decode_json = eval{decode_json($result)};
  290. if($@){
  291. Log3 $name, 3, "NUKIDevice ($name) - JSON error while request: $@";
  292. return;
  293. }
  294. if( ref($decode_json) ne "HASH" ) {
  295. Log3 $name, 2, "NUKIDevice ($name) - got wrong status message for $name: $decode_json";
  296. return undef;
  297. }
  298. Log3 $name, 5, "NUKIDevice ($name) - parse status message for $name";
  299. NUKIDevice_WriteReadings($hash,$decode_json);
  300. }
  301. sub NUKIDevice_WriteReadings($$) {
  302. my ($hash,$decode_json) = @_;
  303. my $name = $hash->{NAME};
  304. ############################
  305. #### Status des Smartlock
  306. my $battery;
  307. if( defined($decode_json->{batteryCritical}) ) {
  308. if( $decode_json->{batteryCritical} eq "false" or $decode_json->{batteryCritical} == 0 ) {
  309. $battery = "ok";
  310. } elsif ( $decode_json->{batteryCritical} eq "true" or $decode_json->{batteryCritical} == 1 ) {
  311. $battery = "low";
  312. }
  313. }
  314. readingsBeginUpdate($hash);
  315. if( defined($hash->{helper}{lockAction}) ) {
  316. my ($state,$lockState);
  317. if( defined($decode_json->{success}) and ($decode_json->{success} eq "true" or $decode_json->{success} eq "1") ) {
  318. $state = $hash->{helper}{lockAction};
  319. $lockState = $hash->{helper}{lockAction};
  320. NUKIDevice_ReadFromNUKIBridge($hash, "lockState", undef, $hash->{NUKIID} ) if( ReadingsVal($hash->{IODev}->{NAME},'bridgeType','Software') eq 'Software' );
  321. } elsif ( defined($decode_json->{success}) and ($decode_json->{success} eq "false" or $decode_json->{success} eq "0") ) {
  322. $state = "error";
  323. NUKIDevice_ReadFromNUKIBridge($hash, "lockState", undef, $hash->{NUKIID} );
  324. }
  325. readingsBulkUpdate( $hash, "state", $state );
  326. readingsBulkUpdate( $hash, "lockState", $lockState );
  327. readingsBulkUpdate( $hash, "success", $decode_json->{success} );
  328. delete $hash->{helper}{lockAction};
  329. Log3 $name, 5, "NUKIDevice ($name) - lockAction readings set for $name";
  330. } else {
  331. readingsBulkUpdate( $hash, "batteryCritical", $decode_json->{batteryCritical} );
  332. readingsBulkUpdate( $hash, "lockState", $decode_json->{stateName} );
  333. readingsBulkUpdate( $hash, "state", $decode_json->{stateName} );
  334. readingsBulkUpdate( $hash, "battery", $battery );
  335. readingsBulkUpdate( $hash, "batteryState", $battery );
  336. readingsBulkUpdate( $hash, "success", $decode_json->{success} );
  337. readingsBulkUpdate( $hash, "name", $decode_json->{name} );
  338. readingsBulkUpdate( $hash, "rssi", $decode_json->{rssi} );
  339. readingsBulkUpdate( $hash, "paired", $decode_json->{paired} );
  340. Log3 $name, 5, "NUKIDevice ($name) - readings set for $name";
  341. }
  342. readingsEndUpdate( $hash, 1 );
  343. return undef;
  344. }
  345. sub NUKIDevice_CGI() {
  346. my ($request) = @_;
  347. my $hash;
  348. my $name;
  349. my $nukiId;
  350. # data received
  351. # Testaufruf:
  352. # curl --data '{"nukiId": 123456, "state": 1,"stateName": "locked", "batteryCritical": false}' http://10.6.6.20:8083/fhem/NUKIDevice-123456
  353. # wget --post-data '{"nukiId": 123456, "state": 1,"stateName": "locked", "batteryCritical": false}' http://10.6.6.20:8083/fhem/NUKIDevice-123456
  354. my $header = join("\n", @FW_httpheader);
  355. my ($first,$json) = split("&",$request,2);
  356. if( !$json ) {
  357. Log3 $name, 3, "NUKIDevice ($name) - empty answer received";
  358. return undef;
  359. } elsif( $json =~ m'HTTP/1.1 200 OK' ) {
  360. Log3 $name, 4, "NUKIDevice ($name) - empty answer received";
  361. return undef;
  362. } elsif( $json !~ m/^[\[{].*[}\]]$/ ) {
  363. Log3 $name, 3, "NUKIDevice ($name) - invalid json detected: $json";
  364. return "NUKIDevice ($name) - invalid json detected: $json";
  365. }
  366. my $decode_json = eval{decode_json($json)};
  367. if($@){
  368. Log3 $name, 3, "NUKIDevice ($name) - JSON error while request: $@";
  369. return;
  370. }
  371. if( ref($decode_json) eq "HASH" ) {
  372. if ( defined( $modules{NUKIDevice}{defptr} ) ) {
  373. while ( my ( $key, $value ) = each %{ $modules{NUKIDevice}{defptr} } ) {
  374. $hash = $modules{NUKIDevice}{defptr}{$key};
  375. $name = $hash->{NAME};
  376. $nukiId = InternalVal( $name, "NUKIID", undef );
  377. next if ( !$nukiId or $nukiId ne $decode_json->{nukiId} );
  378. $hash->{WEBHOOK_COUNTER}++;
  379. $hash->{WEBHOOK_LAST} = TimeNow();
  380. Log3 $name, 4, "NUKIDevice ($name) - Received webhook for matching NukiId at device $name";
  381. NUKIDevice_Parse($hash,$json);
  382. }
  383. }
  384. return ( undef, undef );
  385. }
  386. # no data received
  387. else {
  388. Log3 undef, 4, "NUKIDevice - received malformed request\n$request";
  389. }
  390. return ( "text/plain; charset=utf-8", "Call failure: " . $request );
  391. }
  392. 1;
  393. =pod
  394. =item device
  395. =item summary Modul to control the Nuki Smartlock's
  396. =item summary_DE Modul zur Steuerung des Nuki Smartlocks.
  397. =begin html
  398. <a name="NUKIDevice"></a>
  399. <h3>NUKIDevice</h3>
  400. <ul>
  401. <u><b>NUKIDevice - Controls the Nuki Smartlock</b></u>
  402. <br>
  403. The Nuki module connects FHEM over the Nuki Bridge with a Nuki Smartlock. After that, it´s possible to lock and unlock the Smartlock.<br>
  404. Normally the Nuki devices are automatically created by the bridge module.
  405. <br><br>
  406. <a name="NUKIDevicedefine"></a>
  407. <b>Define</b>
  408. <ul><br>
  409. <code>define &lt;name&gt; NUKIDevice &lt;Nuki-Id&gt; &lt;IODev-Device&gt;</code>
  410. <br><br>
  411. Example:
  412. <ul><br>
  413. <code>define Frontdoor NUKIDevice 1 NBridge1</code><br>
  414. </ul>
  415. <br>
  416. This statement creates a NUKIDevice with the name Frontdoor, the NukiId 1 and the IODev device NBridge1.<br>
  417. After the device has been created, the current state of the Smartlock is automatically read from the bridge.
  418. </ul>
  419. <br><br>
  420. <a name="NUKIDevicereadings"></a>
  421. <b>Readings</b>
  422. <ul>
  423. <li>state - Status of the Smartlock or error message if any error.</li>
  424. <li>lockState - current lock status uncalibrated, locked, unlocked, unlocked (lock ‘n’ go), unlatched, locking, unlocking, unlatching, motor blocked, undefined.</li>
  425. <li>name - name of the device</li>
  426. <li>paired - paired information false/true</li>
  427. <li>rssi - value of rssi</li>
  428. <li>succes - true, false Returns the status of the last closing command. Ok or not Ok.</li>
  429. <li>batteryCritical - Is the battery in a critical state? True, false</li>
  430. <li>batteryState - battery status, ok / low</li>
  431. </ul>
  432. <br><br>
  433. <a name="NUKIDeviceset"></a>
  434. <b>Set</b>
  435. <ul>
  436. <li>statusRequest - retrieves the current state of the smartlock from the bridge.</li>
  437. <li>lock - lock</li>
  438. <li>unlock - unlock</li>
  439. <li>unlatch - unlock / open Door</li>
  440. <li>unpair - Removes the pairing with a given Smart Lock</li>
  441. <li>locknGo - lock when gone</li>
  442. <li>locknGoWithUnlatch - lock after the door has been opened</li>
  443. <br>
  444. </ul>
  445. <br><br>
  446. <a name="NUKIDeviceattribut"></a>
  447. <b>Attributes</b>
  448. <ul>
  449. <li>disable - disables the Nuki device</li>
  450. <li>webhookFWinstance - Webinstanz of the Callback</li>
  451. <li>webhookHttpHostname - IP or FQDN of the FHEM Server Callback</li>
  452. <br>
  453. </ul>
  454. </ul>
  455. =end html
  456. =begin html_DE
  457. <a name="NUKIDevice"></a>
  458. <h3>NUKIDevice</h3>
  459. <ul>
  460. <u><b>NUKIDevice - Steuert das Nuki Smartlock</b></u>
  461. <br>
  462. Das Nuki Modul verbindet FHEM über die Nuki Bridge mit einem Nuki Smartlock. Es ist dann m&ouml;glich das Schloss zu ver- und entriegeln.<br>
  463. In der Regel werden die Nuki Devices automatisch durch das Bridgemodul angelegt.
  464. <br><br>
  465. <a name="NUKIDevicedefine"></a>
  466. <b>Define</b>
  467. <ul><br>
  468. <code>define &lt;name&gt; NUKIDevice &lt;Nuki-Id&gt; &lt;IODev-Device&gt;</code>
  469. <br><br>
  470. Beispiel:
  471. <ul><br>
  472. <code>define Haust&uuml;r NUKIDevice 1 NBridge1</code><br>
  473. </ul>
  474. <br>
  475. Diese Anweisung erstellt ein NUKIDevice mit Namen Haust&uuml;r, der NukiId 1 sowie dem IODev Device NBridge1.<br>
  476. Nach dem anlegen des Devices wird automatisch der aktuelle Zustand des Smartlocks aus der Bridge gelesen.
  477. </ul>
  478. <br><br>
  479. <a name="NUKIDevicereadings"></a>
  480. <b>Readings</b>
  481. <ul>
  482. <li>state - Status des Smartlock bzw. Fehlermeldung von Fehler vorhanden.</li>
  483. <li>lockState - aktueller Schlie&szlig;status uncalibrated, locked, unlocked, unlocked (lock ‘n’ go), unlatched, locking, unlocking, unlatching, motor blocked, undefined.</li>
  484. <li>name - Name des Smart Locks</li>
  485. <li>paired - pairing Status des Smart Locks</li>
  486. <li>rssi - rssi Wert des Smart Locks</li>
  487. <li>succes - true, false Gibt des Status des letzten Schlie&szlig;befehles wieder. Geklappt oder nicht geklappt.</li>
  488. <li>batteryCritical - Ist die Batterie in einem kritischen Zustand? true, false</li>
  489. <li>batteryState - Status der Batterie, ok/low</li>
  490. </ul>
  491. <br><br>
  492. <a name="NUKIDeviceset"></a>
  493. <b>Set</b>
  494. <ul>
  495. <li>statusRequest - ruft den aktuellen Status des Smartlocks von der Bridge ab.</li>
  496. <li>lock - verschlie&szlig;en</li>
  497. <li>unlock - aufschlie&szlig;en</li>
  498. <li>unlatch - entriegeln/Falle &ouml;ffnen.</li>
  499. <li>unpair - entfernt das pairing mit dem Smart Lock</li>
  500. <li>locknGo - verschlie&szlig;en wenn gegangen</li>
  501. <li>locknGoWithUnlatch - verschlie&szlig;en nach dem die Falle ge&ouml;ffnet wurde.</li>
  502. <br>
  503. </ul>
  504. <br><br>
  505. <a name="NUKIDeviceattribut"></a>
  506. <b>Attribute</b>
  507. <ul>
  508. <li>disable - deaktiviert das Nuki Device</li>
  509. <li>webhookFWinstance - zu verwendene Webinstanz für den Callbackaufruf</li>
  510. <li>webhookHttpHostname - IP oder FQDN vom FHEM Server für den Callbackaufruf</li>
  511. <br>
  512. </ul>
  513. </ul>
  514. =end html_DE
  515. =cut