mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-13 23:36:37 +00:00
73_NUKIBridge: und 74_NUKIDevice, New Modules to control Nuki Smartlocks
git-svn-id: https://svn.fhem.de/fhem/trunk@12319 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
011286fba5
commit
86d5ad0297
14
fhem/CHANGED
14
fhem/CHANGED
@ -1,15 +1,16 @@
|
||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||
# Do not insert empty lines here, update check depends on it.
|
||||
- added: 73_NUKIBridge,74_NUKIDevice: New Modules to control Nuki Smartlocks
|
||||
- feature: 98_Hyperion: new attribute hyperionAttrRestore
|
||||
readings will always be refreshed now
|
||||
- feature: 93_DbRep: deviceRename added, new Internal DATABASE,
|
||||
Internal/Attribute ROLE added for Autorename-function
|
||||
- bugfix: 93_DbRep: delEntries not running on SQLite
|
||||
- added: 74_THINKINGCLEANER: new module to support remote control of
|
||||
Internal/Attribute ROLE added for Autorename-function
|
||||
- bugfix: 93_DbRep: delEntries not running on SQLite
|
||||
- added: 74_THINKINGCLEANER: new module to support remote control of
|
||||
Roomba cleaning robots
|
||||
- feature: 02_FTUISRV: if and loop constructs added
|
||||
- bugfix: 74_AMAD: fix FHEM crash when use AMAD and apptime togehter
|
||||
- new: 98_TRAFFIC: provide traffic details with Google Distance API
|
||||
- bugfix: 74_AMAD: fix FHEM crash when use AMAD and apptime togehter
|
||||
- new: 98_TRAFFIC: provide traffic details with Google Distance API
|
||||
- feature: 98_Hyperion: set configFile only available if at least two files
|
||||
are found while get configFiles
|
||||
minor code improvements
|
||||
@ -27,7 +28,8 @@
|
||||
more.
|
||||
- bugfix: 95_Dashboard: fix for yesterdays commit.
|
||||
- feature: readingsGroup: allow grouping of similar readings from one device
|
||||
14_SD_WS09.pm WH1080 CRC-Berechung angepaßt--> automatische Modelauswahl
|
||||
- feature 14_SD_WS09: WH1080 CRC-Berechung angepaßt--> automatische
|
||||
Modelauswahl
|
||||
- feature: 00_SIGNALduino: nonblocking communication, improved init
|
||||
and keepalive, fixed manchester related stuff, Supports
|
||||
Somfy RTS Protocol. Decoding manchester encoded messages
|
||||
|
593
fhem/FHEM/73_NUKIBridge.pm
Normal file
593
fhem/FHEM/73_NUKIBridge.pm
Normal file
@ -0,0 +1,593 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Developed with Kate
|
||||
#
|
||||
# (c) 2016 Copyright: Marko Oldenburg (leongaultier at gmail dot com)
|
||||
# All rights reserved
|
||||
#
|
||||
# This script is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
# A copy is found in the textfile GPL.txt and important notices to the license
|
||||
# from the author is found in LICENSE.txt distributed with these scripts.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use JSON;
|
||||
#use Time::HiRes qw(gettimeofday);
|
||||
use HttpUtils;
|
||||
|
||||
my $version = "0.2.1";
|
||||
my $bridgeAPI = "1.0.2";
|
||||
|
||||
|
||||
|
||||
my %lockActions = (
|
||||
'unlock' => 1,
|
||||
'lock' => 2,
|
||||
'unlatch' => 3,
|
||||
'locknGo' => 4,
|
||||
'locknGoWithUnlatch' => 5
|
||||
);
|
||||
|
||||
|
||||
sub NUKIBridge_Initialize($) {
|
||||
|
||||
my ($hash) = @_;
|
||||
|
||||
# Provider
|
||||
$hash->{ReadFn} = "NUKIBridge_Read";
|
||||
$hash->{WriteFn} = "NUKIBridge_Read";
|
||||
$hash->{Clients} = ":NUKIDevice:";
|
||||
|
||||
# Consumer
|
||||
$hash->{SetFn} = "NUKIBridge_Set";
|
||||
$hash->{DefFn} = "NUKIBridge_Define";
|
||||
$hash->{UndefFn} = "NUKIBridge_Undef";
|
||||
$hash->{AttrFn} = "NUKIBridge_Attr";
|
||||
$hash->{AttrList} = "interval ".
|
||||
"disable:1 ".
|
||||
$readingFnAttributes;
|
||||
|
||||
|
||||
foreach my $d(sort keys %{$modules{NUKIBridge}{defptr}}) {
|
||||
my $hash = $modules{NUKIBridge}{defptr}{$d};
|
||||
$hash->{VERSION} = $version;
|
||||
}
|
||||
}
|
||||
|
||||
sub NUKIBridge_Read($@) {
|
||||
|
||||
my ($hash,$chash,$name,$path,$lockAction,$nukiId)= @_;
|
||||
NUKIBridge_Call($hash,$chash,$path,$lockAction,$nukiId );
|
||||
|
||||
}
|
||||
|
||||
sub NUKIBridge_Define($$) {
|
||||
|
||||
my ( $hash, $def ) = @_;
|
||||
|
||||
my @a = split( "[ \t][ \t]*", $def );
|
||||
|
||||
|
||||
return "too few parameters: define <name> NUKIBridge <HOST> <TOKEN>" if( @a != 4 );
|
||||
|
||||
|
||||
|
||||
my $name = $a[0];
|
||||
my $host = $a[2];
|
||||
my $token = $a[3];
|
||||
my $port = 8080;
|
||||
my $interval = 60;
|
||||
|
||||
$hash->{HOST} = $host;
|
||||
$hash->{PORT} = $port;
|
||||
$hash->{TOKEN} = $token;
|
||||
$hash->{INTERVAL} = $interval;
|
||||
$hash->{VERSION} = $version;
|
||||
|
||||
|
||||
|
||||
Log3 $name, 3, "NUKIBridge ($name) - defined with host $host on port $port, Token $token";
|
||||
|
||||
$attr{$name}{room} = "NUKI" if( !defined( $attr{$name}{room} ) );
|
||||
readingsSingleUpdate($hash, 'state', 'Initialized', 1 );
|
||||
|
||||
RemoveInternalTimer($hash);
|
||||
|
||||
if( $init_done ) {
|
||||
NUKIBridge_Get($hash) if( ($hash->{HOST}) and ($hash->{TOKEN}) );
|
||||
#NUKIBridge_GetCheckBridgeAlive($hash) if( ($hash->{HOST}) and ($hash->{TOKEN}) );
|
||||
} else {
|
||||
InternalTimer( gettimeofday()+15, "NUKIBridge_Get", $hash, 0 ) if( ($hash->{HOST}) and ($hash->{TOKEN}) );
|
||||
}
|
||||
|
||||
$modules{NUKIBridge}{defptr}{$hash->{HOST}} = $hash;
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub NUKIBridge_Undef($$) {
|
||||
|
||||
my ( $hash, $arg ) = @_;
|
||||
|
||||
my $host = $hash->{HOST};
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
RemoveInternalTimer( $hash );
|
||||
|
||||
delete $modules{NUKIBridge}{defptr}{$hash->{HOST}};
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub NUKIBridge_Attr(@) {
|
||||
|
||||
my ( $cmd, $name, $attrName, $attrVal ) = @_;
|
||||
my $hash = $defs{$name};
|
||||
|
||||
my $orig = $attrVal;
|
||||
|
||||
if( $attrName eq "disable" ) {
|
||||
if( $cmd eq "set" ) {
|
||||
if( $attrVal eq "0" ) {
|
||||
RemoveInternalTimer( $hash );
|
||||
InternalTimer( gettimeofday()+2, "NUKIBridge_GetCheckBridgeAlive", $hash, 0 );
|
||||
readingsSingleUpdate($hash, 'state', 'Initialized', 1 );
|
||||
Log3 $name, 3, "NUKIBridge ($name) - enabled";
|
||||
} else {
|
||||
RemoveInternalTimer( $hash );
|
||||
readingsSingleUpdate($hash, 'state', 'disabled', 1 );
|
||||
Log3 $name, 3, "NUKIBridge ($name) - disabled";
|
||||
}
|
||||
|
||||
} else {
|
||||
RemoveInternalTimer( $hash );
|
||||
InternalTimer( gettimeofday()+2, "NUKIBridge_GetCheckBridgeAlive", $hash, 0 );
|
||||
readingsSingleUpdate($hash, 'state', 'Initialized', 1 );
|
||||
Log3 $name, 3, "NUKIBridge ($name) - enabled";
|
||||
}
|
||||
}
|
||||
|
||||
if( $attrName eq "interval" ) {
|
||||
if( $cmd eq "set" ) {
|
||||
if( $attrVal < 30 ) {
|
||||
Log3 $name, 3, "NUKIBridge ($name) - interval too small, please use something > 30 (sec), default is 60 (sec)";
|
||||
return "interval too small, please use something > 30 (sec), default is 60 (sec)";
|
||||
} else {
|
||||
$hash->{INTERVAL} = $attrVal;
|
||||
Log3 $name, 3, "NUKIBridge ($name) - set interval to $attrVal";
|
||||
}
|
||||
}
|
||||
elsif( $cmd eq "del" ) {
|
||||
$hash->{INTERVAL} = 60;
|
||||
Log3 $name, 3, "NUKIBridge ($name) - set interval to default";
|
||||
|
||||
} else {
|
||||
if( $cmd eq "set" ) {
|
||||
$attr{$name}{$attrName} = $attrVal;
|
||||
Log3 $name, 3, "NUKIBridge ($name) - $attrName : $attrVal";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub NUKIBridge_Set($@) {
|
||||
|
||||
my ($hash, $name, $cmd, @args) = @_;
|
||||
my ($arg, @params) = @args;
|
||||
|
||||
|
||||
if($cmd eq 'autocreate') {
|
||||
return "usage: autocreate" if( @args != 0 );
|
||||
|
||||
NUKIBridge_Get($hash);
|
||||
|
||||
return undef;
|
||||
|
||||
} elsif($cmd eq 'statusRequest') {
|
||||
|
||||
NUKIBridge_GetCheckBridgeAlive($hash);
|
||||
|
||||
return undef;
|
||||
|
||||
} elsif($cmd eq 'other2') {
|
||||
|
||||
} else {
|
||||
my $list = "statusRequest:noArg autocreate:noArg";
|
||||
return "Unknown argument $cmd, choose one of $list";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub NUKIBridge_Get($) {
|
||||
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
RemoveInternalTimer($hash);
|
||||
|
||||
NUKIBridge_Call($hash,$hash,"list",undef,undef) if( !IsDisabled($name) );
|
||||
NUKIBridge_GetCheckBridgeAlive($hash);
|
||||
|
||||
Log3 $name, 4, "NUKIBridge ($name) - Call NUKIBridge_Get" if( !IsDisabled($name) );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub NUKIBridge_GetCheckBridgeAlive($) {
|
||||
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
RemoveInternalTimer($hash);
|
||||
|
||||
if( !IsDisabled($name) ) {
|
||||
|
||||
NUKIBridge_Call($hash,$hash,"list",undef,undef,1);
|
||||
|
||||
InternalTimer( gettimeofday()+$hash->{INTERVAL}, "NUKIBridge_GetCheckBridgeAlive", $hash, 1 );
|
||||
Log3 $name, 4, "NUKIBridge ($name) - Call InternalTimer for NUKIBridge_GetCheckBridgeAlive";
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub NUKIBridge_Call($$$$$;$) {
|
||||
|
||||
my ($hash,$chash,$path,$lockAction,$nukiId,$alive) = @_;
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
my $host = $hash->{HOST};
|
||||
my $port = $hash->{PORT};
|
||||
my $token = $hash->{TOKEN};
|
||||
|
||||
$alive = 0 if( !defined($alive) );
|
||||
|
||||
|
||||
my $uri = "http://" . $hash->{HOST} . ":" . $port;
|
||||
$uri .= "/" . $path if( defined $path);
|
||||
$uri .= "?token=" . $token if( defined($token) );
|
||||
$uri .= "&action=" . $lockActions{$lockAction} if( defined($lockAction) );
|
||||
$uri .= "&nukiId=" . $nukiId if( defined($nukiId) );
|
||||
|
||||
|
||||
HttpUtils_NonblockingGet(
|
||||
{
|
||||
url => $uri,
|
||||
timeout => 10,
|
||||
hash => $hash,
|
||||
chash => $chash,
|
||||
endpoint => $path,
|
||||
alive => $alive,
|
||||
method => "GET",
|
||||
doTrigger => 1,
|
||||
noshutdown => 1,
|
||||
callback => \&NUKIBridge_Dispatch,
|
||||
}
|
||||
);
|
||||
|
||||
Log3 $name, 4, "NUKIBridge ($name) - Send HTTP POST with URL $uri";
|
||||
|
||||
#return undef; # beim Aufruf aus dem logischen Modul kam immer erst ein Fehler, deshalb auskommentiert
|
||||
}
|
||||
|
||||
sub NUKIBridge_Dispatch($$$) {
|
||||
|
||||
my ( $param, $err, $json ) = @_;
|
||||
my $hash = $param->{hash};
|
||||
my $doTrigger = $param->{doTrigger};
|
||||
my $name = $hash->{NAME};
|
||||
my $host = $hash->{HOST};
|
||||
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
|
||||
if( defined( $err ) ) {
|
||||
|
||||
if( $err ne "" and $param->{endpoint} eq "list" and $param->{alive} eq 1 ) {
|
||||
|
||||
readingsBulkUpdate( $hash, "state", "not connected");
|
||||
readingsBulkUpdate( $hash, "lastError", $err );
|
||||
|
||||
Log3 $name, 4, "NUKIBridge ($name) - Bridge ist offline";
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
return;
|
||||
}
|
||||
|
||||
elsif ( $err ne "" ) {
|
||||
|
||||
readingsBulkUpdate( $hash, "lastError", $err );
|
||||
Log3 $name, 4, "NUKIBridge ($name) - error while requesting: $err";
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
return $err;
|
||||
}
|
||||
}
|
||||
|
||||
if( $json eq "" and exists( $param->{code} ) && $param->{code} ne 200 ) {
|
||||
|
||||
readingsBulkUpdate( $hash, "lastError", "Internal error, " .$param->{code} );
|
||||
Log3 $name, 4, "NUKIBridge ($name) - received http code " .$param->{code}." without any data after requesting";
|
||||
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
return "received http code ".$param->{code}." without any data after requesting";
|
||||
}
|
||||
|
||||
if( ( $json =~ /Error/i ) and exists( $param->{code} ) ) {
|
||||
|
||||
readingsBulkUpdate( $hash, "lastError", "invalid API token" ) if( $param->{code} eq 401 );
|
||||
readingsBulkUpdate( $hash, "lastError", "action is undefined" ) if( $param->{code} eq 400 and $hash == $param->{chash} );
|
||||
|
||||
|
||||
###### Fehler bei Antwort auf Anfrage eines logischen Devices ######
|
||||
NUKIDevice_Parse($param->{chash},$param->{code}) if( $param->{code} eq 404 );
|
||||
NUKIDevice_Parse($param->{chash},$param->{code}) if( $param->{code} eq 400 and $hash != $param->{chash} );
|
||||
|
||||
|
||||
Log3 $name, 4, "NUKIBridge ($name) - invalid API token" if( $param->{code} eq 401 );
|
||||
Log3 $name, 4, "NUKIBridge ($name) - nukiId is not known" if( $param->{code} eq 404 );
|
||||
Log3 $name, 4, "NUKIBridge ($name) - action is undefined" if( $param->{code} eq 400 and $hash == $param->{chash} );
|
||||
|
||||
|
||||
######### Zum testen da ich kein Nuki Smartlock habe ############
|
||||
#if ( $param->{code} eq 404 ) {
|
||||
# if( defined($param->{chash}->{helper}{lockAction}) ) {
|
||||
# Log3 $name, 3, "NUKIBridge ($name) - Test JSON String for lockAction";
|
||||
# $json = '{"success": true, "batteryCritical": false}';
|
||||
# } else {
|
||||
# Log3 $name, 3, "NUKIBridge ($name) - Test JSON String for lockState";
|
||||
# $json = '{"state": 1, "stateName": "locked", "batteryCritical": false, "success": "true"}';
|
||||
# }
|
||||
# NUKIDevice_Parse($param->{chash},$json);
|
||||
#}
|
||||
|
||||
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
return $param->{code};
|
||||
}
|
||||
|
||||
if( $param->{code} eq 200 and $param->{endpoint} eq "list" and $param->{alive} eq 1 ) {
|
||||
|
||||
readingsBulkUpdate( $hash, "state", "connected" );
|
||||
Log3 $name, 5, "NUKIBridge ($name) - Bridge ist online";
|
||||
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if( $hash == $param->{chash} ) {
|
||||
|
||||
#$json = '[{"nukiId": 1, "name": "Home"}, {"nukiId": 2, "name": "Grandma"}]'; # zum testen da ich kein Nuki Smartlock habe
|
||||
|
||||
NUKIBridge_ResponseProcessing($hash,$json);
|
||||
|
||||
} else {
|
||||
|
||||
NUKIDevice_Parse($param->{chash},$json);
|
||||
}
|
||||
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub NUKIBridge_ResponseProcessing($$) {
|
||||
|
||||
my ( $hash, $json ) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $decode_json;
|
||||
|
||||
|
||||
$decode_json = decode_json($json);
|
||||
|
||||
if( ref($decode_json) eq "ARRAY" and scalar(@{$decode_json}) > 0 ) {
|
||||
|
||||
NUKIBridge_Autocreate($hash,$decode_json);
|
||||
|
||||
} else {
|
||||
return $json;
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub NUKIBridge_Autocreate($$;$) {
|
||||
|
||||
my ($hash,$decode_json,$force)= @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
if( !$force ) {
|
||||
foreach my $d (keys %defs) {
|
||||
next if($defs{$d}{TYPE} ne "autocreate");
|
||||
return undef if(AttrVal($defs{$d}{NAME},"disable",undef));
|
||||
}
|
||||
}
|
||||
|
||||
my $autocreated = 0;
|
||||
my $nukiSmartlock;
|
||||
my $nukiId;
|
||||
my $nukiName;
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
|
||||
foreach $nukiSmartlock (@{$decode_json}) {
|
||||
|
||||
$nukiId = $nukiSmartlock->{nukiId};
|
||||
$nukiName = $nukiSmartlock->{name};
|
||||
|
||||
|
||||
my $code = $name ."-".$nukiId;
|
||||
if( defined($modules{NUKIDevice}{defptr}{$code}) ) {
|
||||
Log3 $name, 5, "$name: NukiId '$nukiId' already defined as '$modules{NUKIDevice}{defptr}{$code}->{NAME}'";
|
||||
next;
|
||||
}
|
||||
|
||||
my $devname = "NUKIDevice" . $nukiId;
|
||||
my $define= "$devname NUKIDevice $nukiId IODev=$name";
|
||||
Log3 $name, 5, "$name: create new device '$devname' for address '$nukiId'";
|
||||
|
||||
my $cmdret= CommandDefine(undef,$define);
|
||||
if($cmdret) {
|
||||
Log3 $name, 1, "($name) Autocreate: An error occurred while creating device for nukiId '$nukiId': $cmdret";
|
||||
} else {
|
||||
$cmdret= CommandAttr(undef,"$devname alias $nukiName");
|
||||
$cmdret= CommandAttr(undef,"$devname room NUKI");
|
||||
$cmdret= CommandAttr(undef,"$devname IODev $name");
|
||||
}
|
||||
|
||||
$defs{$devname}{helper}{fromAutocreate} = 1 ;
|
||||
|
||||
readingsBulkUpdate( $hash, "${autocreated}_nukiId", $nukiId );
|
||||
readingsBulkUpdate( $hash, "${autocreated}_name", $nukiName );
|
||||
|
||||
$autocreated++;
|
||||
|
||||
readingsBulkUpdate( $hash, "smartlockCount", $autocreated );
|
||||
}
|
||||
|
||||
readingsBulkUpdate( $hash, "bridgeAPI", $bridgeAPI );
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
|
||||
|
||||
if( $autocreated ) {
|
||||
Log3 $name, 2, "$name: autocreated $autocreated devices";
|
||||
CommandSave(undef,undef) if( AttrVal( "autocreate", "autosave", 1 ) );
|
||||
}
|
||||
|
||||
return "created $autocreated devices";
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
|
||||
|
||||
=pod
|
||||
=item device
|
||||
=item summary
|
||||
=item summary_DE Modul zur Steuerung des Nuki Smartlock über die Nuki Bridge.
|
||||
|
||||
=begin html
|
||||
|
||||
<a name="NUKIBridge"></a>
|
||||
<h3>NUKIBridge</h3>
|
||||
<ul>
|
||||
<u><b>NUKIBridge - controls the Nuki Smartlock over the Nuki Bridge</b></u>
|
||||
<br>
|
||||
The Nuki Bridge module connects FHEM to the Nuki Bridge and then reads all the smartlocks available on the bridge. Furthermore, the detected Smartlocks are automatically created as independent devices.
|
||||
<br><br>
|
||||
<a name="NUKIBridgedefine"></a>
|
||||
<b>Define</b>
|
||||
<ul><br>
|
||||
<code>define <name> NUKIBridge <HOST> <API-TOKEN></code>
|
||||
<br><br>
|
||||
Example:
|
||||
<ul><br>
|
||||
<code>define NBridge1 NUKIBridge 192.168.0.23 F34HK6</code><br>
|
||||
</ul>
|
||||
<br>
|
||||
This statement creates a NUKIBridge device with the name NBridge1 and the IP 192.168.0.23 as well as the token F34HK6.<br>
|
||||
After the bridge device is created, all available Smartlocks are automatically placed in FHEM.
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIBridgereadings"></a>
|
||||
<b>Readings</b>
|
||||
<ul>
|
||||
<li>0_nukiId - ID of the first found Nuki Smartlock</li>
|
||||
<li>0_name - Name of the first found Nuki Smartlock</li>
|
||||
<li>smartlockCount - number of all found Smartlocks</li>
|
||||
<li>bridgeAPI - API Version of bridge</li>
|
||||
<br>
|
||||
The preceding number is continuous, starts with 0 und returns the properties of <b>one</b> Smartlock.
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIBridgeset"></a>
|
||||
<b>Set</b>
|
||||
<ul>
|
||||
<li>autocreate - Prompts to re-read all Smartlocks from the bridge and if not already present in FHEM, create the autimatic.</li>
|
||||
<li>statusRequest - starts a checkAlive of the bridge, it is determined whether the bridge is still online</li>
|
||||
<br>
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIBridgeattribut"></a>
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
<li>disable - disables the Nuki Bridge</li>
|
||||
<li>interval - changes the interval for the CheckAlive</li>
|
||||
<br>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
=begin html_DE
|
||||
|
||||
<a name="NUKIBridge"></a>
|
||||
<h3>NUKIBridge</h3>
|
||||
<ul>
|
||||
<u><b>NUKIBridge - Steuert das Nuki Smartlock über die Nuki Bridge</b></u>
|
||||
<br>
|
||||
Das Nuki Bridge Modul verbindet FHEM mit der Nuki Bridge und liest dann alle auf der Bridge verfügbaren Smartlocks ein. Desweiteren werden automatisch die erkannten Smartlocks als eigenständige Devices an gelegt.
|
||||
<br><br>
|
||||
<a name="NUKIBridgedefine"></a>
|
||||
<b>Define</b>
|
||||
<ul><br>
|
||||
<code>define <name> NUKIBridge <HOST> <API-TOKEN></code>
|
||||
<br><br>
|
||||
Beispiel:
|
||||
<ul><br>
|
||||
<code>define NBridge1 NUKIBridge 192.168.0.23 F34HK6</code><br>
|
||||
</ul>
|
||||
<br>
|
||||
Diese Anweisung erstellt ein NUKIBridge Device mit Namen NBridge1 und der IP 192.168.0.23 sowie dem Token F34HK6.<br>
|
||||
Nach dem anlegen des Bridge Devices werden alle zur verfügung stehende Smartlock automatisch in FHEM an gelegt.
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIBridgereadings"></a>
|
||||
<b>Readings</b>
|
||||
<ul>
|
||||
<li>0_nukiId - ID des ersten gefundenen Nuki Smartlocks</li>
|
||||
<li>0_name - Name des ersten gefunden Nuki Smartlocks</li>
|
||||
<li>smartlockCount - Anzahl aller gefundenen Smartlock</li>
|
||||
<li>bridgeAPI - API Version der Bridge</li>
|
||||
<br>
|
||||
Die vorangestellte Zahl ist forlaufend und gibt beginnend bei 0 die Eigenschaften <b>Eines</b> Smartlocks wieder.
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIBridgeset"></a>
|
||||
<b>Set</b>
|
||||
<ul>
|
||||
<li>autocreate - Veranlasst ein erneutes Einlesen aller Smartlocks von der Bridge und falls noch nicht in FHEM vorhanden das autimatische anlegen.</li>
|
||||
<li>statusRequest - startet einen checkAlive der Bridge, es wird festgestellt ob die Bridge noch online ist</li>
|
||||
<br>
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIBridgeattribut"></a>
|
||||
<b>Attribute</b>
|
||||
<ul>
|
||||
<li>disable - deaktiviert die Nuki Bridge</li>
|
||||
<li>interval - verändert den Interval für den CheckAlive</li>
|
||||
<br>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
=end html_DE
|
||||
=cut
|
501
fhem/FHEM/74_NUKIDevice.pm
Normal file
501
fhem/FHEM/74_NUKIDevice.pm
Normal file
@ -0,0 +1,501 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Developed with Kate
|
||||
#
|
||||
# (c) 2016 Copyright: Marko Oldenburg (leongaultier at gmail dot com)
|
||||
# All rights reserved
|
||||
#
|
||||
# This script is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
# A copy is found in the textfile GPL.txt and important notices to the license
|
||||
# from the author is found in LICENSE.txt distributed with these scripts.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use JSON;
|
||||
#use Time::HiRes qw(gettimeofday);
|
||||
|
||||
my $version = "0.2.1";
|
||||
|
||||
|
||||
|
||||
|
||||
sub NUKIDevice_Initialize($) {
|
||||
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{SetFn} = "NUKIDevice_Set";
|
||||
$hash->{DefFn} = "NUKIDevice_Define";
|
||||
$hash->{UndefFn} = "NUKIDevice_Undef";
|
||||
$hash->{AttrFn} = "NUKIDevice_Attr";
|
||||
|
||||
$hash->{AttrList} = "IODev ".
|
||||
"disable:1 ".
|
||||
"interval ".
|
||||
$readingFnAttributes;
|
||||
|
||||
|
||||
|
||||
foreach my $d(sort keys %{$modules{NUKIDevice}{defptr}}) {
|
||||
my $hash = $modules{NUKIDevice}{defptr}{$d};
|
||||
$hash->{VERSION} = $version;
|
||||
}
|
||||
}
|
||||
|
||||
sub NUKIDevice_Define($$) {
|
||||
|
||||
my ( $hash, $def ) = @_;
|
||||
|
||||
my @a = split( "[ \t]+", $def );
|
||||
splice( @a, 1, 1 );
|
||||
my $iodev;
|
||||
my $i = 0;
|
||||
|
||||
foreach my $param ( @a ) {
|
||||
if( $param =~ m/IODev=([^\s]*)/ ) {
|
||||
$iodev = $1;
|
||||
splice( @a, $i, 3 );
|
||||
last;
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
return "too few parameters: define <name> NUKIDevice <nukiId>" if( @a < 2 );
|
||||
|
||||
my ($name,$nukiId) = @a;
|
||||
|
||||
$hash->{NUKIID} = $nukiId;
|
||||
$hash->{VERSION} = $version;
|
||||
$hash->{STATE} = 'Initialized';
|
||||
$hash->{INTERVAL} = 20;
|
||||
|
||||
|
||||
AssignIoPort($hash,$iodev) if( !$hash->{IODev} );
|
||||
|
||||
if(defined($hash->{IODev}->{NAME})) {
|
||||
|
||||
Log3 $name, 3, "$name: I/O device is " . $hash->{IODev}->{NAME};
|
||||
} else {
|
||||
|
||||
Log3 $name, 1, "$name: no I/O device";
|
||||
}
|
||||
|
||||
$iodev = $hash->{IODev}->{NAME};
|
||||
|
||||
|
||||
my $code = $hash->{NUKIID};
|
||||
$code = $iodev ."-". $code if( defined($iodev) );
|
||||
my $d = $modules{NUKIDevice}{defptr}{$code};
|
||||
return "NUKIDevice device $hash->{NUKIID} on NUKIBridge $iodev already defined as $d->{NAME}."
|
||||
if( defined($d)
|
||||
&& $d->{IODev} == $hash->{IODev}
|
||||
&& $d->{NAME} ne $name );
|
||||
|
||||
$modules{NUKIDevice}{defptr}{$code} = $hash;
|
||||
|
||||
|
||||
Log3 $name, 3, "NUKIDevice ($name) - defined with Code: $code";
|
||||
|
||||
$attr{$name}{room} = "NUKI" if( !defined( $attr{$name}{room} ) );
|
||||
|
||||
|
||||
RemoveInternalTimer($hash);
|
||||
|
||||
if( $init_done ) {
|
||||
NUKIDevice_GetUpdateInternalTimer($hash);
|
||||
} else {
|
||||
InternalTimer(gettimeofday()+20, "NUKIDevice_GetUpdateInternalTimer", $hash, 0);
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub NUKIDevice_Undef($$) {
|
||||
|
||||
my ( $hash, $arg ) = @_;
|
||||
|
||||
my $nukiId = $hash->{NUKIID};
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
|
||||
RemoveInternalTimer($hash);
|
||||
|
||||
my $code = $hash->{NUKIID};
|
||||
$code = $hash->{IODev}->{NAME} ."-". $code if( defined($hash->{IODev}->{NAME}) );
|
||||
Log3 $name, 3, "NUKIDevice ($name) - undefined with Code: $code";
|
||||
delete($modules{HUEDevice}{defptr}{$code});
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub NUKIDevice_Attr(@) {
|
||||
|
||||
my ( $cmd, $name, $attrName, $attrVal ) = @_;
|
||||
my $hash = $defs{$name};
|
||||
|
||||
if( $attrName eq "disable" ) {
|
||||
if( $cmd eq "set" ) {
|
||||
if( $attrVal eq "0" ) {
|
||||
RemoveInternalTimer( $hash );
|
||||
InternalTimer( gettimeofday()+2, "NUKIDevice_GetUpdateInternalTimer", $hash, 0 );
|
||||
readingsSingleUpdate ( $hash, "state", "Initialized", 1 );
|
||||
Log3 $name, 3, "NUKIDevice ($name) - enabled";
|
||||
} else {
|
||||
readingsSingleUpdate ( $hash, "state", "disabled", 1 );
|
||||
RemoveInternalTimer( $hash );
|
||||
Log3 $name, 3, "NUKIDevice ($name) - disabled";
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
RemoveInternalTimer( $hash );
|
||||
InternalTimer( gettimeofday()+2, "NUKIDevice_GetUpdateInternalTimer", $hash, 0 );
|
||||
readingsSingleUpdate ( $hash, "state", "Initialized", 1 );
|
||||
Log3 $name, 3, "NUKIDevice ($name) - enabled";
|
||||
}
|
||||
}
|
||||
|
||||
if( $attrName eq "interval" ) {
|
||||
if( $cmd eq "set" ) {
|
||||
if( $attrVal < 10 ) {
|
||||
Log3 $name, 3, "NUKIDevice ($name) - interval too small, please use something > 10 (sec), default is 20 (sec)";
|
||||
return "interval too small, please use something > 10 (sec), default is 60 (sec)";
|
||||
} else {
|
||||
$hash->{INTERVAL} = $attrVal;
|
||||
Log3 $name, 3, "NUKIDevice ($name) - set interval to $attrVal";
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$hash->{INTERVAL} = 20;
|
||||
Log3 $name, 3, "NUKIDevice ($name) - set interval to default";
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub NUKIDevice_Set($$@) {
|
||||
|
||||
my ($hash, $name, @aa) = @_;
|
||||
my ($cmd, @args) = @aa;
|
||||
|
||||
my $lockAction;
|
||||
|
||||
|
||||
if( $cmd eq 'statusRequest' ) {
|
||||
return "usage: statusRequest" if( @args != 0 );
|
||||
|
||||
NUKIDevice_GetUpdate($hash);
|
||||
return undef;
|
||||
|
||||
} elsif( $cmd eq 'lock' ) {
|
||||
$lockAction = $cmd;
|
||||
|
||||
} elsif( $cmd eq 'unlock' ) {
|
||||
$lockAction = $cmd;
|
||||
|
||||
} elsif( $cmd eq 'unlatch' ) {
|
||||
$lockAction = $cmd;
|
||||
|
||||
} elsif( $cmd eq 'locknGo' ) {
|
||||
$lockAction = $cmd;
|
||||
|
||||
} elsif( $cmd eq 'locknGoWithUnlatch' ) {
|
||||
$lockAction = $cmd;
|
||||
|
||||
|
||||
} else {
|
||||
my $list = "statusRequest:noArg unlock:noArg lock:noArg unlatch:noArg locknGo:noArg locknGoWithUnlatch:noArg";
|
||||
return "Unknown argument $cmd, choose one of $list";
|
||||
}
|
||||
|
||||
$hash->{helper}{lockAction} = $lockAction;
|
||||
NUKIDevice_ReadFromNUKIBridge($hash,"lockAction",$lockAction,$hash->{NUKIID} );
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub NUKIDevice_GetUpdate($) {
|
||||
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
|
||||
NUKIDevice_ReadFromNUKIBridge($hash, "lockState", undef, $hash->{NUKIID} );
|
||||
Log3 $name, 5, "NUKIDevice ($name) - NUKIDevice_GetUpdate Call NUKIDevice_ReadFromNUKIBridge";
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub NUKIDevice_GetUpdateInternalTimer($) {
|
||||
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
|
||||
NUKIDevice_GetUpdate($hash);
|
||||
Log3 $name, 5, "NUKIDevice ($name) - Call NUKIDevice_GetUpdate";
|
||||
|
||||
RemoveInternalTimer($hash);
|
||||
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "NUKIDevice_GetUpdateInternalTimer", $hash, 0) if( $hash->{INTERVAL} );
|
||||
Log3 $name, 5, "NUKIDevice ($name) - Call InternalTimer";
|
||||
}
|
||||
|
||||
sub NUKIDevice_ReadFromNUKIBridge($@) {
|
||||
|
||||
my ($hash,@a) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
no strict "refs";
|
||||
my $ret;
|
||||
unshift(@a,$name);
|
||||
|
||||
$ret = IOWrite($hash,$hash,@a);
|
||||
use strict "refs";
|
||||
return $ret;
|
||||
return if(IsDummy($name) || IsIgnored($name));
|
||||
my $iohash = $hash->{IODev};
|
||||
|
||||
if(!$iohash ||
|
||||
!$iohash->{TYPE} ||
|
||||
!$modules{$iohash->{TYPE}} ||
|
||||
!$modules{$iohash->{TYPE}}{ReadFn}) {
|
||||
Log3 $name, 3, "No I/O device or ReadFn found for $name";
|
||||
return;
|
||||
}
|
||||
|
||||
no strict "refs";
|
||||
unshift(@a,$name);
|
||||
$ret = &{$modules{$iohash->{TYPE}}{ReadFn}}($iohash, @a);
|
||||
use strict "refs";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub NUKIDevice_Parse($$) {
|
||||
|
||||
my($hash,$result) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
|
||||
#########################################
|
||||
####### Errorhandling #############
|
||||
|
||||
if( $result =~ /\d{3}/ ) {
|
||||
if( $result eq 400 ) {
|
||||
readingsSingleUpdate( $hash, "state", "action is undefined", 1 );
|
||||
Log3 $name, 3, "NUKIDevice ($name) - action is undefined";
|
||||
return;
|
||||
}
|
||||
|
||||
if( $result eq 404 ) {
|
||||
readingsSingleUpdate( $hash, "state", "nukiId is not known", 1 );
|
||||
Log3 $name, 3, "NUKIDevice ($name) - nukiId is not known";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#########################################
|
||||
#### verarbeiten des JSON Strings #######
|
||||
|
||||
my $decode_json = decode_json($result);
|
||||
|
||||
if( ref($decode_json) ne "HASH" ) {
|
||||
Log3 $name, 2, "$name: got wrong status message for $name: $decode_json";
|
||||
return undef;
|
||||
}
|
||||
|
||||
Log3 $name, 5, "parse status message for $name";
|
||||
|
||||
|
||||
############################
|
||||
#### Status des Smartlock
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
|
||||
|
||||
my $battery;
|
||||
if( $decode_json->{batteryCritical} eq "false" ) {
|
||||
$battery = "ok";
|
||||
} else {
|
||||
$battery = "low";
|
||||
}
|
||||
|
||||
if( defined($hash->{helper}{lockAction}) ) {
|
||||
|
||||
my ($state,$lockState);
|
||||
|
||||
$state = $hash->{helper}{lockAction} if( $decode_json->{success} eq "true" );
|
||||
$state = "error" if( $decode_json->{success} eq "false" );
|
||||
$lockState = $hash->{helper}{lockAction} if( $decode_json->{success} eq "true" );
|
||||
|
||||
|
||||
readingsBulkUpdate( $hash, "state", $state );
|
||||
readingsBulkUpdate( $hash, "lockState", $lockState );
|
||||
readingsBulkUpdate( $hash, "success", $decode_json->{success} );
|
||||
readingsBulkUpdate( $hash, "batteryCritical", $decode_json->{batteryCritical} );
|
||||
readingsBulkUpdate( $hash, "battery", $battery );
|
||||
|
||||
delete $hash->{helper}{lockAction};
|
||||
|
||||
} else {
|
||||
|
||||
readingsBulkUpdate( $hash, "batteryCritical", $decode_json->{batteryCritical} );
|
||||
readingsBulkUpdate( $hash, "lockState", $decode_json->{stateName} );
|
||||
readingsBulkUpdate( $hash, "state", $decode_json->{stateName} );
|
||||
readingsBulkUpdate( $hash, "battery", $battery );
|
||||
readingsBulkUpdate( $hash, "success", $decode_json->{success} );
|
||||
|
||||
Log3 $name, 5, "readings set for $name";
|
||||
}
|
||||
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
||||
|
||||
|
||||
|
||||
|
||||
=pod
|
||||
=item device
|
||||
=item summary
|
||||
=item summary_DE Modul zur Steuerung des Nuki Smartlocks.
|
||||
|
||||
=begin html
|
||||
|
||||
<a name="NUKIDevice"></a>
|
||||
<h3>NUKIDevice</h3>
|
||||
<ul>
|
||||
<u><b>NUKIDevice - Controls the Nuki Smartlock</b></u>
|
||||
<br>
|
||||
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>
|
||||
Normally the Nuki devices are automatically created by the bridge module.
|
||||
<br><br>
|
||||
<a name="NUKIDevicedefine"></a>
|
||||
<b>Define</b>
|
||||
<ul><br>
|
||||
<code>define <name> NUKIDevice <Nuki-Id> <IODev-Device></code>
|
||||
<br><br>
|
||||
Example:
|
||||
<ul><br>
|
||||
<code>define Frontdoor NUKIDevice 1 NBridge1</code><br>
|
||||
</ul>
|
||||
<br>
|
||||
This statement creates a NUKIDevice with the name Frontdoor, the NukiId 1 and the IODev device NBridge1.<br>
|
||||
After the device has been created, the current state of the Smartlock is automatically read from the bridge.
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIDevicereadings"></a>
|
||||
<b>Readings</b>
|
||||
<ul>
|
||||
<li>state - Status of the Smartlock or error message if any error.</li>
|
||||
<li>lockState - current lock status uncalibrated, locked, unlocked, unlocked (lock ‘n’ go), unlatched, locking, unlocking, unlatching, motor blocked, undefined.</li>
|
||||
<li>succes - true, false Returns the status of the last closing command. Ok or not Ok.</li>
|
||||
<li>batteryCritical - Is the battery in a critical state? True, false</li>
|
||||
<li>battery - battery status, ok / low</li>
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIDeviceset"></a>
|
||||
<b>Set</b>
|
||||
<ul>
|
||||
<li>statusRequest - retrieves the current state of the smartlock from the bridge.</li>
|
||||
<li>lock - lock</li>
|
||||
<li>unlock - unlock</li>
|
||||
<li>unlatch - unlock / open Door</li>
|
||||
<li>locknGo - lock when gone</li>
|
||||
<li>locknGoWithUnlatch - lock after the door has been opened</li>
|
||||
<br>
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIDeviceattribut"></a>
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
<li>disable - disables the Nuki device</li>
|
||||
<li>interval - changes the interval for the statusRequest</li>
|
||||
<br>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
=begin html_DE
|
||||
|
||||
<a name="NUKIDevice"></a>
|
||||
<h3>NUKIDevice</h3>
|
||||
<ul>
|
||||
<u><b>NUKIDevice - Steuert das Nuki Smartlock</b></u>
|
||||
<br>
|
||||
Das Nuki Modul verbindet FHEM über die Nuki Bridge mit einem Nuki Smartlock. Es ist dann möglich das Schloss zu ver- und entriegeln.<br>
|
||||
In der Regel werden die Nuki Devices automatisch durch das Bridgemodul angelegt.
|
||||
<br><br>
|
||||
<a name="NUKIDevicedefine"></a>
|
||||
<b>Define</b>
|
||||
<ul><br>
|
||||
<code>define <name> NUKIDevice <Nuki-Id> <IODev-Device></code>
|
||||
<br><br>
|
||||
Beispiel:
|
||||
<ul><br>
|
||||
<code>define Haustür NUKIDevice 1 NBridge1</code><br>
|
||||
</ul>
|
||||
<br>
|
||||
Diese Anweisung erstellt ein NUKIDevice mit Namen Haustür, der NukiId 1 sowie dem IODev Device NBridge1.<br>
|
||||
Nach dem anlegen des Devices wird automatisch der aktuelle Zustand des Smartlocks aus der Bridge gelesen.
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIDevicereadings"></a>
|
||||
<b>Readings</b>
|
||||
<ul>
|
||||
<li>state - Status des Smartlock bzw. Fehlermeldung von Fehler vorhanden.</li>
|
||||
<li>lockState - aktueller Schließstatus uncalibrated, locked, unlocked, unlocked (lock ‘n’ go), unlatched, locking, unlocking, unlatching, motor blocked, undefined.</li>
|
||||
<li>succes - true, false Gibt des Status des letzten Schließbefehles wieder. Geklappt oder nicht geklappt.</li>
|
||||
<li>batteryCritical - Ist die Batterie in einem kritischen Zustand? true, false</li>
|
||||
<li>battery - Status der Batterie, ok/low</li>
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIDeviceset"></a>
|
||||
<b>Set</b>
|
||||
<ul>
|
||||
<li>statusRequest - ruft den aktuellen Status des Smartlocks von der Bridge ab.</li>
|
||||
<li>lock - verschließen</li>
|
||||
<li>unlock - aufschließen</li>
|
||||
<li>unlatch - entriegeln/Falle öffnen.</li>
|
||||
<li>locknGo - verschließen wenn gegangen</li>
|
||||
<li>locknGoWithUnlatch - verschließen nach dem die Falle geöffnet wurde.</li>
|
||||
<br>
|
||||
</ul>
|
||||
<br><br>
|
||||
<a name="NUKIDeviceattribut"></a>
|
||||
<b>Attribute</b>
|
||||
<ul>
|
||||
<li>disable - deaktiviert das Nuki Device</li>
|
||||
<li>interval - verändert den Interval für den statusRequest</li>
|
||||
<br>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
=end html_DE
|
||||
=cut
|
@ -276,8 +276,10 @@ FHEM/73_GasCalculator Sailor http://forum.fhem.de/index.php
|
||||
FHEM/73_km200.pm Sailor http://forum.fhem.de/index.php/topic,25540.0.html
|
||||
FHEM/73_PRESENCE.pm markusbloch http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/73_MPD.pm Wzut http://forum.fhem.de Multimedia
|
||||
FHEM/74_NUKIBridge.pm CoolTux http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/74_AMAD.pm CoolTux http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/74_HOMBOT.pm CoolTux http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/74_HOMBOT.pm CoolTux http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/74_NUKIDevice.pm CoolTux http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/74_THINKINGCLEANER.pm loredo http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/74_Unifi.pm rapster http://forum.fhem.de Automatisierung
|
||||
FHEM/75_MSG.pm loredo http://forum.fhem.de Automatisierung
|
||||
@ -285,8 +287,8 @@ FHEM/75_msgConfig.pm loredo http://forum.fhem.de Automatis
|
||||
FHEM/76_MSGFile.pm gandy http://forum.fhem.de Automatisierung
|
||||
FHEM/76_MSGMail.pm gandy http://forum.fhem.de Automatisierung
|
||||
FHEM/77_UWZ.pm CoolTux http://forum.fhem.de Unterstuetzende Dienste/Wettermodule
|
||||
FHEM/77_SMAEM.pm VolkerKettenbach http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/77_SMASTP.pm VolkerKettenbach http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/77_SMAEM.pm VolkerKettenbach http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/77_SMASTP.pm VolkerKettenbach http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/79_BDKM.pm arnoaugustin http://forum.fhem.de Heizungssteuerung/Raumklima (bitte auch PM)
|
||||
FHEM/80_M232.pm borisneubert http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/80_xxLG7000.pm markusbloch http://forum.fhem.de Multimedia
|
||||
|
Loading…
x
Reference in New Issue
Block a user