mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 09:16:53 +00:00
GardenaSmart: all modules change to new API and code PBP conform
git-svn-id: https://svn.fhem.de/fhem/trunk@21791 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
b16f95a60d
commit
36f5c6cc04
@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# 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.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
|
- bugfix: GardenaSmart: all modules change to new API and code PBP conform
|
||||||
- feature: 37_echodevice.pm A1WAR447VT003J Yamaha MusicCast 20
|
- feature: 37_echodevice.pm A1WAR447VT003J Yamaha MusicCast 20
|
||||||
CHANGE: get status
|
CHANGE: get status
|
||||||
- feature: 10_SOMFY: new attr autoStoreRollingCode - store rc in uniqueID
|
- feature: 10_SOMFY: new attr autoStoreRollingCode - store rc in uniqueID
|
||||||
|
@ -54,22 +54,23 @@
|
|||||||
##
|
##
|
||||||
|
|
||||||
package FHEM::GardenaSmartBridge;
|
package FHEM::GardenaSmartBridge;
|
||||||
use GPUtils qw(GP_Import)
|
use GPUtils qw(GP_Import GP_Export);
|
||||||
; # wird für den Import der FHEM Funktionen aus der fhem.pl benötigt
|
|
||||||
|
# use Data::Dumper; #only for Debugging
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use POSIX;
|
use POSIX;
|
||||||
use FHEM::Meta;
|
use FHEM::Meta;
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
use HttpUtils;
|
use HttpUtils;
|
||||||
our $VERSION = '1.6.9';
|
|
||||||
|
|
||||||
my $missingModul = '';
|
my $missingModul = '';
|
||||||
eval "use Encode qw(encode encode_utf8 decode_utf8);1"
|
eval "use Encode qw(encode encode_utf8 decode_utf8);1"
|
||||||
or $missingModul .= "Encode ";
|
or $missingModul .= "Encode ";
|
||||||
|
|
||||||
# eval "use JSON;1" or $missingModul .= 'JSON ';
|
# eval "use JSON;1" || $missingModul .= 'JSON ';
|
||||||
eval "use IO::Socket::SSL;1" or $missingModul .= 'IO::Socket::SSL ';
|
eval "use IO::Socket::SSL;1" or $missingModul .= 'IO::Socket::SSL ';
|
||||||
|
|
||||||
# try to use JSON::MaybeXS wrapper
|
# try to use JSON::MaybeXS wrapper
|
||||||
@ -176,42 +177,30 @@ BEGIN {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# _Export - Export references to main context using a different naming schema
|
|
||||||
sub _Export {
|
|
||||||
no strict qw/refs/; ## no critic
|
|
||||||
my $pkg = caller(0);
|
|
||||||
my $main = $pkg;
|
|
||||||
$main =~ s/^(?:.+::)?([^:]+)$/main::$1\_/g;
|
|
||||||
foreach (@_) {
|
|
||||||
*{ $main . $_ } = *{ $pkg . '::' . $_ };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#-- Export to main context with different name
|
#-- Export to main context with different name
|
||||||
_Export(
|
GP_Export(
|
||||||
qw(
|
qw(
|
||||||
Initialize
|
Initialize
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
sub Initialize($) {
|
sub Initialize {
|
||||||
|
my $hash = shift;
|
||||||
my ($hash) = @_;
|
|
||||||
|
|
||||||
# Provider
|
# Provider
|
||||||
$hash->{WriteFn} = 'FHEM::GardenaSmartBridge::Write';
|
$hash->{WriteFn} = \&Write;
|
||||||
$hash->{Clients} = ':GardenaSmartDevice:';
|
$hash->{Clients} = ':GardenaSmartDevice:';
|
||||||
$hash->{MatchList} = { '1:GardenaSmartDevice' => '^{"id":".*' };
|
$hash->{MatchList} = { '1:GardenaSmartDevice' => '^{"id":".*' };
|
||||||
|
|
||||||
# Consumer
|
# Consumer
|
||||||
$hash->{SetFn} = 'FHEM::GardenaSmartBridge::Set';
|
$hash->{SetFn} = \&Set;
|
||||||
$hash->{DefFn} = 'FHEM::GardenaSmartBridge::Define';
|
$hash->{DefFn} = \&Define;
|
||||||
$hash->{UndefFn} = 'FHEM::GardenaSmartBridge::Undef';
|
$hash->{UndefFn} = \&Undef;
|
||||||
$hash->{DeleteFn} = 'FHEM::GardenaSmartBridge::Delete';
|
$hash->{DeleteFn} = \&Delete;
|
||||||
$hash->{RenameFn} = 'FHEM::GardenaSmartBridge::Rename';
|
$hash->{RenameFn} = \&Rename;
|
||||||
$hash->{NotifyFn} = 'FHEM::GardenaSmartBridge::Notify';
|
$hash->{NotifyFn} = \&Notify;
|
||||||
|
|
||||||
$hash->{AttrFn} = 'FHEM::GardenaSmartBridge::Attr';
|
$hash->{AttrFn} = \&Attr;
|
||||||
$hash->{AttrList} =
|
$hash->{AttrList} =
|
||||||
'debugJSON:0,1 '
|
'debugJSON:0,1 '
|
||||||
. 'disable:1 '
|
. 'disable:1 '
|
||||||
@ -220,38 +209,33 @@ sub Initialize($) {
|
|||||||
. 'gardenaAccountEmail '
|
. 'gardenaAccountEmail '
|
||||||
. 'gardenaBaseURL '
|
. 'gardenaBaseURL '
|
||||||
. $readingFnAttributes;
|
. $readingFnAttributes;
|
||||||
|
$hash->{parseParams} = 1;
|
||||||
foreach my $d ( sort keys %{ $modules{GardenaSmartBridge}{defptr} } ) {
|
|
||||||
|
|
||||||
my $hash = $modules{GardenaSmartBridge}{defptr}{$d};
|
|
||||||
$hash->{VERSION} = $VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FHEM::Meta::InitMod( __FILE__, $hash );
|
return FHEM::Meta::InitMod( __FILE__, $hash );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Define($$) {
|
sub Define {
|
||||||
|
my $hash = shift;
|
||||||
my ( $hash, $def ) = @_;
|
my $a = shift;
|
||||||
|
|
||||||
my @a = split( '[ \t][ \t]*', $def );
|
|
||||||
|
|
||||||
return $@ unless ( FHEM::Meta::SetInternals($hash) );
|
return $@ unless ( FHEM::Meta::SetInternals($hash) );
|
||||||
|
use version 0.60; our $VERSION = FHEM::Meta::Get( $hash, 'version' );
|
||||||
|
|
||||||
return 'too few parameters: define <NAME> GardenaSmartBridge'
|
return 'too few parameters: define <NAME> GardenaSmartBridge'
|
||||||
if ( @a != 2 );
|
if ( scalar( @{$a} ) != 2 );
|
||||||
return
|
return
|
||||||
'Cannot define Gardena Bridge device. Perl modul '
|
'Cannot define Gardena Bridge device. Perl modul '
|
||||||
. ${missingModul}
|
. ${missingModul}
|
||||||
. ' is missing.'
|
. ' is missing.'
|
||||||
if ($missingModul);
|
if ($missingModul);
|
||||||
|
|
||||||
my $name = $a[0];
|
my $name = shift @$a;
|
||||||
$hash->{BRIDGE} = 1;
|
$hash->{BRIDGE} = 1;
|
||||||
$hash->{URL} =
|
$hash->{URL} =
|
||||||
AttrVal( $name, 'gardenaBaseURL',
|
AttrVal( $name, 'gardenaBaseURL',
|
||||||
'https://sg-api.dss.husqvarnagroup.net' )
|
'https://sg-api.dss.husqvarnagroup.net' )
|
||||||
. '/sg-1';
|
. '/sg-1';
|
||||||
$hash->{VERSION} = $VERSION;
|
$hash->{VERSION} = version->parse($VERSION)->normal;
|
||||||
$hash->{INTERVAL} = 60;
|
$hash->{INTERVAL} = 60;
|
||||||
$hash->{NOTIFYDEV} = "global,$name";
|
$hash->{NOTIFYDEV} = "global,$name";
|
||||||
|
|
||||||
@ -265,35 +249,34 @@ sub Define($$) {
|
|||||||
|
|
||||||
$modules{GardenaSmartBridge}{defptr}{BRIDGE} = $hash;
|
$modules{GardenaSmartBridge}{defptr}{BRIDGE} = $hash;
|
||||||
|
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Undef($$) {
|
sub Undef {
|
||||||
|
my $hash = shift;
|
||||||
my ( $hash, $name ) = @_;
|
my $name = shift;
|
||||||
|
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
delete $modules{GardenaSmartBridge}{defptr}{BRIDGE}
|
delete $modules{GardenaSmartBridge}{defptr}{BRIDGE}
|
||||||
if ( defined( $modules{GardenaSmartBridge}{defptr}{BRIDGE} ) );
|
if ( defined( $modules{GardenaSmartBridge}{defptr}{BRIDGE} ) );
|
||||||
|
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Delete($$) {
|
sub Delete {
|
||||||
|
my $hash = shift;
|
||||||
my ( $hash, $name ) = @_;
|
my $name = shift;
|
||||||
|
|
||||||
setKeyValue( $hash->{TYPE} . '_' . $name . '_passwd', undef );
|
setKeyValue( $hash->{TYPE} . '_' . $name . '_passwd', undef );
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Attr(@) {
|
sub Attr {
|
||||||
|
|
||||||
my ( $cmd, $name, $attrName, $attrVal ) = @_;
|
my ( $cmd, $name, $attrName, $attrVal ) = @_;
|
||||||
my $hash = $defs{$name};
|
my $hash = $defs{$name};
|
||||||
|
|
||||||
if ( $attrName eq 'disable' ) {
|
if ( $attrName eq 'disable' ) {
|
||||||
if ( $cmd eq 'set' and $attrVal eq '1' ) {
|
if ( $cmd eq 'set' && $attrVal eq '1' ) {
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
readingsSingleUpdate( $hash, 'state', 'inactive', 1 );
|
readingsSingleUpdate( $hash, 'state', 'inactive', 1 );
|
||||||
Log3 $name, 3, "GardenaSmartBridge ($name) - disabled";
|
Log3 $name, 3, "GardenaSmartBridge ($name) - disabled";
|
||||||
@ -307,7 +290,7 @@ sub Attr(@) {
|
|||||||
if ( $cmd eq 'set' ) {
|
if ( $cmd eq 'set' ) {
|
||||||
return
|
return
|
||||||
"check disabledForIntervals Syntax HH:MM-HH:MM or 'HH:MM-HH:MM HH:MM-HH:MM ...'"
|
"check disabledForIntervals Syntax HH:MM-HH:MM or 'HH:MM-HH:MM HH:MM-HH:MM ...'"
|
||||||
unless ( $attrVal =~ /^((\d{2}:\d{2})-(\d{2}:\d{2})\s?)+$/ );
|
if ( $attrVal !~ /^((\d{2}:\d{2})-(\d{2}:\d{2})\s?)+$/ );
|
||||||
Log3 $name, 3, "GardenaSmartBridge ($name) - disabledForIntervals";
|
Log3 $name, 3, "GardenaSmartBridge ($name) - disabledForIntervals";
|
||||||
}
|
}
|
||||||
elsif ( $cmd eq 'del' ) {
|
elsif ( $cmd eq 'del' ) {
|
||||||
@ -319,7 +302,7 @@ sub Attr(@) {
|
|||||||
if ( $cmd eq 'set' ) {
|
if ( $cmd eq 'set' ) {
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
return 'Interval must be greater than 0'
|
return 'Interval must be greater than 0'
|
||||||
unless ( $attrVal > 0 );
|
if ( $attrVal == 0 );
|
||||||
$hash->{INTERVAL} = $attrVal;
|
$hash->{INTERVAL} = $attrVal;
|
||||||
Log3 $name, 3,
|
Log3 $name, 3,
|
||||||
"GardenaSmartBridge ($name) - set interval: $attrVal";
|
"GardenaSmartBridge ($name) - set interval: $attrVal";
|
||||||
@ -342,12 +325,13 @@ sub Attr(@) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Notify($$) {
|
sub Notify {
|
||||||
|
my $hash = shift;
|
||||||
|
my $dev = shift;
|
||||||
|
|
||||||
my ( $hash, $dev ) = @_;
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
return if ( IsDisabled($name) );
|
return if ( IsDisabled($name) );
|
||||||
|
|
||||||
@ -360,7 +344,7 @@ sub Notify($$) {
|
|||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
$devtype eq 'Global'
|
$devtype eq 'Global'
|
||||||
and (
|
&& (
|
||||||
grep /^INITIALIZED$/,
|
grep /^INITIALIZED$/,
|
||||||
@{$events} or grep /^REREADCFG$/,
|
@{$events} or grep /^REREADCFG$/,
|
||||||
@{$events} or grep /^DEFINED.$name$/,
|
@{$events} or grep /^DEFINED.$name$/,
|
||||||
@ -370,11 +354,11 @@ sub Notify($$) {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
or (
|
|| (
|
||||||
$devtype eq 'GardenaSmartBridge'
|
$devtype eq 'GardenaSmartBridge'
|
||||||
and (
|
&& (
|
||||||
grep /^gardenaAccountPassword.+/,
|
grep /^gardenaAccountPassword.+/,
|
||||||
@{$events} or ReadingsVal( '$devname', 'token', '' ) eq 'none'
|
@{$events} || ReadingsVal( '$devname', 'token', '' ) eq 'none'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -382,19 +366,19 @@ sub Notify($$) {
|
|||||||
getDevices($hash)
|
getDevices($hash)
|
||||||
if (
|
if (
|
||||||
$devtype eq 'Global'
|
$devtype eq 'Global'
|
||||||
and (
|
&& (
|
||||||
grep /^DELETEATTR.$name.disable$/,
|
grep /^DELETEATTR.$name.disable$/,
|
||||||
@{$events} or grep /^ATTR.$name.disable.0$/,
|
@{$events} or grep /^ATTR.$name.disable.0$/,
|
||||||
@{$events} or grep /^DELETEATTR.$name.interval$/,
|
@{$events} or grep /^DELETEATTR.$name.interval$/,
|
||||||
@{$events} or grep /^ATTR.$name.interval.[0-9]+/,
|
@{$events} or grep /^ATTR.$name.interval.[0-9]+/,
|
||||||
@{$events}
|
@{$events}
|
||||||
)
|
)
|
||||||
and $init_done
|
&& $init_done
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$devtype eq 'GardenaSmartBridge'
|
$devtype eq 'GardenaSmartBridge'
|
||||||
and (
|
&& (
|
||||||
grep /^state:.Connected$/,
|
grep /^state:.Connected$/,
|
||||||
@{$events} or grep /^lastRequestState:.request_error$/,
|
@{$events} or grep /^lastRequestState:.request_error$/,
|
||||||
@{$events}
|
@{$events}
|
||||||
@ -411,9 +395,12 @@ sub Notify($$) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Set($@) {
|
sub Set {
|
||||||
|
my $hash = shift;
|
||||||
|
my $a = shift;
|
||||||
|
|
||||||
my ( $hash, $name, $cmd, @args ) = @_;
|
my $name = shift @$a;
|
||||||
|
my $cmd = shift @$a // return qq{"set $name" needs at least one argument};
|
||||||
|
|
||||||
if ( lc $cmd eq 'getdevicesstate' ) {
|
if ( lc $cmd eq 'getdevicesstate' ) {
|
||||||
getDevices($hash);
|
getDevices($hash);
|
||||||
@ -423,44 +410,39 @@ sub Set($@) {
|
|||||||
return "please set Attribut gardenaAccountEmail first"
|
return "please set Attribut gardenaAccountEmail first"
|
||||||
if ( AttrVal( $name, 'gardenaAccountEmail', 'none' ) eq 'none' );
|
if ( AttrVal( $name, 'gardenaAccountEmail', 'none' ) eq 'none' );
|
||||||
return "please set gardenaAccountPassword first"
|
return "please set gardenaAccountPassword first"
|
||||||
if ( not defined( ReadPassword($hash,$name) ) );
|
if ( not defined( ReadPassword( $hash, $name ) ) );
|
||||||
return "token is up to date"
|
return "token is up to date"
|
||||||
if ( defined( $hash->{helper}{session_id} ) );
|
if ( defined( $hash->{helper}{session_id} ) );
|
||||||
|
|
||||||
getToken($hash);
|
getToken($hash);
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( lc $cmd eq 'gardenaaccountpassword' ) {
|
elsif ( lc $cmd eq 'gardenaaccountpassword' ) {
|
||||||
return "please set Attribut gardenaAccountEmail first"
|
return "please set Attribut gardenaAccountEmail first"
|
||||||
if ( AttrVal( $name, 'gardenaAccountEmail', 'none' ) eq 'none' );
|
if ( AttrVal( $name, 'gardenaAccountEmail', 'none' ) eq 'none' );
|
||||||
return "usage: $cmd <password>" if ( @args != 1 );
|
return "usage: $cmd <password>" if ( scalar( @{$a} ) != 0 );
|
||||||
|
|
||||||
my $passwd = join( ' ', @args );
|
|
||||||
StorePassword( $hash, $name, $passwd );
|
|
||||||
|
|
||||||
|
StorePassword( $hash, $name, $a->[0] );
|
||||||
}
|
}
|
||||||
elsif ( lc $cmd eq 'deleteaccountpassword' ) {
|
elsif ( lc $cmd eq 'deleteaccountpassword' ) {
|
||||||
return "usage: $cmd <password>" if ( @args != 0 );
|
return "usage: $cmd <password>" if ( scalar( @{$a} ) != 0 );
|
||||||
|
|
||||||
DeletePassword($hash);
|
DeletePassword($hash);
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
my $list = "getDevicesState:noArg getToken:noArg"
|
my $list = "getDevicesState:noArg getToken:noArg"
|
||||||
if ( defined( ReadPassword($hash,$name) ) );
|
if ( defined( ReadPassword( $hash, $name ) ) );
|
||||||
$list .= " gardenaAccountPassword"
|
$list .= " gardenaAccountPassword"
|
||||||
if ( not defined( ReadPassword($hash,$name) ) );
|
if ( not defined( ReadPassword( $hash, $name ) ) );
|
||||||
$list .= " deleteAccountPassword:noArg"
|
$list .= " deleteAccountPassword:noArg"
|
||||||
if ( defined( ReadPassword($hash,$name) ) );
|
if ( defined( ReadPassword( $hash, $name ) ) );
|
||||||
return "Unknown argument $cmd, choose one of $list";
|
return "Unknown argument $cmd, choose one of $list";
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Write($@) {
|
sub Write {
|
||||||
|
|
||||||
my ( $hash, $payload, $deviceId, $abilities ) = @_;
|
my ( $hash, $payload, $deviceId, $abilities ) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
@ -489,18 +471,21 @@ sub Write($@) {
|
|||||||
|
|
||||||
# Log3($name, 3,
|
# Log3($name, 3,
|
||||||
# "GardenaSmartBridge ($name) - Send with URL: $hash->{URL}$uri, HEADER: $header, DATA: $payload, METHOD: $method");
|
# "GardenaSmartBridge ($name) - Send with URL: $hash->{URL}$uri, HEADER: $header, DATA: $payload, METHOD: $method");
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub ErrorHandling($$$) {
|
sub ErrorHandling {
|
||||||
|
my $param = shift;
|
||||||
my ( $param, $err, $data ) = @_;
|
my $err = shift;
|
||||||
|
my $data = shift;
|
||||||
|
|
||||||
my $hash = $param->{hash};
|
my $hash = $param->{hash};
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $dhash = $hash;
|
my $dhash = $hash;
|
||||||
|
|
||||||
$dhash = $modules{GardenaSmartDevice}{defptr}{ $param->{'device_id'} }
|
$dhash = $modules{GardenaSmartDevice}{defptr}{ $param->{'device_id'} }
|
||||||
unless ( not defined( $param->{'device_id'} ) );
|
if ( defined( $param->{'device_id'} ) );
|
||||||
|
|
||||||
my $dname = $dhash->{NAME};
|
my $dname = $dhash->{NAME};
|
||||||
|
|
||||||
@ -526,7 +511,7 @@ sub ErrorHandling($$$) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
elsif ($err =~ /Keine Route zum Zielrechner/
|
elsif ($err =~ /Keine Route zum Zielrechner/
|
||||||
or $err =~ /no route to target/ )
|
|| $err =~ /no route to target/ )
|
||||||
{
|
{
|
||||||
|
|
||||||
Log3 $dname, 5,
|
Log3 $dname, 5,
|
||||||
@ -551,7 +536,7 @@ sub ErrorHandling($$$) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $data eq "" and exists( $param->{code} ) and $param->{code} != 200 ) {
|
if ( $data eq "" && exists( $param->{code} ) && $param->{code} != 200 ) {
|
||||||
|
|
||||||
readingsBeginUpdate($dhash);
|
readingsBeginUpdate($dhash);
|
||||||
readingsBulkUpdate( $dhash, "state", $param->{code}, 1 )
|
readingsBulkUpdate( $dhash, "state", $param->{code}, 1 )
|
||||||
@ -560,7 +545,7 @@ sub ErrorHandling($$$) {
|
|||||||
readingsBulkUpdateIfChanged( $dhash, "lastRequestState",
|
readingsBulkUpdateIfChanged( $dhash, "lastRequestState",
|
||||||
"request_error", 1 );
|
"request_error", 1 );
|
||||||
|
|
||||||
if ( $param->{code} == 401 and $hash eq $dhash ) {
|
if ( $param->{code} == 401 && $hash eq $dhash ) {
|
||||||
|
|
||||||
if ( ReadingsVal( $dname, 'token', 'none' ) eq 'none' ) {
|
if ( ReadingsVal( $dname, 'token', 'none' ) eq 'none' ) {
|
||||||
readingsBulkUpdate( $dhash, "state", "no token available", 1 );
|
readingsBulkUpdate( $dhash, "state", "no token available", 1 );
|
||||||
@ -572,9 +557,9 @@ sub ErrorHandling($$$) {
|
|||||||
"GardenaSmartBridge ($dname) - RequestERROR: " . $param->{code};
|
"GardenaSmartBridge ($dname) - RequestERROR: " . $param->{code};
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( $param->{code} == 204
|
elsif ($param->{code} == 204
|
||||||
and $dhash ne $hash
|
&& $dhash ne $hash
|
||||||
and defined( $dhash->{helper}{deviceAction} ) )
|
&& defined( $dhash->{helper}{deviceAction} ) )
|
||||||
{
|
{
|
||||||
|
|
||||||
readingsBulkUpdate( $dhash, "state", "the command is processed",
|
readingsBulkUpdate( $dhash, "state", "the command is processed",
|
||||||
@ -607,9 +592,9 @@ sub ErrorHandling($$$) {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
$data =~ /Error/
|
$data =~ /Error/
|
||||||
or ( defined($decode_json)
|
|| ( defined($decode_json)
|
||||||
and ref($decode_json) eq 'HASH'
|
&& ref($decode_json) eq 'HASH'
|
||||||
and defined( $decode_json->{errors} ) )
|
&& defined( $decode_json->{errors} ) )
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
readingsBeginUpdate($dhash);
|
readingsBeginUpdate($dhash);
|
||||||
@ -621,7 +606,7 @@ sub ErrorHandling($$$) {
|
|||||||
if ( $param->{code} == 400 ) {
|
if ( $param->{code} == 400 ) {
|
||||||
if ($decode_json) {
|
if ($decode_json) {
|
||||||
if ( ref( $decode_json->{errors} ) eq "ARRAY"
|
if ( ref( $decode_json->{errors} ) eq "ARRAY"
|
||||||
and defined( $decode_json->{errors} ) )
|
&& defined( $decode_json->{errors} ) )
|
||||||
{
|
{
|
||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$dhash,
|
$dhash,
|
||||||
@ -660,7 +645,7 @@ sub ErrorHandling($$$) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
elsif ( $param->{code} == 404 ) {
|
elsif ( $param->{code} == 404 ) {
|
||||||
if ( defined( $dhash->{helper}{deviceAction} ) and $dhash ne $hash )
|
if ( defined( $dhash->{helper}{deviceAction} ) && $dhash ne $hash )
|
||||||
{
|
{
|
||||||
readingsBulkUpdate( $dhash, "state", "device Id not found", 1 );
|
readingsBulkUpdate( $dhash, "state", "device Id not found", 1 );
|
||||||
readingsBulkUpdate( $dhash, "lastRequestState",
|
readingsBulkUpdate( $dhash, "lastRequestState",
|
||||||
@ -701,11 +686,13 @@ sub ErrorHandling($$$) {
|
|||||||
if ( defined( $hash->{helper}{locations_id} ) );
|
if ( defined( $hash->{helper}{locations_id} ) );
|
||||||
ResponseProcessing( $hash, $data )
|
ResponseProcessing( $hash, $data )
|
||||||
if ( ref($decode_json) eq 'HASH' );
|
if ( ref($decode_json) eq 'HASH' );
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub ResponseProcessing($$) {
|
sub ResponseProcessing {
|
||||||
|
my $hash = shift;
|
||||||
my ( $hash, $json ) = @_;
|
my $json = shift;
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
@ -722,7 +709,9 @@ sub ResponseProcessing($$) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( defined( $decode_json->{sessions} ) and $decode_json->{sessions} ) {
|
# print Dumper $decode_json;
|
||||||
|
|
||||||
|
if ( defined( $decode_json->{sessions} ) && $decode_json->{sessions} ) {
|
||||||
|
|
||||||
$hash->{helper}{session_id} = $decode_json->{sessions}{token};
|
$hash->{helper}{session_id} = $decode_json->{sessions}{token};
|
||||||
$hash->{helper}{user_id} = $decode_json->{sessions}{user_id};
|
$hash->{helper}{user_id} = $decode_json->{sessions}{user_id};
|
||||||
@ -734,13 +723,12 @@ sub ResponseProcessing($$) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( not defined( $hash->{helper}{locations_id} )
|
elsif ( !defined( $hash->{helper}{locations_id} )
|
||||||
and defined( $decode_json->{locations} )
|
&& defined( $decode_json->{locations} )
|
||||||
and ref( $decode_json->{locations} ) eq "ARRAY"
|
&& ref( $decode_json->{locations} ) eq 'ARRAY'
|
||||||
and scalar( @{ $decode_json->{locations} } ) > 0 )
|
&& scalar( @{ $decode_json->{locations} } ) > 0 )
|
||||||
{
|
{
|
||||||
|
for my $location ( @{ $decode_json->{locations} } ) {
|
||||||
foreach my $location ( @{ $decode_json->{locations} } ) {
|
|
||||||
|
|
||||||
$hash->{helper}{locations_id} = $location->{id};
|
$hash->{helper}{locations_id} = $location->{id};
|
||||||
|
|
||||||
@ -753,11 +741,10 @@ sub ResponseProcessing($$) {
|
|||||||
Write( $hash, undef, undef, undef );
|
Write( $hash, undef, undef, undef );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( defined( $decode_json->{devices} )
|
elsif (defined( $decode_json->{devices} )
|
||||||
and ref( $decode_json->{devices} ) eq "ARRAY"
|
&& ref( $decode_json->{devices} ) eq 'ARRAY'
|
||||||
and scalar( @{ $decode_json->{devices} } ) > 0 )
|
&& scalar( @{ $decode_json->{devices} } ) > 0 )
|
||||||
{
|
{
|
||||||
|
|
||||||
my @buffer = split( '"devices":\[', $json );
|
my @buffer = split( '"devices":\[', $json );
|
||||||
@ -779,19 +766,18 @@ sub ResponseProcessing($$) {
|
|||||||
. " Tail: "
|
. " Tail: "
|
||||||
. $tail;
|
. $tail;
|
||||||
|
|
||||||
unless ( not defined($tail) and not($tail) ) {
|
if ( defined($tail) and $tail ) {
|
||||||
|
|
||||||
$decode_json = eval { decode_json($json) };
|
$decode_json = eval { decode_json($json) };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
Log3 $name, 3,
|
Log3 $name, 5,
|
||||||
"GardenaSmartBridge ($name) - JSON error while request: $@";
|
"GardenaSmartBridge ($name) - JSON error while request: $@";
|
||||||
}
|
}
|
||||||
|
|
||||||
Dispatch( $hash, $json, undef )
|
Dispatch( $hash, $json, undef )
|
||||||
unless ( $decode_json->{category} eq 'gateway' );
|
if ( $decode_json->{category} ne 'gateway' );
|
||||||
WriteReadings( $hash, $decode_json )
|
WriteReadings( $hash, $decode_json )
|
||||||
if ( defined( $decode_json->{category} )
|
if ( defined( $decode_json->{category} )
|
||||||
and $decode_json->{category} eq 'gateway' );
|
&& $decode_json->{category} eq 'gateway' );
|
||||||
}
|
}
|
||||||
|
|
||||||
( $json, $tail ) = ParseJSON( $hash, $tail );
|
( $json, $tail ) = ParseJSON( $hash, $tail );
|
||||||
@ -809,17 +795,22 @@ sub ResponseProcessing($$) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log3 $name, 3, "GardenaSmartBridge ($name) - no Match for processing data";
|
Log3 $name, 3, "GardenaSmartBridge ($name) - no Match for processing data";
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub WriteReadings($$) {
|
sub WriteReadings {
|
||||||
|
my $hash = shift;
|
||||||
|
my $decode_json = shift;
|
||||||
|
|
||||||
|
# print Dumper $decode_json;
|
||||||
|
|
||||||
my ( $hash, $decode_json ) = @_;
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
if ( defined( $decode_json->{id} )
|
if ( defined( $decode_json->{id} )
|
||||||
and $decode_json->{id}
|
&& $decode_json->{id}
|
||||||
and defined( $decode_json->{name} )
|
&& defined( $decode_json->{name} )
|
||||||
and $decode_json->{name} )
|
&& $decode_json->{name} )
|
||||||
{
|
{
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
if ( $decode_json->{id} eq $hash->{helper}{locations_id} ) {
|
if ( $decode_json->{id} eq $hash->{helper}{locations_id} ) {
|
||||||
@ -839,9 +830,9 @@ sub WriteReadings($$) {
|
|||||||
readingsBulkUpdateIfChanged( $hash, 'zones',
|
readingsBulkUpdateIfChanged( $hash, 'zones',
|
||||||
scalar( @{ $decode_json->{zones} } ) );
|
scalar( @{ $decode_json->{zones} } ) );
|
||||||
}
|
}
|
||||||
elsif ( $decode_json->{id} ne $hash->{helper}{locations_id}
|
elsif ($decode_json->{id} ne $hash->{helper}{locations_id}
|
||||||
and ref( $decode_json->{abilities} ) eq 'ARRAY'
|
&& ref( $decode_json->{abilities} ) eq 'ARRAY'
|
||||||
and ref( $decode_json->{abilities}[0]{properties} ) eq 'ARRAY' )
|
&& ref( $decode_json->{abilities}[0]{properties} ) eq 'ARRAY' )
|
||||||
{
|
{
|
||||||
my $properties =
|
my $properties =
|
||||||
scalar( @{ $decode_json->{abilities}[0]{properties} } );
|
scalar( @{ $decode_json->{abilities}[0]{properties} } );
|
||||||
@ -861,20 +852,20 @@ sub WriteReadings($$) {
|
|||||||
{name} . '-' . $t,
|
{name} . '-' . $t,
|
||||||
$v
|
$v
|
||||||
)
|
)
|
||||||
unless (
|
if (
|
||||||
$decode_json->{abilities}[0]{properties}[$properties]
|
$decode_json->{abilities}[0]{properties}[$properties]
|
||||||
{name} eq 'ethernet_status'
|
{name} ne 'ethernet_status'
|
||||||
or $decode_json->{abilities}[0]{properties}[$properties]
|
|| $decode_json->{abilities}[0]{properties}
|
||||||
{name} eq 'wifi_status' );
|
[$properties]{name} ne 'wifi_status' );
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
$decode_json->{abilities}[0]{properties}
|
$decode_json->{abilities}[0]{properties}
|
||||||
[$properties]{name} eq 'ethernet_status'
|
[$properties]{name} eq 'ethernet_status'
|
||||||
or $decode_json->{abilities}[0]{properties}
|
|| $decode_json->{abilities}[0]{properties}
|
||||||
[$properties]{name} eq 'wifi_status'
|
[$properties]{name} eq 'wifi_status'
|
||||||
)
|
)
|
||||||
and ref($v) eq 'HASH'
|
&& ref($v) eq 'HASH'
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if ( $decode_json->{abilities}[0]{properties}
|
if ( $decode_json->{abilities}[0]{properties}
|
||||||
@ -914,15 +905,17 @@ sub WriteReadings($$) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log3 $name, 4, "GardenaSmartBridge ($name) - readings would be written";
|
Log3 $name, 4, "GardenaSmartBridge ($name) - readings would be written";
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
####################################
|
####################################
|
||||||
#### my little helpers Sub's #######
|
#### my little helpers Sub's #######
|
||||||
|
|
||||||
sub getDevices($) {
|
sub getDevices {
|
||||||
|
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
@ -938,11 +931,13 @@ sub getDevices($) {
|
|||||||
readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
|
readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
|
||||||
Log3 $name, 3, "GardenaSmartBridge ($name) - device is disabled";
|
Log3 $name, 3, "GardenaSmartBridge ($name) - device is disabled";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub getToken($) {
|
sub getToken {
|
||||||
|
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
return readingsSingleUpdate( $hash, 'state',
|
return readingsSingleUpdate( $hash, 'state',
|
||||||
@ -950,35 +945,39 @@ sub getToken($) {
|
|||||||
if ( AttrVal( $name, 'gardenaAccountEmail', 'none' ) eq 'none' );
|
if ( AttrVal( $name, 'gardenaAccountEmail', 'none' ) eq 'none' );
|
||||||
return readingsSingleUpdate( $hash, 'state',
|
return readingsSingleUpdate( $hash, 'state',
|
||||||
'please set gardena account password first', 1 )
|
'please set gardena account password first', 1 )
|
||||||
if ( not defined( ReadPassword($hash,$name) ) );
|
if ( !defined( ReadPassword( $hash, $name ) ) );
|
||||||
readingsSingleUpdate( $hash, 'state', 'get token', 1 );
|
readingsSingleUpdate( $hash, 'state', 'get token', 1 );
|
||||||
|
|
||||||
delete $hash->{helper}{session_id}
|
delete $hash->{helper}{session_id}
|
||||||
if ( defined( $hash->{helper}{session_id} )
|
if ( defined( $hash->{helper}{session_id} )
|
||||||
and $hash->{helper}{session_id} );
|
&& $hash->{helper}{session_id} );
|
||||||
delete $hash->{helper}{user_id}
|
delete $hash->{helper}{user_id}
|
||||||
if ( defined( $hash->{helper}{user_id} ) and $hash->{helper}{user_id} );
|
if ( defined( $hash->{helper}{user_id} ) && $hash->{helper}{user_id} );
|
||||||
delete $hash->{helper}{locations_id}
|
delete $hash->{helper}{locations_id}
|
||||||
if ( defined( $hash->{helper}{locations_id} )
|
if ( defined( $hash->{helper}{locations_id} )
|
||||||
and $hash->{helper}{locations_id} );
|
&& $hash->{helper}{locations_id} );
|
||||||
|
|
||||||
Write(
|
Write(
|
||||||
$hash,
|
$hash,
|
||||||
'"sessions": {"email": "'
|
'"sessions": {"email": "'
|
||||||
. AttrVal( $name, 'gardenaAccountEmail', 'none' )
|
. AttrVal( $name, 'gardenaAccountEmail', 'none' )
|
||||||
. '","password": "'
|
. '","password": "'
|
||||||
. ReadPassword($hash,$name) . '"}',
|
. ReadPassword( $hash, $name ) . '"}',
|
||||||
undef,
|
undef,
|
||||||
undef
|
undef
|
||||||
);
|
);
|
||||||
|
|
||||||
Log3 $name, 3,
|
Log3 $name, 3,
|
||||||
"GardenaSmartBridge ($name) - send credentials to fetch Token and locationId";
|
"GardenaSmartBridge ($name) - send credentials to fetch Token and locationId";
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub StorePassword($@) {
|
sub StorePassword {
|
||||||
|
my $hash = shift;
|
||||||
|
my $name = shift;
|
||||||
|
my $password = shift;
|
||||||
|
|
||||||
my ( $hash, $name, $password ) = @_;
|
|
||||||
my $index = $hash->{TYPE} . "_" . $name . "_passwd";
|
my $index = $hash->{TYPE} . "_" . $name . "_passwd";
|
||||||
my $key = getUniqueId() . $index;
|
my $key = getUniqueId() . $index;
|
||||||
my $enc_pwd = "";
|
my $enc_pwd = "";
|
||||||
@ -1002,11 +1001,12 @@ sub StorePassword($@) {
|
|||||||
return "password successfully saved";
|
return "password successfully saved";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub ReadPassword($$) {
|
sub ReadPassword {
|
||||||
|
my $hash = shift;
|
||||||
|
my $name = shift;
|
||||||
|
|
||||||
my ( $hash, $name ) = @_;
|
my $index = $hash->{TYPE} . "_" . $name . "_passwd";
|
||||||
my $index = $hash->{TYPE} . "_" . $name . "_passwd";
|
my $key = getUniqueId() . $index;
|
||||||
my $key = getUniqueId() . $index;
|
|
||||||
my ( $password, $err );
|
my ( $password, $err );
|
||||||
|
|
||||||
Log3 $name, 4, "GardenaSmartBridge ($name) - Read password from file";
|
Log3 $name, 4, "GardenaSmartBridge ($name) - Read password from file";
|
||||||
@ -1045,22 +1045,25 @@ sub ReadPassword($$) {
|
|||||||
Log3 $name, 3, "GardenaSmartBridge ($name) - No password in file";
|
Log3 $name, 3, "GardenaSmartBridge ($name) - No password in file";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Rename(@) {
|
sub Rename {
|
||||||
|
my $new = shift;
|
||||||
|
my $old = shift;
|
||||||
|
|
||||||
my ( $new, $old ) = @_;
|
|
||||||
my $hash = $defs{$new};
|
my $hash = $defs{$new};
|
||||||
|
|
||||||
StorePassword( $hash, $new, ReadPassword($hash,$old) );
|
StorePassword( $hash, $new, ReadPassword( $hash, $old ) );
|
||||||
setKeyValue( $hash->{TYPE} . "_" . $old . "_passwd", undef );
|
setKeyValue( $hash->{TYPE} . "_" . $old . "_passwd", undef );
|
||||||
|
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub ParseJSON($$) {
|
sub ParseJSON {
|
||||||
|
my $hash = shift;
|
||||||
my ( $hash, $buffer ) = @_;
|
my $buffer = shift;
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $open = 0;
|
my $open = 0;
|
||||||
@ -1069,14 +1072,14 @@ sub ParseJSON($$) {
|
|||||||
my $tail = '';
|
my $tail = '';
|
||||||
|
|
||||||
if ($buffer) {
|
if ($buffer) {
|
||||||
foreach my $c ( split //, $buffer ) {
|
for my $c ( split //, $buffer ) {
|
||||||
if ( $open == $close and $open > 0 ) {
|
if ( $open == $close && $open > 0 ) {
|
||||||
$tail .= $c;
|
$tail .= $c;
|
||||||
Log3 $name, 5,
|
Log3 $name, 5,
|
||||||
"GardenaSmartBridge ($name) - $open == $close and $open > 0";
|
"GardenaSmartBridge ($name) - $open == $close and $open > 0";
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( ( $open == $close ) and ( $c ne '{' ) ) {
|
elsif ( ( $open == $close ) && ( $c ne '{' ) ) {
|
||||||
|
|
||||||
Log3 $name, 5,
|
Log3 $name, 5,
|
||||||
"GardenaSmartBridge ($name) - Garbage character before message: "
|
"GardenaSmartBridge ($name) - Garbage character before message: "
|
||||||
@ -1111,9 +1114,9 @@ sub ParseJSON($$) {
|
|||||||
return ( $msg, $tail );
|
return ( $msg, $tail );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub createHttpValueStrings($@) {
|
sub createHttpValueStrings {
|
||||||
|
|
||||||
my ( $hash, $payload, $deviceId, $abilities ) = @_;
|
my ( $hash, $payload, $deviceId, $abilities ) = @_;
|
||||||
|
|
||||||
my $session_id = $hash->{helper}{session_id};
|
my $session_id = $hash->{helper}{session_id};
|
||||||
my $header = "Content-Type: application/json";
|
my $header = "Content-Type: application/json";
|
||||||
my $uri = '';
|
my $uri = '';
|
||||||
@ -1121,25 +1124,25 @@ sub createHttpValueStrings($@) {
|
|||||||
$header .= "\r\nX-Session: $session_id"
|
$header .= "\r\nX-Session: $session_id"
|
||||||
if ( defined( $hash->{helper}{session_id} ) );
|
if ( defined( $hash->{helper}{session_id} ) );
|
||||||
$payload = '{' . $payload . '}' if ( defined($payload) );
|
$payload = '{' . $payload . '}' if ( defined($payload) );
|
||||||
$payload = '{}' if ( not defined($payload) );
|
$payload = '{}' if ( !defined($payload) );
|
||||||
|
|
||||||
if ( $payload eq '{}' ) {
|
if ( $payload eq '{}' ) {
|
||||||
$method = 'GET';
|
$method = 'GET';
|
||||||
$uri .= '/locations/?user_id=' . $hash->{helper}{user_id}
|
$uri .= '/locations/?user_id=' . $hash->{helper}{user_id}
|
||||||
if ( exists($hash->{helper}{user_id})
|
if ( exists( $hash->{helper}{user_id} )
|
||||||
and not defined( $hash->{helper}{locations_id} ) );
|
&& !defined( $hash->{helper}{locations_id} ) );
|
||||||
readingsSingleUpdate( $hash, 'state', 'fetch locationId', 1 )
|
readingsSingleUpdate( $hash, 'state', 'fetch locationId', 1 )
|
||||||
if ( not defined( $hash->{helper}{locations_id} ) );
|
if ( !defined( $hash->{helper}{locations_id} ) );
|
||||||
$uri .= '/sessions' if ( not defined( $hash->{helper}{session_id} ) );
|
$uri .= '/sessions' if ( !defined( $hash->{helper}{session_id} ) );
|
||||||
$uri .= '/devices'
|
$uri .= '/devices'
|
||||||
if ( not defined($abilities)
|
if (!defined($abilities)
|
||||||
and defined( $hash->{helper}{locations_id} ) );
|
&& defined( $hash->{helper}{locations_id} ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$uri .= '/sessions' if ( not defined( $hash->{helper}{session_id} ) );
|
$uri .= '/sessions' if ( !defined( $hash->{helper}{session_id} ) );
|
||||||
|
|
||||||
if ( defined( $hash->{helper}{locations_id} ) ) {
|
if ( defined( $hash->{helper}{locations_id} ) ) {
|
||||||
if ( defined($abilities) and $abilities eq 'mower_settings' ) {
|
if ( defined($abilities) && $abilities eq 'mower_settings' ) {
|
||||||
|
|
||||||
$method = 'PUT';
|
$method = 'PUT';
|
||||||
my $dhash = $modules{GardenaSmartDevice}{defptr}{$deviceId};
|
my $dhash = $modules{GardenaSmartDevice}{defptr}{$deviceId};
|
||||||
@ -1148,14 +1151,14 @@ sub createHttpValueStrings($@) {
|
|||||||
. $deviceId
|
. $deviceId
|
||||||
. '/settings/'
|
. '/settings/'
|
||||||
. $dhash->{helper}{STARTINGPOINTID}
|
. $dhash->{helper}{STARTINGPOINTID}
|
||||||
if ( defined($abilities)
|
if ( defined($abilities)
|
||||||
and defined($payload)
|
&& defined($payload)
|
||||||
and $abilities eq 'mower_settings' );
|
&& $abilities eq 'mower_settings' );
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( defined($abilities)
|
elsif (defined($abilities)
|
||||||
and defined($payload)
|
&& defined($payload)
|
||||||
and $abilities eq 'watering' )
|
&& $abilities eq 'watering' )
|
||||||
{
|
{
|
||||||
my $valve_id;
|
my $valve_id;
|
||||||
$method = 'PUT';
|
$method = 'PUT';
|
||||||
@ -1172,9 +1175,9 @@ sub createHttpValueStrings($@) {
|
|||||||
. $valve_id;
|
. $valve_id;
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( defined($abilities)
|
elsif (defined($abilities)
|
||||||
and defined($payload)
|
&& defined($payload)
|
||||||
and $abilities eq 'manual_watering' )
|
&& $abilities eq 'manual_watering' )
|
||||||
{
|
{
|
||||||
my $valve_id;
|
my $valve_id;
|
||||||
$method = 'PUT';
|
$method = 'PUT';
|
||||||
@ -1187,9 +1190,9 @@ sub createHttpValueStrings($@) {
|
|||||||
. '/properties/manual_watering_timer';
|
. '/properties/manual_watering_timer';
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( defined($abilities)
|
elsif (defined($abilities)
|
||||||
and defined($payload)
|
&& defined($payload)
|
||||||
and $abilities eq 'power' )
|
&& $abilities eq 'power' )
|
||||||
{
|
{
|
||||||
my $valve_id;
|
my $valve_id;
|
||||||
$method = 'PUT';
|
$method = 'PUT';
|
||||||
@ -1205,7 +1208,7 @@ sub createHttpValueStrings($@) {
|
|||||||
else {
|
else {
|
||||||
$uri .=
|
$uri .=
|
||||||
'/devices/' . $deviceId . '/abilities/' . $abilities . '/command'
|
'/devices/' . $deviceId . '/abilities/' . $abilities . '/command'
|
||||||
if ( defined($abilities) and defined($payload) );
|
if ( defined($abilities) && defined($payload) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$uri .= '?locationId=' . $hash->{helper}{locations_id};
|
$uri .= '?locationId=' . $hash->{helper}{locations_id};
|
||||||
@ -1215,13 +1218,12 @@ sub createHttpValueStrings($@) {
|
|||||||
$abilities );
|
$abilities );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub DeletePassword($) {
|
sub DeletePassword {
|
||||||
|
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
|
|
||||||
setKeyValue( $hash->{TYPE} . "_" . $hash->{NAME} . "_passwd", undef );
|
setKeyValue( $hash->{TYPE} . "_" . $hash->{NAME} . "_passwd", undef );
|
||||||
|
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
@ -1373,6 +1375,7 @@ sub DeletePassword($) {
|
|||||||
],
|
],
|
||||||
"release_status": "stable",
|
"release_status": "stable",
|
||||||
"license": "GPL_2",
|
"license": "GPL_2",
|
||||||
|
"version": "v2.0.0",
|
||||||
"author": [
|
"author": [
|
||||||
"Marko Oldenburg <leongaultier@gmail.com>"
|
"Marko Oldenburg <leongaultier@gmail.com>"
|
||||||
],
|
],
|
||||||
|
@ -55,18 +55,13 @@
|
|||||||
|
|
||||||
## unserer packagename
|
## unserer packagename
|
||||||
package FHEM::GardenaSmartDevice;
|
package FHEM::GardenaSmartDevice;
|
||||||
|
use GPUtils qw(GP_Import GP_Export);
|
||||||
use GPUtils qw(GP_Import)
|
|
||||||
; # wird für den Import der FHEM Funktionen aus der fhem.pl benötigt
|
|
||||||
|
|
||||||
my $missingModul = "";
|
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use POSIX;
|
use POSIX;
|
||||||
use FHEM::Meta;
|
use FHEM::Meta;
|
||||||
use Time::Local;
|
use Time::Local;
|
||||||
our $VERSION = '1.6.7';
|
|
||||||
|
|
||||||
# try to use JSON::MaybeXS wrapper
|
# try to use JSON::MaybeXS wrapper
|
||||||
# for chance of better performance + open code
|
# for chance of better performance + open code
|
||||||
@ -163,70 +158,51 @@ BEGIN {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# _Export - Export references to main context using a different naming schema
|
|
||||||
sub _Export {
|
|
||||||
no strict qw/refs/; ## no critic
|
|
||||||
my $pkg = caller(0);
|
|
||||||
my $main = $pkg;
|
|
||||||
$main =~ s/^(?:.+::)?([^:]+)$/main::$1\_/g;
|
|
||||||
foreach (@_) {
|
|
||||||
*{ $main . $_ } = *{ $pkg . '::' . $_ };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#-- Export to main context with different name
|
#-- Export to main context with different name
|
||||||
_Export(
|
GP_Export(
|
||||||
qw(
|
qw(
|
||||||
Initialize
|
Initialize
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
sub Initialize($) {
|
sub Initialize {
|
||||||
|
my $hash = shift;
|
||||||
my ($hash) = @_;
|
|
||||||
|
|
||||||
$hash->{Match} = '^{"id":".*';
|
$hash->{Match} = '^{"id":".*';
|
||||||
|
|
||||||
$hash->{SetFn} = "FHEM::GardenaSmartDevice::Set";
|
$hash->{SetFn} = \&Set;
|
||||||
$hash->{DefFn} = "FHEM::GardenaSmartDevice::Define";
|
$hash->{DefFn} = \&Define;
|
||||||
$hash->{UndefFn} = "FHEM::GardenaSmartDevice::Undef";
|
$hash->{UndefFn} = \&Undef;
|
||||||
$hash->{ParseFn} = "FHEM::GardenaSmartDevice::Parse";
|
$hash->{ParseFn} = \&Parse;
|
||||||
|
|
||||||
$hash->{AttrFn} = "FHEM::GardenaSmartDevice::Attr";
|
$hash->{AttrFn} = \&Attr;
|
||||||
$hash->{AttrList} =
|
$hash->{AttrList} =
|
||||||
"readingValueLanguage:de,en "
|
"readingValueLanguage:de,en "
|
||||||
. "model:watering_computer,sensor,mower,ic24,power,electronic_pressure_pump "
|
. "model:watering_computer,sensor,mower,ic24,power,electronic_pressure_pump "
|
||||||
. "IODev "
|
. "IODev "
|
||||||
. $readingFnAttributes;
|
. $readingFnAttributes;
|
||||||
|
$hash->{parseParams} = 1;
|
||||||
foreach my $d ( sort keys %{ $modules{GardenaSmartDevice}{defptr} } ) {
|
|
||||||
|
|
||||||
my $hash = $modules{GardenaSmartDevice}{defptr}{$d};
|
|
||||||
$hash->{VERSION} = $VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FHEM::Meta::InitMod( __FILE__, $hash );
|
return FHEM::Meta::InitMod( __FILE__, $hash );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Define($$) {
|
sub Define {
|
||||||
|
my $hash = shift;
|
||||||
my ( $hash, $def ) = @_;
|
my $a = shift;
|
||||||
my @a = split( "[ \t]+", $def );
|
|
||||||
|
|
||||||
return $@ unless ( FHEM::Meta::SetInternals($hash) );
|
return $@ unless ( FHEM::Meta::SetInternals($hash) );
|
||||||
|
use version 0.60; our $VERSION = FHEM::Meta::Get( $hash, 'version' );
|
||||||
|
|
||||||
return
|
return
|
||||||
"too few parameters: define <NAME> GardenaSmartDevice <device_Id> <model>"
|
"too few parameters: define <NAME> GardenaSmartDevice <device_Id> <model>"
|
||||||
if ( @a < 3 );
|
if ( scalar( @{$a} ) < 3 );
|
||||||
return
|
|
||||||
"Cannot define Gardena Bridge device. Perl modul $missingModul is missing."
|
|
||||||
if ($missingModul);
|
|
||||||
|
|
||||||
my $name = $a[0];
|
my $name = $a->[0];
|
||||||
my $deviceId = $a[2];
|
my $deviceId = $a->[2];
|
||||||
my $category = $a[3];
|
my $category = $a->[3];
|
||||||
|
|
||||||
$hash->{DEVICEID} = $deviceId;
|
$hash->{DEVICEID} = $deviceId;
|
||||||
$hash->{VERSION} = $VERSION;
|
$hash->{VERSION} = version->parse($VERSION)->normal;
|
||||||
$hash->{helper}{STARTINGPOINTID} = '';
|
$hash->{helper}{STARTINGPOINTID} = '';
|
||||||
|
|
||||||
CommandAttr( undef,
|
CommandAttr( undef,
|
||||||
@ -251,9 +227,9 @@ sub Define($$) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
"GardenaSmartDevice device $name on GardenaSmartBridge $iodev already defined."
|
"GardenaSmartDevice device $name on GardenaSmartBridge $iodev already defined."
|
||||||
if ( defined($d)
|
if ( defined($d)
|
||||||
and $d->{IODev} == $hash->{IODev}
|
&& $d->{IODev} == $hash->{IODev}
|
||||||
and $d->{NAME} ne $name );
|
&& $d->{NAME} ne $name );
|
||||||
|
|
||||||
CommandAttr( undef, $name . ' room GardenaSmart' )
|
CommandAttr( undef, $name . ' room GardenaSmart' )
|
||||||
if ( AttrVal( $name, 'room', 'none' ) eq 'none' );
|
if ( AttrVal( $name, 'room', 'none' ) eq 'none' );
|
||||||
@ -267,100 +243,107 @@ sub Define($$) {
|
|||||||
|
|
||||||
$modules{GardenaSmartDevice}{defptr}{$deviceId} = $hash;
|
$modules{GardenaSmartDevice}{defptr}{$deviceId} = $hash;
|
||||||
|
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Undef($$) {
|
sub Undef {
|
||||||
|
my $hash = shift;
|
||||||
|
my $arg = shift;
|
||||||
|
|
||||||
my ( $hash, $arg ) = @_;
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $deviceId = $hash->{DEVICEID};
|
my $deviceId = $hash->{DEVICEID};
|
||||||
|
|
||||||
delete $modules{GardenaSmartDevice}{defptr}{$deviceId};
|
delete $modules{GardenaSmartDevice}{defptr}{$deviceId};
|
||||||
|
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Attr(@) {
|
sub Attr {
|
||||||
|
|
||||||
my ( $cmd, $name, $attrName, $attrVal ) = @_;
|
my ( $cmd, $name, $attrName, $attrVal ) = @_;
|
||||||
my $hash = $defs{$name};
|
my $hash = $defs{$name};
|
||||||
|
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Set($@) {
|
sub Set {
|
||||||
|
my $hash = shift;
|
||||||
|
my $a = shift;
|
||||||
|
|
||||||
my ( $hash, $name, $cmd, @args ) = @_;
|
my $name = shift @$a;
|
||||||
|
my $cmd = shift @$a // return qq{"set $name" needs at least one argument};
|
||||||
|
|
||||||
my $payload;
|
my $payload;
|
||||||
my $abilities = '';
|
my $abilities = '';
|
||||||
|
|
||||||
### mower
|
### mower
|
||||||
if ( lc $cmd eq 'parkuntilfurthernotice' ) {
|
if ( lc $cmd eq 'parkuntilfurthernotice' ) {
|
||||||
|
|
||||||
$payload = '"name":"park_until_further_notice"';
|
$payload = '"name":"park_until_further_notice"';
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( lc $cmd eq 'parkuntilnexttimer' ) {
|
elsif ( lc $cmd eq 'parkuntilnexttimer' ) {
|
||||||
|
|
||||||
$payload = '"name":"park_until_next_timer"';
|
$payload = '"name":"park_until_next_timer"';
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( lc $cmd eq 'startresumeschedule' ) {
|
elsif ( lc $cmd eq 'startresumeschedule' ) {
|
||||||
|
|
||||||
$payload = '"name":"start_resume_schedule"';
|
$payload = '"name":"start_resume_schedule"';
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( lc $cmd eq 'startoverridetimer' ) {
|
elsif ( lc $cmd eq 'startoverridetimer' ) {
|
||||||
|
|
||||||
my $duration = join( " ", @args );
|
|
||||||
$payload = '"name":"start_override_timer","parameters":{"duration":'
|
$payload = '"name":"start_override_timer","parameters":{"duration":'
|
||||||
. $duration * 60 . '}';
|
. $a->[0] * 60 . '}';
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( lc $cmd eq 'startpoint' ) {
|
elsif ( lc $cmd eq 'startpoint' ) {
|
||||||
my $err;
|
my $err;
|
||||||
|
|
||||||
( $err, $payload, $abilities ) =
|
( $err, $payload, $abilities ) = SetPredefinedStartPoints( $hash, @$a );
|
||||||
SetPredefinedStartPoints( $hash, @args );
|
|
||||||
return $err if ( defined($err) );
|
return $err if ( defined($err) );
|
||||||
|
|
||||||
}
|
}
|
||||||
### electronic_pressure_pump
|
### electronic_pressure_pump
|
||||||
elsif ( lc $cmd eq 'pumptimer' ) {
|
elsif ( lc $cmd eq 'pumptimer' ) {
|
||||||
|
|
||||||
my $duration = join( " ", @args );
|
|
||||||
|
|
||||||
$payload =
|
$payload =
|
||||||
'"name":"pump_manual_watering_timer","parameters":{"duration":'
|
'"name":"pump_manual_watering_timer","parameters":{"duration":'
|
||||||
. $duration . '}';
|
. $a->[0] . '}';
|
||||||
}
|
}
|
||||||
### watering_computer
|
### watering_computer
|
||||||
elsif ( lc $cmd eq 'manualoverride' ) {
|
elsif ( lc $cmd eq 'manualoverride' ) {
|
||||||
|
$payload =
|
||||||
my $duration = join( " ", @args );
|
'"properties":{"name":"watering_timer_1'
|
||||||
$payload = '"name":"manual_override","parameters":{"duration":'
|
. '","value":{"state":"manual","duration":'
|
||||||
. $duration . '}';
|
. $a->[0] * 60
|
||||||
|
. ',"valve_id":1}}';
|
||||||
}
|
}
|
||||||
elsif ( lc $cmd eq 'canceloverride' ) {
|
elsif ( $cmd =~ m{\AcancelOverride}xms ) {
|
||||||
|
|
||||||
$payload = '"name":"cancel_override"';
|
my $valve_id = 1;
|
||||||
|
|
||||||
|
if ( $cmd =~ m{\AcancelOverrideValve(\d)\z}xms ) {
|
||||||
|
$valve_id = $1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload =
|
||||||
|
'"properties":{"name":"watering_timer_'
|
||||||
|
. $valve_id
|
||||||
|
. '","value":{"state":"idle","duration":'
|
||||||
|
. 0
|
||||||
|
. ',"valve_id":'
|
||||||
|
. $valve_id . '}}';
|
||||||
}
|
}
|
||||||
elsif ( lc $cmd eq 'on' or lc $cmd eq 'off' or lc $cmd eq 'on-for-timer' ) {
|
elsif ( lc $cmd eq 'on' || lc $cmd eq 'off' || lc $cmd eq 'on-for-timer' ) {
|
||||||
|
my $val = (
|
||||||
|
defined($a) && ref($a) eq 'ARRAY'
|
||||||
|
? $a->[0] * 60
|
||||||
|
: lc $cmd
|
||||||
|
);
|
||||||
|
|
||||||
my $val = ( defined( $args[0] ) ? join( " ", @args ) * 60 : lc $cmd );
|
|
||||||
$payload = '"properties":{"value":"' . $val . '"}';
|
$payload = '"properties":{"value":"' . $val . '"}';
|
||||||
}
|
}
|
||||||
### Watering ic24
|
### Watering ic24
|
||||||
elsif ( $cmd =~ /manualDurationValve/ ) {
|
elsif ( $cmd =~ m{\AmanualDurationValve\d\z}xms ) {
|
||||||
|
|
||||||
my $valve_id;
|
my $valve_id;
|
||||||
my $duration = join( " ", @args );
|
|
||||||
|
|
||||||
if ( $cmd =~ m#(\d)$# ) {
|
if ( $cmd =~ m{\AmanualDurationValve(\d)\z}xms ) {
|
||||||
$valve_id = $1;
|
$valve_id = $1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,14 +351,14 @@ sub Set($@) {
|
|||||||
'"properties":{"name":"watering_timer_'
|
'"properties":{"name":"watering_timer_'
|
||||||
. $valve_id
|
. $valve_id
|
||||||
. '","value":{"state":"manual","duration":'
|
. '","value":{"state":"manual","duration":'
|
||||||
. $duration * 60
|
. $a->[0] * 60
|
||||||
. ',"valve_id":'
|
. ',"valve_id":'
|
||||||
. $valve_id . '}}';
|
. $valve_id . '}}';
|
||||||
}
|
}
|
||||||
### Sensors
|
### Sensors
|
||||||
elsif ( lc $cmd eq 'refresh' ) {
|
elsif ( lc $cmd eq 'refresh' ) {
|
||||||
|
|
||||||
my $sensname = join( " ", @args );
|
my $sensname = $a->[0];
|
||||||
if ( lc $sensname eq 'temperature' ) {
|
if ( lc $sensname eq 'temperature' ) {
|
||||||
$payload = '"name":"measure_ambient_temperature"';
|
$payload = '"name":"measure_ambient_temperature"';
|
||||||
$abilities = 'ambient_temperature';
|
$abilities = 'ambient_temperature';
|
||||||
@ -395,18 +378,12 @@ sub Set($@) {
|
|||||||
else {
|
else {
|
||||||
|
|
||||||
my $list = '';
|
my $list = '';
|
||||||
$list .=
|
|
||||||
'parkUntilFurtherNotice:noArg parkUntilNextTimer:noArg startResumeSchedule:noArg startOverrideTimer:slider,0,1,60 startpoint'
|
|
||||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' );
|
|
||||||
|
|
||||||
$list .= 'manualOverride:slider,0,1,59 cancelOverride:noArg'
|
$list .= 'manualOverride:slider,1,1,59 cancelOverride:noArg'
|
||||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
|
if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
|
||||||
|
|
||||||
# $list .= 'pumpTimer:slider,0,1,59'
|
|
||||||
# if ( AttrVal( $name, 'model', 'unknown' ) eq 'electronic_pressure_pump' );
|
|
||||||
|
|
||||||
$list .=
|
$list .=
|
||||||
'manualDurationValve1:slider,1,1,59 manualDurationValve2:slider,1,1,59 manualDurationValve3:slider,1,1,59 manualDurationValve4:slider,1,1,59 manualDurationValve5:slider,1,1,59 manualDurationValve6:slider,1,1,59'
|
'manualDurationValve1:slider,1,1,59 manualDurationValve2:slider,1,1,59 manualDurationValve3:slider,1,1,59 manualDurationValve4:slider,1,1,59 manualDurationValve5:slider,1,1,59 manualDurationValve6:slider,1,1,59 cancelOverrideValve1:noArg cancelOverrideValve2:noArg cancelOverrideValve3:noArg cancelOverrideValve4:noArg cancelOverrideValve5:noArg cancelOverrideValve6:noArg'
|
||||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
|
if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
|
||||||
|
|
||||||
$list .= 'refresh:temperature,light,humidity'
|
$list .= 'refresh:temperature,light,humidity'
|
||||||
@ -420,11 +397,10 @@ sub Set($@) {
|
|||||||
|
|
||||||
$abilities = 'mower'
|
$abilities = 'mower'
|
||||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' )
|
if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' )
|
||||||
and $abilities ne 'mower_settings';
|
&& $abilities ne 'mower_settings';
|
||||||
$abilities = 'outlet'
|
|
||||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
|
|
||||||
$abilities = 'watering'
|
$abilities = 'watering'
|
||||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
|
if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24'
|
||||||
|
|| AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
|
||||||
$abilities = 'power'
|
$abilities = 'power'
|
||||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'power' );
|
if ( AttrVal( $name, 'model', 'unknown' ) eq 'power' );
|
||||||
$abilities = 'manual_watering'
|
$abilities = 'manual_watering'
|
||||||
@ -437,12 +413,12 @@ sub Set($@) {
|
|||||||
Log3 $name, 4,
|
Log3 $name, 4,
|
||||||
"GardenaSmartBridge ($name) - IOWrite: $payload $hash->{DEVICEID} $abilities IODevHash=$hash->{IODev}";
|
"GardenaSmartBridge ($name) - IOWrite: $payload $hash->{DEVICEID} $abilities IODevHash=$hash->{IODev}";
|
||||||
|
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Parse($$) {
|
sub Parse {
|
||||||
|
my $io_hash = shift;
|
||||||
my ( $io_hash, $json ) = @_;
|
my $json = shift;
|
||||||
|
|
||||||
my $name = $io_hash->{NAME};
|
my $name = $io_hash->{NAME};
|
||||||
|
|
||||||
@ -481,11 +457,13 @@ sub Parse($$) {
|
|||||||
. " GardenaSmartDevice $decode_json->{id} $decode_json->{category}";
|
. " GardenaSmartDevice $decode_json->{id} $decode_json->{category}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub WriteReadings($$) {
|
sub WriteReadings {
|
||||||
|
my $hash = shift;
|
||||||
my ( $hash, $decode_json ) = @_;
|
my $decode_json = shift;
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $abilities = scalar( @{ $decode_json->{abilities} } );
|
my $abilities = scalar( @{ $decode_json->{abilities} } );
|
||||||
@ -497,11 +475,10 @@ sub WriteReadings($$) {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
ref( $decode_json->{abilities}[$abilities]{properties} ) eq "ARRAY"
|
ref( $decode_json->{abilities}[$abilities]{properties} ) eq "ARRAY"
|
||||||
and
|
&& scalar( @{ $decode_json->{abilities}[$abilities]{properties} } )
|
||||||
scalar( @{ $decode_json->{abilities}[$abilities]{properties} } ) >
|
> 0 )
|
||||||
0 )
|
|
||||||
{
|
{
|
||||||
foreach my $propertie (
|
for my $propertie (
|
||||||
@{ $decode_json->{abilities}[$abilities]{properties} } )
|
@{ $decode_json->{abilities}[$abilities]{properties} } )
|
||||||
{
|
{
|
||||||
readingsBulkUpdateIfChanged(
|
readingsBulkUpdateIfChanged(
|
||||||
@ -511,21 +488,21 @@ sub WriteReadings($$) {
|
|||||||
RigRadingsValue( $hash, $propertie->{value} )
|
RigRadingsValue( $hash, $propertie->{value} )
|
||||||
)
|
)
|
||||||
if ( defined( $propertie->{value} )
|
if ( defined( $propertie->{value} )
|
||||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
&& $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} ne 'radio-quality'
|
. $propertie->{name} ne 'radio-quality'
|
||||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
&& $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} ne 'battery-level'
|
. $propertie->{name} ne 'battery-level'
|
||||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
&& $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} ne 'internal_temperature-temperature'
|
. $propertie->{name} ne 'internal_temperature-temperature'
|
||||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
&& $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} ne 'ambient_temperature-temperature'
|
. $propertie->{name} ne 'ambient_temperature-temperature'
|
||||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
&& $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} ne 'soil_temperature-temperature'
|
. $propertie->{name} ne 'soil_temperature-temperature'
|
||||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
&& $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} ne 'humidity-humidity'
|
. $propertie->{name} ne 'humidity-humidity'
|
||||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
&& $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} ne 'light-light'
|
. $propertie->{name} ne 'light-light'
|
||||||
and ref( $propertie->{value} ) ne "HASH" );
|
&& ref( $propertie->{value} ) ne "HASH" );
|
||||||
|
|
||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
@ -535,21 +512,21 @@ sub WriteReadings($$) {
|
|||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
defined( $propertie->{value} )
|
defined( $propertie->{value} )
|
||||||
and ( $decode_json->{abilities}[$abilities]{name} . '-'
|
&& ( $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} eq 'radio-quality'
|
. $propertie->{name} eq 'radio-quality'
|
||||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
|| $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} eq 'battery-level'
|
. $propertie->{name} eq 'battery-level'
|
||||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
|| $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} eq
|
. $propertie->{name} eq
|
||||||
'internal_temperature-temperature'
|
'internal_temperature-temperature'
|
||||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
|| $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} eq
|
. $propertie->{name} eq
|
||||||
'ambient_temperature-temperature'
|
'ambient_temperature-temperature'
|
||||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
|| $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} eq 'soil_temperature-temperature'
|
. $propertie->{name} eq 'soil_temperature-temperature'
|
||||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
|| $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} eq 'humidity-humidity'
|
. $propertie->{name} eq 'humidity-humidity'
|
||||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
|| $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} eq 'light-light' )
|
. $propertie->{name} eq 'light-light' )
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -560,7 +537,7 @@ sub WriteReadings($$) {
|
|||||||
join( ',', @{ $propertie->{value} } )
|
join( ',', @{ $propertie->{value} } )
|
||||||
)
|
)
|
||||||
if ( defined( $propertie->{value} )
|
if ( defined( $propertie->{value} )
|
||||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
&& $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} eq 'ic24-valves_connected' );
|
. $propertie->{name} eq 'ic24-valves_connected' );
|
||||||
|
|
||||||
readingsBulkUpdateIfChanged(
|
readingsBulkUpdateIfChanged(
|
||||||
@ -570,7 +547,7 @@ sub WriteReadings($$) {
|
|||||||
join( ',', @{ $propertie->{value} } )
|
join( ',', @{ $propertie->{value} } )
|
||||||
)
|
)
|
||||||
if ( defined( $propertie->{value} )
|
if ( defined( $propertie->{value} )
|
||||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
&& $decode_json->{abilities}[$abilities]{name} . '-'
|
||||||
. $propertie->{name} eq 'ic24-valves_master_config' );
|
. $propertie->{name} eq 'ic24-valves_master_config' );
|
||||||
|
|
||||||
if ( ref( $propertie->{value} ) eq "HASH" ) {
|
if ( ref( $propertie->{value} ) eq "HASH" ) {
|
||||||
@ -593,7 +570,7 @@ sub WriteReadings($$) {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
if ( ref( $decode_json->{settings}[$settings]{value} ) eq "ARRAY"
|
if ( ref( $decode_json->{settings}[$settings]{value} ) eq "ARRAY"
|
||||||
and $decode_json->{settings}[$settings]{name} eq 'starting_points' )
|
&& $decode_json->{settings}[$settings]{name} eq 'starting_points' )
|
||||||
{
|
{
|
||||||
#save the startingpointid needed to update the startingpoints
|
#save the startingpointid needed to update the startingpoints
|
||||||
if ( $hash->{helper}{STARTINGPOINTID} ne
|
if ( $hash->{helper}{STARTINGPOINTID} ne
|
||||||
@ -608,7 +585,7 @@ sub WriteReadings($$) {
|
|||||||
. encode_json( $decode_json->{settings}[$settings]{value} ) . '}';
|
. encode_json( $decode_json->{settings}[$settings]{value} ) . '}';
|
||||||
my $startpoint_cnt = 0;
|
my $startpoint_cnt = 0;
|
||||||
|
|
||||||
foreach my $startingpoint (
|
for my $startingpoint (
|
||||||
@{ $decode_json->{settings}[$settings]{value} } )
|
@{ $decode_json->{settings}[$settings]{value} } )
|
||||||
{
|
{
|
||||||
$startpoint_cnt++;
|
$startpoint_cnt++;
|
||||||
@ -629,9 +606,9 @@ sub WriteReadings($$) {
|
|||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash, 'state',
|
$hash, 'state',
|
||||||
(
|
(
|
||||||
ReadingsVal( $name, 'outlet-valve_open', 0 ) == 1
|
ReadingsVal( $name, 'watering-watering_timer_1_state', 0 ) eq 'idle'
|
||||||
? RigRadingsValue( $hash, 'open' )
|
? RigRadingsValue( $hash, 'closed' )
|
||||||
: RigRadingsValue( $hash, 'closed' )
|
: RigRadingsValue( $hash, 'open' )
|
||||||
)
|
)
|
||||||
) if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
|
) if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
|
||||||
|
|
||||||
@ -664,17 +641,19 @@ sub WriteReadings($$) {
|
|||||||
readingsEndUpdate( $hash, 1 );
|
readingsEndUpdate( $hash, 1 );
|
||||||
|
|
||||||
Log3 $name, 4, "GardenaSmartDevice ($name) - readings was written}";
|
Log3 $name, 4, "GardenaSmartDevice ($name) - readings was written}";
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
##################################
|
##################################
|
||||||
##################################
|
##################################
|
||||||
#### my little helpers ###########
|
#### my little helpers ###########
|
||||||
|
|
||||||
sub ReadingLangGerman($$) {
|
sub ReadingLangGerman {
|
||||||
|
my $hash = shift;
|
||||||
my ( $hash, $readingValue ) = @_;
|
my $readingValue = shift;
|
||||||
my $name = $hash->{NAME};
|
|
||||||
|
|
||||||
|
my $name = $hash->{NAME};
|
||||||
my %langGermanMapp = (
|
my %langGermanMapp = (
|
||||||
'ok_cutting' => 'mähen',
|
'ok_cutting' => 'mähen',
|
||||||
'paused' => 'pausiert',
|
'paused' => 'pausiert',
|
||||||
@ -777,9 +756,9 @@ sub ReadingLangGerman($$) {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
defined( $langGermanMapp{$readingValue} )
|
defined( $langGermanMapp{$readingValue} )
|
||||||
and ( AttrVal( 'global', 'language', 'none' ) eq 'DE'
|
&& ( AttrVal( 'global', 'language', 'none' ) eq 'DE'
|
||||||
or AttrVal( $name, 'readingValueLanguage', 'none' ) eq 'de' )
|
|| AttrVal( $name, 'readingValueLanguage', 'none' ) eq 'de' )
|
||||||
and AttrVal( $name, 'readingValueLanguage', 'none' ) ne 'en'
|
&& AttrVal( $name, 'readingValueLanguage', 'none' ) ne 'en'
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return $langGermanMapp{$readingValue};
|
return $langGermanMapp{$readingValue};
|
||||||
@ -787,11 +766,13 @@ sub ReadingLangGerman($$) {
|
|||||||
else {
|
else {
|
||||||
return $readingValue;
|
return $readingValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub RigRadingsValue($$) {
|
sub RigRadingsValue {
|
||||||
|
my $hash = shift;
|
||||||
my ( $hash, $readingValue ) = @_;
|
my $readingValue = shift;
|
||||||
|
|
||||||
my $rigReadingValue;
|
my $rigReadingValue;
|
||||||
|
|
||||||
@ -805,9 +786,9 @@ sub RigRadingsValue($$) {
|
|||||||
return $rigReadingValue;
|
return $rigReadingValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Zulu2LocalString($) {
|
sub Zulu2LocalString {
|
||||||
|
|
||||||
my $t = shift;
|
my $t = shift;
|
||||||
|
|
||||||
my ( $datehour, $datemin, $rest ) = split( /:/, $t, 3 );
|
my ( $datehour, $datemin, $rest ) = split( /:/, $t, 3 );
|
||||||
|
|
||||||
my ( $year, $month, $day, $hour, $min ) =
|
my ( $year, $month, $day, $hour, $min ) =
|
||||||
@ -840,18 +821,23 @@ sub Zulu2LocalString($) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub SetPredefinedStartPoints($@) {
|
sub SetPredefinedStartPoints {
|
||||||
|
my $hash = shift;
|
||||||
|
my $a = shift;
|
||||||
|
|
||||||
|
my ( $startpoint_state, $startpoint_num, @morestartpoints ) = @$a;
|
||||||
|
|
||||||
my ( $hash, $startpoint_state, $startpoint_num, @morestartpoints ) = @_;
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $payload;
|
my $payload;
|
||||||
my $abilities;
|
my $abilities;
|
||||||
|
|
||||||
if ( defined($startpoint_state) and defined($startpoint_num) ) {
|
if ( defined($startpoint_state) && defined($startpoint_num) ) {
|
||||||
if ( defined( $hash->{helper}{STARTINGPOINTS} )
|
if ( defined( $hash->{helper}{STARTINGPOINTS} )
|
||||||
and $hash->{helper}{STARTINGPOINTS} ne '' )
|
&& $hash->{helper}{STARTINGPOINTS} ne '' )
|
||||||
{
|
{
|
||||||
# add needed parameters to saved settings config and change the value in request
|
# add needed parameters to saved settings config and change the value in request
|
||||||
my $decode_json_settings =
|
my $decode_json_settings =
|
||||||
@ -869,8 +855,8 @@ sub SetPredefinedStartPoints($@) {
|
|||||||
#set more startpoints
|
#set more startpoints
|
||||||
if (
|
if (
|
||||||
defined scalar(@morestartpoints)
|
defined scalar(@morestartpoints)
|
||||||
and ( scalar(@morestartpoints) == 2
|
&& ( scalar(@morestartpoints) == 2
|
||||||
or scalar(@morestartpoints) == 4 )
|
|| scalar(@morestartpoints) == 4 )
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if ( scalar(@morestartpoints) == 2 ) {
|
if ( scalar(@morestartpoints) == 2 ) {
|
||||||
@ -1221,6 +1207,7 @@ sub SetPredefinedStartPoints($@) {
|
|||||||
],
|
],
|
||||||
"release_status": "stable",
|
"release_status": "stable",
|
||||||
"license": "GPL_2",
|
"license": "GPL_2",
|
||||||
|
"version": "v2.0.0",
|
||||||
"author": [
|
"author": [
|
||||||
"Marko Oldenburg <leongaultier@gmail.com>"
|
"Marko Oldenburg <leongaultier@gmail.com>"
|
||||||
],
|
],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user