Compare commits
	
		
			250 Commits
		
	
	
		
			v2.4.0
			...
			c2863d9998
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c2863d9998 | |||
| 
						 | 
					76a7eeb4e5 | ||
| 
						 | 
					388ae1635e | ||
| 
						 | 
					d660366aea | ||
| 
						 | 
					8b9ce793cd | ||
| 
						 | 
					71b435d90b | ||
| 
						 | 
					c86cae74e6 | ||
| 
						 | 
					8ce2980356 | ||
| 
						 | 
					0d29721111 | ||
| 
						 | 
					ade45510ac | ||
| 
						 | 
					8a32c9f215 | ||
| 
						 | 
					78b5731bbf | ||
| 
						 | 
					0ee95be7be | ||
| 
						 | 
					bae27c39c1 | ||
| 
						 | 
					47804c996b | ||
| 
						 | 
					6a7083f6ea | ||
| 
						 | 
					ada7e2875c | ||
| 
						 | 
					658f40e979 | ||
| 
						 | 
					1c7097e476 | ||
| 
						 | 
					e363b45862 | ||
| 
						 | 
					11c5e6650d | ||
| 
						 | 
					4b998d19ab | ||
| 
						 | 
					7f6c7bc265 | ||
| 
						 | 
					e108afda5a | ||
| 
						 | 
					a13c42f08c | ||
| 
						 | 
					df33172650 | ||
| 
						 | 
					f3d153726b | ||
| 
						 | 
					33a10d3756 | ||
| 
						 | 
					abcccefeb4 | ||
| 
						 | 
					f61e9d327b | ||
| 42afa2133e | |||
| 
						 | 
					6aba15caca | ||
| 1abf586f71 | |||
| f02da0c428 | |||
| fd4ac49f59 | |||
| 73d7c50db0 | |||
| f5ec4f699a | |||
| 
						 | 
					f2400a3949 | ||
| 
						 | 
					63443d75b4 | ||
| 
						 | 
					5e87026852 | ||
| 
						 | 
					c6ee46489b | ||
| 
						 | 
					97540ef9c4 | ||
| 
						 | 
					0c75c89cf0 | ||
| 
						 | 
					93d0ef26c7 | ||
| 
						 | 
					9b49c75317 | ||
| 
						 | 
					5e10125a09 | ||
| 
						 | 
					9e389681f0 | ||
| 
						 | 
					5b8bd75c55 | ||
| 
						 | 
					f77f49b7f1 | ||
| 
						 | 
					43d9356d8c | ||
| 
						 | 
					41c226536f | ||
| 
						 | 
					ec88be0b06 | ||
| 
						 | 
					8ce72c5ddc | ||
| 
						 | 
					9643a9074f | ||
| 
						 | 
					6f1eebcf48 | ||
| 
						 | 
					c084fabc92 | ||
| 188f5d3838 | |||
| 9d70fa238a | |||
| 740effe531 | |||
| 426fb7c06a | |||
| 
						 | 
					782ad5f0a9 | ||
| 41ef5cd10a | |||
| 
						 | 
					6d684ade92 | ||
| 
						 | 
					bc4b6eecf5 | ||
| 
						 | 
					e8c2bd5183 | ||
| 
						 | 
					967ec86ea1 | ||
| 
						 | 
					0086f52d74 | ||
| 
						 | 
					54b378d094 | ||
| 
						 | 
					200751b72b | ||
| 
						 | 
					7cefd1c7e3 | ||
| 
						 | 
					ee0c7fa4ba | ||
| 
						 | 
					ae3bf5f68a | ||
| 
						 | 
					929bd705d5 | ||
| 
						 | 
					9b1170a978 | ||
| 
						 | 
					2a5872002f | ||
| 
						 | 
					1b7670f8c5 | ||
| 768a5a6d7a | |||
| 
						 | 
					2eefd813df | ||
| 
						 | 
					197dba15f1 | ||
| 
						 | 
					8dd9771033 | ||
| 
						 | 
					a4a75ab016 | ||
| 
						 | 
					2cbe907db4 | ||
| 
						 | 
					af3dee00a2 | ||
| 
						 | 
					c9b1e470cb | ||
| 
						 | 
					458edffa85 | ||
| 
						 | 
					930e42835b | ||
| 
						 | 
					d3020ded2c | ||
| 
						 | 
					97f55e6122 | ||
| 
						 | 
					9f9722ce9c | ||
| 
						 | 
					6ce4b352b4 | ||
| 
						 | 
					b3d39a6e58 | ||
| 
						 | 
					3780befa7a | ||
| 
						 | 
					c68f35c2e3 | ||
| 
						 | 
					830e5426d6 | ||
| 
						 | 
					bbf9919ad3 | ||
| 
						 | 
					ab2e990ffb | ||
| 
						 | 
					df99f04e6e | ||
| 
						 | 
					91ff06ea79 | ||
| 
						 | 
					0c3db5e445 | ||
| 
						 | 
					9ffde3bd2c | ||
| 
						 | 
					3326b134a8 | ||
| 
						 | 
					f8b4df8f4f | ||
| 
						 | 
					5bf618a9d2 | ||
| 
						 | 
					9a85c9c20d | ||
| 
						 | 
					86b679ba97 | ||
| 
						 | 
					a4865cae47 | ||
| 
						 | 
					b6a179a0ea | ||
| 
						 | 
					4666020263 | ||
| 
						 | 
					576569ea2d | ||
| 
						 | 
					ae4e1b9990 | ||
| 
						 | 
					c07f757c4a | ||
| 
						 | 
					6faccfe564 | ||
| 
						 | 
					9505316291 | ||
| 
						 | 
					c76fd125ec | ||
| 
						 | 
					3b28a20b33 | ||
| 
						 | 
					8002d2a1d3 | ||
| 
						 | 
					6b475415cc | ||
| 
						 | 
					40074a3db6 | ||
| 234607cb8d | |||
| 
						 | 
					9ad11bff63 | ||
| 
						 | 
					0849705c62 | ||
| 
						 | 
					6490c2f1be | ||
| 
						 | 
					d863cbeff0 | ||
| 
						 | 
					d04ea31ef0 | ||
| 
						 | 
					33fddad023 | ||
| 
						 | 
					b620f87eb1 | ||
| 
						 | 
					97b4147072 | ||
| 
						 | 
					bd3d354786 | ||
| 
						 | 
					b230baa776 | ||
| 
						 | 
					4e6ca5f8ed | ||
| 
						 | 
					d6e6847955 | ||
| 
						 | 
					c551f4855f | ||
| 
						 | 
					15c791e1bf | ||
| 
						 | 
					af2f803be5 | ||
| 
						 | 
					91fd570896 | ||
| 
						 | 
					0e876c319c | ||
| 
						 | 
					122983580f | ||
| 
						 | 
					948f68515c | ||
| 
						 | 
					528e8d5a08 | ||
| 
						 | 
					b7adf6af6d | ||
| 
						 | 
					a8646efe0d | ||
| 
						 | 
					480946f9be | ||
| 
						 | 
					c3620aa017 | ||
| 
						 | 
					43bf81053b | ||
| 
						 | 
					b4f5cef061 | ||
| 
						 | 
					58333bef34 | ||
| 
						 | 
					0beab4ec1d | ||
| 
						 | 
					4860b7e0ee | ||
| 
						 | 
					bf6734f44b | ||
| 
						 | 
					a1fad78c3b | ||
| 
						 | 
					bfbf2cced4 | ||
| 
						 | 
					78e9906e6b | ||
| 
						 | 
					8d03f20b57 | ||
| 
						 | 
					83b9a4347c | ||
| 
						 | 
					b197fbd082 | ||
| 
						 | 
					29869e9b08 | ||
| 
						 | 
					d61e06e0e9 | ||
| 
						 | 
					6b87b19f0d | ||
| c87d8e9302 | |||
| 8afc912ed5 | |||
| b06c9acda3 | |||
| 
						 | 
					a56dfe6a2d | ||
| 
						 | 
					17b4182abe | ||
| 
						 | 
					9f19ed8817 | ||
| 
						 | 
					cea5741fb8 | ||
| 
						 | 
					5661ef3e59 | ||
| 
						 | 
					40c7318992 | ||
| 
						 | 
					9bdeb2ac19 | ||
| 
						 | 
					e64f8fd0a4 | ||
| 
						 | 
					a193c6f814 | ||
| 
						 | 
					d1b04b6a74 | ||
| 
						 | 
					7113e9974e | ||
| 
						 | 
					7c074adbb9 | ||
| 
						 | 
					462311836f | ||
| 
						 | 
					c553b8ef8f | ||
| 
						 | 
					1d75b5cc77 | ||
| 
						 | 
					f2c840bedc | ||
| 
						 | 
					b6c5f42acc | ||
| 
						 | 
					65cbeba975 | ||
| 1498f73b10 | |||
| 8ae1510a71 | |||
| b211fe2b56 | |||
| 85c7b3fa0a | |||
| 65df7eb47b | |||
| 13e7e24911 | |||
| b61458a45e | |||
| 673445e339 | |||
| 157e9fc58c | |||
| f3f2688292 | |||
| 5d245d5a3d | |||
| ddbe145179 | |||
| bd06f26248 | |||
| 8e470ccbb6 | |||
| 7c01c1c790 | |||
| 7b30b50cf1 | |||
| 32eec48ce6 | |||
| 5545ac1370 | |||
| 
						 | 
					d186f3e6c8 | ||
| eec264b014 | |||
| ef1aabfcb0 | |||
| 
						 | 
					c3882d4af3 | ||
| 
						 | 
					43b4c15a9d | ||
| 
						 | 
					908fe4fc24 | ||
| 
						 | 
					b423fc73fc | ||
| 
						 | 
					9abd0a9173 | ||
| 2af38efe42 | |||
| 8ddb1a8233 | |||
| 23be875b9f | |||
| 5294e3fea5 | |||
| 
						 | 
					12c4a0d5ba | ||
| 
						 | 
					a856bb574a | ||
| 
						 | 
					4e52ea8215 | ||
| 
						 | 
					70c54892d8 | ||
| b49d7f643b | |||
| 
						 | 
					cf93bbdba6 | ||
| 
						 | 
					9d3ddb088b | ||
| 
						 | 
					48e526a627 | ||
| 
						 | 
					113dec6551 | ||
| 
						 | 
					71ef5799c2 | ||
| 
						 | 
					49ef217d12 | ||
| 
						 | 
					65f031e1c2 | ||
| 
						 | 
					10718f1355 | ||
| 
						 | 
					b0638c525e | ||
| 
						 | 
					0adf1d8a3b | ||
| 
						 | 
					a0d8125d32 | ||
| 
						 | 
					b6866dd44a | ||
| 
						 | 
					6f0aee2a69 | ||
| 
						 | 
					acb482e37f | ||
| 
						 | 
					0ec53ea1b3 | ||
| 
						 | 
					08bb518e9a | ||
| 
						 | 
					33eb0ed012 | ||
| 
						 | 
					70af6fd6a3 | ||
| 
						 | 
					44a251f7f7 | ||
| 0aa3e543a8 | |||
| 
						 | 
					97b8a6edab | ||
| a7d374596d | |||
| 
						 | 
					cf0772f6ae | ||
| 
						 | 
					fe23d695e4 | ||
| 
						 | 
					9a6241b608 | ||
| 
						 | 
					065eebb858 | ||
| 1f3465a12d | |||
| 
						 | 
					e3674c401d | ||
| 
						 | 
					1dde30c52c | ||
| 5fb14e80a8 | |||
| 
						 | 
					c9f212a641 | ||
| 
						 | 
					9e20c40b37 | ||
| 
						 | 
					e9d37309b4 | ||
| 
						 | 
					613e14b4f9 | ||
| 
						 | 
					6e5f2d98b3 | ||
| 
						 | 
					249f996db7 | 
@@ -1,8 +1,8 @@
 | 
				
			|||||||
###############################################################################
 | 
					###############################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Developed with Kate
 | 
					# Developed with VSCodium and richterger perl plugin.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  (c) 2017-2021 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
 | 
					#  (c) 2017-2022 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
 | 
				
			||||||
#  All rights reserved
 | 
					#  All rights reserved
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#   Special thanks goes to comitters:
 | 
					#   Special thanks goes to comitters:
 | 
				
			||||||
@@ -57,7 +57,6 @@
 | 
				
			|||||||
package FHEM::GardenaSmartBridge;
 | 
					package FHEM::GardenaSmartBridge;
 | 
				
			||||||
use GPUtils qw(GP_Import GP_Export);
 | 
					use GPUtils qw(GP_Import GP_Export);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
use strict;
 | 
					use strict;
 | 
				
			||||||
use warnings;
 | 
					use warnings;
 | 
				
			||||||
use POSIX;
 | 
					use POSIX;
 | 
				
			||||||
@@ -66,11 +65,12 @@ use FHEM::Meta;
 | 
				
			|||||||
use HttpUtils;
 | 
					use HttpUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
my $missingModul = '';
 | 
					my $missingModul = '';
 | 
				
			||||||
eval "use Encode qw(encode encode_utf8 decode_utf8);1"
 | 
					eval { use Encode qw /encode_utf8 decode_utf8/; 1 }
 | 
				
			||||||
  or $missingModul .= "Encode ";
 | 
					  or $missingModul .= "Encode ";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# eval "use JSON;1" || $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
 | 
				
			||||||
#   for chance of better performance + open code
 | 
					#   for chance of better performance + open code
 | 
				
			||||||
@@ -78,15 +78,11 @@ eval {
 | 
				
			|||||||
    require JSON::MaybeXS;
 | 
					    require JSON::MaybeXS;
 | 
				
			||||||
    import JSON::MaybeXS qw( decode_json encode_json );
 | 
					    import JSON::MaybeXS qw( decode_json encode_json );
 | 
				
			||||||
    1;
 | 
					    1;
 | 
				
			||||||
};
 | 
					} or do {
 | 
				
			||||||
 | 
					 | 
				
			||||||
if ($@) {
 | 
					 | 
				
			||||||
    $@ = undef;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # try to use JSON wrapper
 | 
					    # try to use JSON wrapper
 | 
				
			||||||
    #   for chance of better performance
 | 
					    #   for chance of better performance
 | 
				
			||||||
    eval {
 | 
					    eval {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        # JSON preference order
 | 
					        # JSON preference order
 | 
				
			||||||
        local $ENV{PERL_JSON_BACKEND} =
 | 
					        local $ENV{PERL_JSON_BACKEND} =
 | 
				
			||||||
          'Cpanel::JSON::XS,JSON::XS,JSON::PP,JSON::backportPP'
 | 
					          'Cpanel::JSON::XS,JSON::XS,JSON::PP,JSON::backportPP'
 | 
				
			||||||
@@ -95,10 +91,7 @@ if ($@) {
 | 
				
			|||||||
        require JSON;
 | 
					        require JSON;
 | 
				
			||||||
        import JSON qw( decode_json encode_json );
 | 
					        import JSON qw( decode_json encode_json );
 | 
				
			||||||
        1;
 | 
					        1;
 | 
				
			||||||
    };
 | 
					    } or do {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ($@) {
 | 
					 | 
				
			||||||
        $@ = undef;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # In rare cases, Cpanel::JSON::XS may
 | 
					        # In rare cases, Cpanel::JSON::XS may
 | 
				
			||||||
        #   be installed but JSON|JSON::MaybeXS not ...
 | 
					        #   be installed but JSON|JSON::MaybeXS not ...
 | 
				
			||||||
@@ -106,10 +99,7 @@ if ($@) {
 | 
				
			|||||||
            require Cpanel::JSON::XS;
 | 
					            require Cpanel::JSON::XS;
 | 
				
			||||||
            import Cpanel::JSON::XS qw(decode_json encode_json);
 | 
					            import Cpanel::JSON::XS qw(decode_json encode_json);
 | 
				
			||||||
            1;
 | 
					            1;
 | 
				
			||||||
        };
 | 
					        } or do {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ($@) {
 | 
					 | 
				
			||||||
            $@ = undef;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # In rare cases, JSON::XS may
 | 
					            # In rare cases, JSON::XS may
 | 
				
			||||||
            #   be installed but JSON not ...
 | 
					            #   be installed but JSON not ...
 | 
				
			||||||
@@ -117,10 +107,7 @@ if ($@) {
 | 
				
			|||||||
                require JSON::XS;
 | 
					                require JSON::XS;
 | 
				
			||||||
                import JSON::XS qw(decode_json encode_json);
 | 
					                import JSON::XS qw(decode_json encode_json);
 | 
				
			||||||
                1;
 | 
					                1;
 | 
				
			||||||
            };
 | 
					            } or do {
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if ($@) {
 | 
					 | 
				
			||||||
                $@ = undef;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # Fallback to built-in JSON which SHOULD
 | 
					                # Fallback to built-in JSON which SHOULD
 | 
				
			||||||
                #   be available since 5.014 ...
 | 
					                #   be available since 5.014 ...
 | 
				
			||||||
@@ -128,20 +115,17 @@ if ($@) {
 | 
				
			|||||||
                    require JSON::PP;
 | 
					                    require JSON::PP;
 | 
				
			||||||
                    import JSON::PP qw(decode_json encode_json);
 | 
					                    import JSON::PP qw(decode_json encode_json);
 | 
				
			||||||
                    1;
 | 
					                    1;
 | 
				
			||||||
                };
 | 
					                } or do {
 | 
				
			||||||
 | 
					 | 
				
			||||||
                if ($@) {
 | 
					 | 
				
			||||||
                    $@ = undef;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    # Fallback to JSON::backportPP in really rare cases
 | 
					                    # Fallback to JSON::backportPP in really rare cases
 | 
				
			||||||
                    require JSON::backportPP;
 | 
					                    require JSON::backportPP;
 | 
				
			||||||
                    import JSON::backportPP qw(decode_json encode_json);
 | 
					                    import JSON::backportPP qw(decode_json encode_json);
 | 
				
			||||||
                    1;
 | 
					                    1;
 | 
				
			||||||
                }
 | 
					                };
 | 
				
			||||||
            }
 | 
					            };
 | 
				
			||||||
        }
 | 
					        };
 | 
				
			||||||
    }
 | 
					    };
 | 
				
			||||||
}
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Import der FHEM Funktionen
 | 
					## Import der FHEM Funktionen
 | 
				
			||||||
#-- Run before package compilation
 | 
					#-- Run before package compilation
 | 
				
			||||||
@@ -205,6 +189,7 @@ sub Initialize {
 | 
				
			|||||||
    $hash->{AttrFn} = \&Attr;
 | 
					    $hash->{AttrFn} = \&Attr;
 | 
				
			||||||
    $hash->{AttrList} =
 | 
					    $hash->{AttrList} =
 | 
				
			||||||
        'debugJSON:0,1 '
 | 
					        'debugJSON:0,1 '
 | 
				
			||||||
 | 
					      . 'debugDEVICE:0,1 '
 | 
				
			||||||
      . 'disable:1 '
 | 
					      . 'disable:1 '
 | 
				
			||||||
      . 'interval '
 | 
					      . 'interval '
 | 
				
			||||||
      . 'disabledForIntervals '
 | 
					      . 'disabledForIntervals '
 | 
				
			||||||
@@ -234,9 +219,7 @@ sub Define {
 | 
				
			|||||||
    my $name = shift @$aArg;
 | 
					    my $name = shift @$aArg;
 | 
				
			||||||
    $hash->{BRIDGE} = 1;
 | 
					    $hash->{BRIDGE} = 1;
 | 
				
			||||||
    $hash->{URL} =
 | 
					    $hash->{URL} =
 | 
				
			||||||
      AttrVal( $name, 'gardenaBaseURL',
 | 
					      AttrVal( $name, 'gardenaBaseURL', 'https://smart.gardena.com' ) . '/v1';
 | 
				
			||||||
        'https://smart.gardena.com' )
 | 
					 | 
				
			||||||
      . '/v1';
 | 
					 | 
				
			||||||
    $hash->{VERSION}   = version->parse($VERSION)->normal;
 | 
					    $hash->{VERSION}   = version->parse($VERSION)->normal;
 | 
				
			||||||
    $hash->{INTERVAL}  = 60;
 | 
					    $hash->{INTERVAL}  = 60;
 | 
				
			||||||
    $hash->{NOTIFYDEV} = "global,$name";
 | 
					    $hash->{NOTIFYDEV} = "global,$name";
 | 
				
			||||||
@@ -258,7 +241,7 @@ sub Undef {
 | 
				
			|||||||
    my $hash = shift;
 | 
					    my $hash = shift;
 | 
				
			||||||
    my $name = shift;
 | 
					    my $name = shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RemoveInternalTimer($hash);
 | 
					    RemoveInternalTimer( $hash, "FHEM::GardenaSmartBridge::getDevices" );
 | 
				
			||||||
    delete $modules{GardenaSmartBridge}{defptr}{BRIDGE}
 | 
					    delete $modules{GardenaSmartBridge}{defptr}{BRIDGE}
 | 
				
			||||||
      if ( defined( $modules{GardenaSmartBridge}{defptr}{BRIDGE} ) );
 | 
					      if ( defined( $modules{GardenaSmartBridge}{defptr}{BRIDGE} ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -279,7 +262,8 @@ sub Attr {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if ( $attrName eq 'disable' ) {
 | 
					    if ( $attrName eq 'disable' ) {
 | 
				
			||||||
        if ( $cmd eq 'set' && $attrVal eq '1' ) {
 | 
					        if ( $cmd eq 'set' && $attrVal eq '1' ) {
 | 
				
			||||||
            RemoveInternalTimer($hash);
 | 
					            RemoveInternalTimer( $hash,
 | 
				
			||||||
 | 
					                "FHEM::GardenaSmartBridge::getDevices" );
 | 
				
			||||||
            readingsSingleUpdate( $hash, 'state', 'inactive', 1 );
 | 
					            readingsSingleUpdate( $hash, 'state', 'inactive', 1 );
 | 
				
			||||||
            Log3 $name, 3, "GardenaSmartBridge ($name) - disabled";
 | 
					            Log3 $name, 3, "GardenaSmartBridge ($name) - disabled";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -304,13 +288,15 @@ sub Attr {
 | 
				
			|||||||
        if ( $cmd eq 'set' ) {
 | 
					        if ( $cmd eq 'set' ) {
 | 
				
			||||||
            return 'Interval must be greater than 0'
 | 
					            return 'Interval must be greater than 0'
 | 
				
			||||||
              if ( $attrVal == 0 );
 | 
					              if ( $attrVal == 0 );
 | 
				
			||||||
            RemoveInternalTimer($hash);
 | 
					            RemoveInternalTimer( $hash,
 | 
				
			||||||
 | 
					                "FHEM::GardenaSmartBridge::getDevices" );
 | 
				
			||||||
            $hash->{INTERVAL} = $attrVal;
 | 
					            $hash->{INTERVAL} = $attrVal;
 | 
				
			||||||
            Log3 $name, 3,
 | 
					            Log3 $name, 3,
 | 
				
			||||||
              "GardenaSmartBridge ($name) - set interval: $attrVal";
 | 
					              "GardenaSmartBridge ($name) - set interval: $attrVal";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        elsif ( $cmd eq 'del' ) {
 | 
					        elsif ( $cmd eq 'del' ) {
 | 
				
			||||||
            RemoveInternalTimer($hash);
 | 
					            RemoveInternalTimer( $hash,
 | 
				
			||||||
 | 
					                "FHEM::GardenaSmartBridge::getDevices" );
 | 
				
			||||||
            $hash->{INTERVAL} = 60;
 | 
					            $hash->{INTERVAL} = 60;
 | 
				
			||||||
            Log3 $name, 3,
 | 
					            Log3 $name, 3,
 | 
				
			||||||
"GardenaSmartBridge ($name) - delete User interval and set default: 60";
 | 
					"GardenaSmartBridge ($name) - delete User interval and set default: 60";
 | 
				
			||||||
@@ -352,25 +338,21 @@ sub Notify {
 | 
				
			|||||||
                @{$events} or grep /^DEFINED.$name$/,
 | 
					                @{$events} or grep /^DEFINED.$name$/,
 | 
				
			||||||
                @{$events} or grep /^MODIFIED.$name$/,
 | 
					                @{$events} or grep /^MODIFIED.$name$/,
 | 
				
			||||||
                @{$events} or grep /^ATTR.$name.gardenaAccountEmail.+/,
 | 
					                @{$events} or grep /^ATTR.$name.gardenaAccountEmail.+/,
 | 
				
			||||||
 | 
					                @{$events} or grep /^DELETEATTR.$name.disable$/,
 | 
				
			||||||
                @{$events}
 | 
					                @{$events}
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        || (
 | 
					        || ( $devtype eq 'GardenaSmartBridge'
 | 
				
			||||||
            $devtype eq 'GardenaSmartBridge'
 | 
					            && ( grep /^gardenaAccountPassword.+/, @{$events} ) )
 | 
				
			||||||
            && (
 | 
					        && $init_done
 | 
				
			||||||
                grep /^gardenaAccountPassword.+/,
 | 
					 | 
				
			||||||
                @{$events}
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getDevices($hash)
 | 
					    getDevices($hash)
 | 
				
			||||||
      if (
 | 
					      if (
 | 
				
			||||||
        $devtype eq 'Global'
 | 
					        $devtype eq 'Global'
 | 
				
			||||||
        && (
 | 
					        && (
 | 
				
			||||||
            grep /^DELETEATTR.$name.disable$/,
 | 
					            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}
 | 
				
			||||||
@@ -387,7 +369,6 @@ sub Notify {
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        InternalTimer( gettimeofday() + $hash->{INTERVAL},
 | 
					        InternalTimer( gettimeofday() + $hash->{INTERVAL},
 | 
				
			||||||
            "FHEM::GardenaSmartBridge::getDevices", $hash );
 | 
					            "FHEM::GardenaSmartBridge::getDevices", $hash );
 | 
				
			||||||
        Log3 $name, 4,
 | 
					        Log3 $name, 4,
 | 
				
			||||||
@@ -396,6 +377,7 @@ sub Notify {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sub Get {
 | 
					sub Get {
 | 
				
			||||||
    my $hash = shift // return;
 | 
					    my $hash = shift // return;
 | 
				
			||||||
    my $aArg = shift // return;
 | 
					    my $aArg = shift // return;
 | 
				
			||||||
@@ -407,14 +389,15 @@ sub Get {
 | 
				
			|||||||
    if ( lc $cmd eq 'debug_devices_list' ) {
 | 
					    if ( lc $cmd eq 'debug_devices_list' ) {
 | 
				
			||||||
        my $device = shift @$aArg;
 | 
					        my $device = shift @$aArg;
 | 
				
			||||||
        $hash->{helper}{debug_device} = $device;
 | 
					        $hash->{helper}{debug_device} = $device;
 | 
				
			||||||
        Write($hash, undef, undef, undef, undef); 
 | 
					        Write( $hash, undef, undef, undef, undef );
 | 
				
			||||||
        return undef;
 | 
					        return;
 | 
				
			||||||
    } else {
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
        my $list = "";
 | 
					        my $list = "";
 | 
				
			||||||
        $list .= " debug_devices_list:"
 | 
					        $list .=
 | 
				
			||||||
          .join( ',', @{ $hash->{helper}{deviceList} }) 
 | 
					          " debug_devices_list:" . join( ',', @{ $hash->{helper}{deviceList} } )
 | 
				
			||||||
          if ( AttrVal( $name, "debugJSON", "none") ne "none" 
 | 
					          if ( AttrVal( $name, "debugDEVICE", "none" ) ne "none"
 | 
				
			||||||
           && exists($hash->{helper}{deviceList}) );
 | 
					            && exists( $hash->{helper}{deviceList} ) );
 | 
				
			||||||
        return "Unknown argument $cmd,choose one of $list";
 | 
					        return "Unknown argument $cmd,choose one of $list";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -424,13 +407,13 @@ sub Set {
 | 
				
			|||||||
    my $aArg = shift // return;
 | 
					    my $aArg = shift // return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    my $name = shift @$aArg // return;
 | 
					    my $name = shift @$aArg // return;
 | 
				
			||||||
    my $cmd  = shift @$aArg // return qq{"set $name" needs at least one argument};
 | 
					    my $cmd  = shift @$aArg
 | 
				
			||||||
 | 
					      // return qq{"set $name" needs at least one argument};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#     Das Argument für das Passwort, also das Passwort an sich darf keine = enthalten!!!
 | 
					#     Das Argument für das Passwort, also das Passwort an sich darf keine = enthalten!!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( lc $cmd eq 'getdevicesstate' ) {
 | 
					    if ( lc $cmd eq 'getdevicesstate' ) {
 | 
				
			||||||
        getDevices($hash);
 | 
					        getDevices($hash);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    elsif ( lc $cmd eq 'gettoken' ) {
 | 
					    elsif ( lc $cmd eq 'gettoken' ) {
 | 
				
			||||||
        return "please set Attribut gardenaAccountEmail first"
 | 
					        return "please set Attribut gardenaAccountEmail first"
 | 
				
			||||||
@@ -454,6 +437,13 @@ sub Set {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        DeletePassword($hash);
 | 
					        DeletePassword($hash);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    elsif ( lc $cmd eq 'debughelper') {
 | 
				
			||||||
 | 
					      return "usage: $cmd" if ( scalar( @{$aArg} ) != 2 );
 | 
				
			||||||
 | 
					      my $new_helper = $aArg->[0];
 | 
				
			||||||
 | 
					      my $new_helper_value = $aArg->[1];
 | 
				
			||||||
 | 
					      Log3( $name, 5, "[DEBUG] - GardenaSmartBridge ($name) - override helper $new_helper with $new_helper_value");
 | 
				
			||||||
 | 
					      $hash->{helper}{$new_helper} = $new_helper_value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        my $list = "getDevicesState:noArg getToken:noArg"
 | 
					        my $list = "getDevicesState:noArg getToken:noArg"
 | 
				
			||||||
@@ -475,12 +465,14 @@ sub Write {
 | 
				
			|||||||
    my ( $session_id, $header, $uri, $method );
 | 
					    my ( $session_id, $header, $uri, $method );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ( $payload, $session_id, $header, $uri, $method, $deviceId, $service_id ) =
 | 
					    ( $payload, $session_id, $header, $uri, $method, $deviceId, $service_id ) =
 | 
				
			||||||
      createHttpValueStrings( $hash, $payload, $deviceId, $abilities, $service_id );
 | 
					      createHttpValueStrings( $hash, $payload, $deviceId, $abilities,
 | 
				
			||||||
 | 
					        $service_id );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HttpUtils_NonblockingGet(
 | 
					    HttpUtils_NonblockingGet(
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            url                => $hash->{URL} . $uri,
 | 
					            url                => $hash->{URL} . $uri,
 | 
				
			||||||
            timeout            => 15,
 | 
					            timeout            => 15,
 | 
				
			||||||
 | 
					            incrementalTimeout => 1,
 | 
				
			||||||
            hash               => $hash,
 | 
					            hash               => $hash,
 | 
				
			||||||
            device_id          => $deviceId,
 | 
					            device_id          => $deviceId,
 | 
				
			||||||
            data               => $payload,
 | 
					            data               => $payload,
 | 
				
			||||||
@@ -518,7 +510,7 @@ sub ErrorHandling {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Log3 $name, 4, "GardenaSmartBridge ($name) - Request: $data";
 | 
					    Log3 $name, 4, "GardenaSmartBridge ($name) - Request: $data";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    my $decode_json = eval { decode_json($data) };
 | 
					    my $decode_json = eval { decode_json($data) } if ( length($data) > 0 );
 | 
				
			||||||
    if ($@) {
 | 
					    if ($@) {
 | 
				
			||||||
        Log3 $name, 3, "GardenaSmartBridge ($name) - JSON error while request";
 | 
					        Log3 $name, 3, "GardenaSmartBridge ($name) - JSON error while request";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -534,7 +526,6 @@ sub ErrorHandling {
 | 
				
			|||||||
                1 );
 | 
					                1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ( $err =~ /timed out/ ) {
 | 
					            if ( $err =~ /timed out/ ) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
                Log3 $dname, 5,
 | 
					                Log3 $dname, 5,
 | 
				
			||||||
"GardenaSmartBridge ($dname) - RequestERROR: connect to gardena cloud is timed out. check network";
 | 
					"GardenaSmartBridge ($dname) - RequestERROR: connect to gardena cloud is timed out. check network";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -621,6 +612,7 @@ sub ErrorHandling {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (
 | 
					    if (
 | 
				
			||||||
        $data =~ /Error/
 | 
					        $data =~ /Error/
 | 
				
			||||||
 | 
					        && $data !~ /lastLonaErrorCode/
 | 
				
			||||||
        || (   defined($decode_json)
 | 
					        || (   defined($decode_json)
 | 
				
			||||||
            && ref($decode_json) eq 'HASH'
 | 
					            && ref($decode_json) eq 'HASH'
 | 
				
			||||||
            && defined( $decode_json->{errors} ) )
 | 
					            && defined( $decode_json->{errors} ) )
 | 
				
			||||||
@@ -698,6 +690,11 @@ sub ErrorHandling {
 | 
				
			|||||||
              . $param->{code};
 | 
					              . $param->{code};
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ( !defined( $hash->{helper}{session_id} ) ) {
 | 
				
			||||||
 | 
					            readingsSingleUpdate( $hash, 'token', 'none', 1 );
 | 
				
			||||||
 | 
					            InternalTimer( gettimeofday() + 5,
 | 
				
			||||||
 | 
					                "FHEM::GardenaSmartBridge::getToken", $hash );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        readingsEndUpdate( $dhash, 1 );
 | 
					        readingsEndUpdate( $dhash, 1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Log3 $dname, 5,
 | 
					        Log3 $dname, 5,
 | 
				
			||||||
@@ -710,29 +707,58 @@ sub ErrorHandling {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 if (defined($hash->{helper}{debug_device})){
 | 
					    elsif ( defined( $decode_json->{message} )
 | 
				
			||||||
      Log3 $name, 5, "GardenaSmartBridge DEBUG Device";
 | 
					        && $decode_json->{message} eq 'Unauthorized' )
 | 
				
			||||||
      my @device_spec = ("name", "id", "category");
 | 
					    {
 | 
				
			||||||
      my $devJson=$decode_json->{devices};
 | 
					        Log3 $name, 3,
 | 
				
			||||||
      my $output = '.:{ DEBUG OUTPUT for '.$devJson->{name}.' }:. \n';
 | 
					          "GardenaSmartBridge ($name) - Unauthorized -> fetch new token ";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        getToken($hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( defined( $hash->{helper}{debug_device} )
 | 
				
			||||||
 | 
					        && $hash->{helper}{debug_device} ne 'none' )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Log3 $name, 4, "GardenaSmartBridge DEBUG Device";
 | 
				
			||||||
 | 
					        delete $hash->{helper}{debug_device};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        my @device_spec = ( "name", "id", "category" );
 | 
				
			||||||
 | 
					        my $devJson     = $decode_json->{devices};
 | 
				
			||||||
 | 
					        my $output = '.:{ DEBUG OUTPUT for ' . $devJson->{name} . ' }:. \n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for my $spec (@device_spec) {
 | 
					        for my $spec (@device_spec) {
 | 
				
			||||||
            $output .= "$spec : $devJson->{$spec} \n";
 | 
					            $output .= "$spec : $devJson->{$spec} \n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #settings
 | 
					        #settings
 | 
				
			||||||
        $output .= '\n=== Settings \n';
 | 
					        $output .= '\n=== Settings \n';
 | 
				
			||||||
        my $i = 0;
 | 
					        my $i = 0;
 | 
				
			||||||
      for my $dev_settings ( @ { $devJson->{settings} } ) {
 | 
					        for my $dev_settings ( @{ $devJson->{settings} } ) {
 | 
				
			||||||
        $output .= "[".$i++."]id: $dev_settings->{id} \n";
 | 
					            $output .= "[" . $i++ . "]id: $dev_settings->{id} \n";
 | 
				
			||||||
        $output .= "name: $dev_settings->{name} ";
 | 
					            $output .= "name: $dev_settings->{name} \n";
 | 
				
			||||||
        if (ref ($dev_settings->{value}) eq 'ARRAY' 
 | 
					            if (   ref( $dev_settings->{value} ) eq 'ARRAY'
 | 
				
			||||||
          || ref ($dev_settings->{value}) eq 'HASH'){
 | 
					                || ref( $dev_settings->{value} ) eq 'HASH' )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                $output .= 'N/A \n';
 | 
					                $output .= 'N/A \n';
 | 
				
			||||||
        } else {
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
                $output .= "value: $dev_settings->{value} \n";
 | 
					                $output .= "value: $dev_settings->{value} \n";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $output .= '\n=== Abilities \n';
 | 
				
			||||||
 | 
					        $i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for my $dev_settings ( @{ $devJson->{abilities} } ) {
 | 
				
			||||||
 | 
					            $output .= "[" . $i++ . "]id: $dev_settings->{id} \n";
 | 
				
			||||||
 | 
					            $output .= "name: $dev_settings->{name} \n";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $hash->{helper}{debug_device_output} = $output;
 | 
					        $hash->{helper}{debug_device_output} = $output;
 | 
				
			||||||
      asyncOutput($param->{cl},  $hash->{helper}{debug_device_output});
 | 
					        asyncOutput( $param->{cl}, $hash->{helper}{debug_device_output} );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    readingsSingleUpdate( $hash, 'state', 'Connected', 1 )
 | 
					    readingsSingleUpdate( $hash, 'state', 'Connected', 1 )
 | 
				
			||||||
@@ -762,15 +788,21 @@ sub ResponseProcessing {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # print Dumper $decode_json;
 | 
					    if (   defined( $decode_json->{data} )
 | 
				
			||||||
 | 
					        && $decode_json->{data}
 | 
				
			||||||
    if ( defined( $decode_json->{data} ) && $decode_json->{data} 
 | 
					        && ref( $decode_json->{data} ) eq 'HASH'
 | 
				
			||||||
        && ref($decode_json->{data}) eq 'HASH'
 | 
					        && !defined( $hash->{helper}->{user_id} ) )
 | 
				
			||||||
        && !defined( $hash->{helper}->{user_id})) {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $hash->{helper}{session_id} = $decode_json->{data}{id};
 | 
					        $hash->{helper}{session_id} = $decode_json->{data}{id};
 | 
				
			||||||
        $hash->{helper}{user_id} = $decode_json->{data}{attributes}->{user_id};
 | 
					        $hash->{helper}{user_id} = $decode_json->{data}{attributes}->{user_id};
 | 
				
			||||||
        $hash->{helper}{refresh_token}  = $decode_json->{data}{attributes}->{refresh_token};
 | 
					        $hash->{helper}{refresh_token} =
 | 
				
			||||||
 | 
					          $decode_json->{data}{attributes}->{refresh_token};
 | 
				
			||||||
 | 
					        $hash->{helper}{token_expired} =
 | 
				
			||||||
 | 
					          gettimeofday() + $decode_json->{data}{attributes}->{expires_in};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        InternalTimer( $hash->{helper}{token_expired},
 | 
				
			||||||
 | 
					            "FHEM::GardenaSmartBridge::getToken", $hash );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Write( $hash, undef, undef, undef );
 | 
					        Write( $hash, undef, undef, undef );
 | 
				
			||||||
        Log3 $name, 3, "GardenaSmartBridge ($name) - fetch locations id";
 | 
					        Log3 $name, 3, "GardenaSmartBridge ($name) - fetch locations id";
 | 
				
			||||||
@@ -802,50 +834,35 @@ sub ResponseProcessing {
 | 
				
			|||||||
        && ref( $decode_json->{devices} ) eq 'ARRAY'
 | 
					        && ref( $decode_json->{devices} ) eq 'ARRAY'
 | 
				
			||||||
        && scalar( @{ $decode_json->{devices} } ) > 0 )
 | 
					        && scalar( @{ $decode_json->{devices} } ) > 0 )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        my @buffer = split( '"devices":\[', $json );
 | 
					        my @buffer = split( '"devices":\[', $json );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        my ( $json, $tail ) = ParseJSON( $hash, $buffer[1] );
 | 
					        require SubProcess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while ($json) {
 | 
					        my $subprocess =
 | 
				
			||||||
 | 
					          SubProcess->new( { onRun => \&ResponseSubprocessing } );
 | 
				
			||||||
 | 
					        $subprocess->{buffer} = $buffer[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Log3 $name, 5,
 | 
					        my $pid = $subprocess->run();
 | 
				
			||||||
                "GardenaSmartBridge ($name) - Decoding JSON message. Length: "
 | 
					 | 
				
			||||||
              . length($json)
 | 
					 | 
				
			||||||
              . " Content: "
 | 
					 | 
				
			||||||
              . $json;
 | 
					 | 
				
			||||||
            Log3 $name, 5,
 | 
					 | 
				
			||||||
                "GardenaSmartBridge ($name) - Vor Sub: Laenge JSON: "
 | 
					 | 
				
			||||||
              . length($json)
 | 
					 | 
				
			||||||
              . " Content: "
 | 
					 | 
				
			||||||
              . $json
 | 
					 | 
				
			||||||
              . " Tail: "
 | 
					 | 
				
			||||||
              . $tail;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ( defined($tail) and $tail ) {
 | 
					        if ( !defined($pid) ) {
 | 
				
			||||||
                $decode_json = eval { decode_json($json) };
 | 
					            Log3( $name, 1,
 | 
				
			||||||
                if ($@) {
 | 
					qq{GardenaSmartBridge ($name) - Cannot execute parse json asynchronously}
 | 
				
			||||||
                    Log3 $name, 5,
 | 
					            );
 | 
				
			||||||
"GardenaSmartBridge ($name) - JSON error while request: $@";
 | 
					
 | 
				
			||||||
 | 
					            CleanSubprocess($hash);
 | 
				
			||||||
 | 
					            readingsSingleUpdate( $hash, 'state',
 | 
				
			||||||
 | 
					                'Cannot execute parse json asynchronously', 1 );
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Dispatch( $hash, $json, undef )
 | 
					        Log3( $name, 4,
 | 
				
			||||||
                  if ( $decode_json->{category} ne 'gateway' );
 | 
					qq{GardenaSmartBridge ($name) - execute parse json asynchronously (PID="$pid")}
 | 
				
			||||||
                WriteReadings( $hash, $decode_json )
 | 
					        );
 | 
				
			||||||
                  if ( defined( $decode_json->{category} )
 | 
					 | 
				
			||||||
                    && $decode_json->{category} eq 'gateway' );
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ( $json, $tail ) = ParseJSON( $hash, $tail );
 | 
					        $hash->{".fhem"}{subprocess} = $subprocess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Log3 $name, 5,
 | 
					        InternalTimer( gettimeofday() + 1,
 | 
				
			||||||
                "GardenaSmartBridge ($name) - Nach Sub: Laenge JSON: "
 | 
					            "FHEM::GardenaSmartBridge::PollChild", $hash );
 | 
				
			||||||
              . length($json)
 | 
					 | 
				
			||||||
              . " Content: "
 | 
					 | 
				
			||||||
              . $json
 | 
					 | 
				
			||||||
              . " Tail: "
 | 
					 | 
				
			||||||
              . $tail;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -855,12 +872,148 @@ sub ResponseProcessing {
 | 
				
			|||||||
    return;
 | 
					    return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sub ResponseProcessingFinalFromSubProcessing {
 | 
				
			||||||
 | 
					    my $hash     = shift;
 | 
				
			||||||
 | 
					    my $response = shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    my $name = $hash->{NAME};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    my @response = split '\|,', $response;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Log3( $name, 4,
 | 
				
			||||||
 | 
					        qq{GardenaSmartBridge ($name) - got result from asynchronous parsing} );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    my $decode_json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Log3( $name, 4, qq{GardenaSmartBridge ($name) - asynchronous finished.} );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( scalar(@response) > 0 ) {
 | 
				
			||||||
 | 
					        for my $json (@response) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            #################
 | 
				
			||||||
 | 
					            $decode_json = eval { decode_json($json) };
 | 
				
			||||||
 | 
					            if ($@) {
 | 
				
			||||||
 | 
					                Log3 $name, 5,
 | 
				
			||||||
 | 
					                  "GardenaSmartBridge ($name) - JSON error while request: $@";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Dispatch( $hash, $json, undef )
 | 
				
			||||||
 | 
					              if ( $decode_json->{category} ne 'gateway' );
 | 
				
			||||||
 | 
					            WriteReadings( $hash, $decode_json )
 | 
				
			||||||
 | 
					              if ( defined( $decode_json->{category} )
 | 
				
			||||||
 | 
					                && $decode_json->{category} eq 'gateway' );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sub PollChild {
 | 
				
			||||||
 | 
					    my $hash = shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    my $name = $hash->{NAME};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( defined( $hash->{".fhem"}{subprocess} ) ) {
 | 
				
			||||||
 | 
					        my $subprocess = $hash->{".fhem"}{subprocess};
 | 
				
			||||||
 | 
					        my $response   = $subprocess->readFromChild();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ( defined($response) ) {
 | 
				
			||||||
 | 
					            ResponseProcessingFinalFromSubProcessing( $hash, $response );
 | 
				
			||||||
 | 
					            $subprocess->wait();
 | 
				
			||||||
 | 
					            CleanSubprocess($hash);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Log3( $name, 4,
 | 
				
			||||||
 | 
					qq{GardenaSmartBridge ($name) - still waiting ($subprocess->{lasterror}).}
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        InternalTimer( gettimeofday() + 1,
 | 
				
			||||||
 | 
					            "FHEM::GardenaSmartBridge::PollChild", $hash );
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# ResponseSubprocessin muss in eine async ausgelagert werden
 | 
				
			||||||
 | 
					######################################
 | 
				
			||||||
 | 
					# Begin Childprozess
 | 
				
			||||||
 | 
					######################################
 | 
				
			||||||
 | 
					sub ResponseSubprocessing {
 | 
				
			||||||
 | 
					    my $subprocess = shift;
 | 
				
			||||||
 | 
					    my $buffer     = $subprocess->{buffer};
 | 
				
			||||||
 | 
					    my @response   = ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    my ( $json, $tail ) = ParseJSON($buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while ($json) {
 | 
				
			||||||
 | 
					        if ( defined($tail) and $tail ) {
 | 
				
			||||||
 | 
					            push @response, $json;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ( $json, $tail ) = ParseJSON($tail);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $subprocess->writeToParent( join '|', @response );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sub ParseJSON {
 | 
				
			||||||
 | 
					    my $buffer = shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    my $open  = 0;
 | 
				
			||||||
 | 
					    my $close = 0;
 | 
				
			||||||
 | 
					    my $msg   = '';
 | 
				
			||||||
 | 
					    my $tail  = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($buffer) {
 | 
				
			||||||
 | 
					        for my $c ( split //, $buffer ) {
 | 
				
			||||||
 | 
					            if ( $open == $close && $open > 0 ) {
 | 
				
			||||||
 | 
					                $tail .= $c;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if ( $c eq '{' ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $open++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                elsif ( $c eq '}' ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $close++;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $msg .= $c;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ( $open != $close ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $tail = $msg;
 | 
				
			||||||
 | 
					            $msg  = '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ( $msg, $tail );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					######################################
 | 
				
			||||||
 | 
					# End Childprozess
 | 
				
			||||||
 | 
					######################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sub CleanSubprocess {
 | 
				
			||||||
 | 
					    my $hash = shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    my $name = $hash->{NAME};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    delete( $hash->{".fhem"}{subprocess} );
 | 
				
			||||||
 | 
					    Log3( $name, 4, qq{GardenaSmartBridge ($name) - clean Subprocess} );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sub WriteReadings {
 | 
					sub WriteReadings {
 | 
				
			||||||
    my $hash        = shift;
 | 
					    my $hash        = shift;
 | 
				
			||||||
    my $decode_json = shift;
 | 
					    my $decode_json = shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #     print Dumper $decode_json;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    my $name = $hash->{NAME};
 | 
					    my $name = $hash->{NAME};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (   defined( $decode_json->{id} )
 | 
					    if (   defined( $decode_json->{id} )
 | 
				
			||||||
@@ -905,7 +1058,8 @@ sub WriteReadings {
 | 
				
			|||||||
                          {name} . '-' . $t,
 | 
					                          {name} . '-' . $t,
 | 
				
			||||||
                        $v
 | 
					                        $v
 | 
				
			||||||
                      )
 | 
					                      )
 | 
				
			||||||
                      if ($decode_json->{abilities}[0]{properties}[$properties]{name} !~ /ethernet_status|wifi_status/ );
 | 
					                      if ( $decode_json->{abilities}[0]{properties}[$properties]
 | 
				
			||||||
 | 
					                        {name} !~ /ethernet_status|wifi_status/ );
 | 
				
			||||||
                    if (
 | 
					                    if (
 | 
				
			||||||
                        (
 | 
					                        (
 | 
				
			||||||
                            $decode_json->{abilities}[0]{properties}
 | 
					                            $decode_json->{abilities}[0]{properties}
 | 
				
			||||||
@@ -931,10 +1085,9 @@ sub WriteReadings {
 | 
				
			|||||||
                        elsif ( $decode_json->{abilities}[0]{properties}
 | 
					                        elsif ( $decode_json->{abilities}[0]{properties}
 | 
				
			||||||
                            [$properties]{name} eq 'wifi_status' )
 | 
					                            [$properties]{name} eq 'wifi_status' )
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            #TODO: read valies if bridge connected to wifi
 | 
					 | 
				
			||||||
                            readingsBulkUpdateIfChanged( $hash,
 | 
					                            readingsBulkUpdateIfChanged( $hash,
 | 
				
			||||||
                                'wifi_status-ssid', $v->{ssid} )
 | 
					                                'wifi_status-ssid', $v->{ssid} )
 | 
				
			||||||
                              if (ref($v->{ssid}) ne 'HASH');
 | 
					                              if ( ref( $v->{ssid} ) ne 'HASH' );
 | 
				
			||||||
                            readingsBulkUpdateIfChanged( $hash,
 | 
					                            readingsBulkUpdateIfChanged( $hash,
 | 
				
			||||||
                                'wifi_status-mac', $v->{mac} );
 | 
					                                'wifi_status-mac', $v->{mac} );
 | 
				
			||||||
                            readingsBulkUpdateIfChanged( $hash,
 | 
					                            readingsBulkUpdateIfChanged( $hash,
 | 
				
			||||||
@@ -967,23 +1120,25 @@ sub getDevices {
 | 
				
			|||||||
    my $hash = shift;
 | 
					    my $hash = shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    my $name = $hash->{NAME};
 | 
					    my $name = $hash->{NAME};
 | 
				
			||||||
 | 
					    RemoveInternalTimer( $hash, "FHEM::GardenaSmartBridge::getDevices" );
 | 
				
			||||||
    RemoveInternalTimer($hash);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( not IsDisabled($name) ) {
 | 
					    if ( not IsDisabled($name) ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        delete $hash->{helper}{deviceList};
 | 
					        delete $hash->{helper}{deviceList};
 | 
				
			||||||
        my @list;
 | 
					        my @list;
 | 
				
			||||||
        @list = devspec2array('TYPE=GardenaSmartDevice');
 | 
					        @list = devspec2array('TYPE=GardenaSmartDevice');
 | 
				
			||||||
        for my $gardenaDev (@list){
 | 
					        for my $gardenaDev (@list) {
 | 
				
			||||||
            push( @{ $hash->{helper}{deviceList} }, $gardenaDev );
 | 
					            push( @{ $hash->{helper}{deviceList} }, $gardenaDev );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if ( AttrVal( $name, 'gardenaAccountEmail', 'none' ) ne 'none'
 | 
				
			||||||
 | 
					            && ( defined( ReadPassword( $hash, $name ) ) ) )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            Write( $hash, undef, undef, undef );
 | 
					            Write( $hash, undef, undef, undef );
 | 
				
			||||||
            Log3 $name, 4,
 | 
					            Log3 $name, 4,
 | 
				
			||||||
          "GardenaSmartBridge ($name) - fetch device list and device states";
 | 
					"GardenaSmartBridge ($name) - fetch device list and device states";
 | 
				
			||||||
 | 
					        }    # fi gardenaAccountEmail
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        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";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -1005,36 +1160,29 @@ sub getToken {
 | 
				
			|||||||
    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 ( exists( $hash->{helper}{session_id} ) );
 | 
				
			||||||
        && $hash->{helper}{session_id} );
 | 
					 | 
				
			||||||
    delete $hash->{helper}{user_id}
 | 
					    delete $hash->{helper}{user_id}
 | 
				
			||||||
      if ( defined( $hash->{helper}{user_id} ) && $hash->{helper}{user_id} );
 | 
					      if ( exists( $hash->{helper}{user_id} ) );
 | 
				
			||||||
    delete $hash->{helper}{locations_id}
 | 
					    delete $hash->{helper}{locations_id}
 | 
				
			||||||
      if ( defined( $hash->{helper}{locations_id} )
 | 
					      if ( exists( $hash->{helper}{locations_id} ) );
 | 
				
			||||||
        && $hash->{helper}{locations_id} );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Write(
 | 
					 | 
				
			||||||
    #     $hash,
 | 
					 | 
				
			||||||
    #     '"sessions": {"email": "'
 | 
					 | 
				
			||||||
    #       . AttrVal( $name, 'gardenaAccountEmail', 'none' )
 | 
					 | 
				
			||||||
    #       . '","password": "'
 | 
					 | 
				
			||||||
    #       . ReadPassword( $hash, $name ) . '"}',
 | 
					 | 
				
			||||||
    #     undef,
 | 
					 | 
				
			||||||
    #     undef
 | 
					 | 
				
			||||||
    # );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Write(
 | 
					    Write(
 | 
				
			||||||
        $hash,
 | 
					        $hash,
 | 
				
			||||||
        '"data": {"type":"token", "attributes":{"username": "'
 | 
					        '"data": {"type":"token", "attributes":{"username": "'
 | 
				
			||||||
          . AttrVal( $name, 'gardenaAccountEmail', 'none' )
 | 
					          . AttrVal( $name, 'gardenaAccountEmail', 'none' )
 | 
				
			||||||
          . '","password": "'
 | 
					          . '","password": "'
 | 
				
			||||||
            . ReadPassword( $hash, $name ) . '", "client_id":"smartgarden-jwt-client"}}',
 | 
					          . ReadPassword( $hash, $name )
 | 
				
			||||||
 | 
					          . '", "client_id":"smartgarden-jwt-client"}}',
 | 
				
			||||||
        undef,
 | 
					        undef,
 | 
				
			||||||
        undef
 | 
					        undef
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Log3 $name, 4, '"data": {"type":"token", "attributes":{"username": "'      . AttrVal( $name, 'gardenaAccountEmail', 'none' )      . '","password": "'
 | 
					    Log3 $name, 4,
 | 
				
			||||||
          . ReadPassword( $hash, $name ) . '", "client_id":"smartgarden-jwt-client"}}';
 | 
					        '"data": {"type":"token", "attributes":{"username": "'
 | 
				
			||||||
 | 
					      . AttrVal( $name, 'gardenaAccountEmail', 'none' )
 | 
				
			||||||
 | 
					      . '","password": "'
 | 
				
			||||||
 | 
					      . ReadPassword( $hash, $name )
 | 
				
			||||||
 | 
					      . '", "client_id":"smartgarden-jwt-client"}}';
 | 
				
			||||||
    Log3 $name, 3,
 | 
					    Log3 $name, 3,
 | 
				
			||||||
"GardenaSmartBridge ($name) - send credentials to fetch Token and locationId";
 | 
					"GardenaSmartBridge ($name) - send credentials to fetch Token and locationId";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1085,7 +1233,7 @@ sub ReadPassword {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Log3 $name, 3,
 | 
					        Log3 $name, 3,
 | 
				
			||||||
"GardenaSmartBridge ($name) - unable to read password from file: $err";
 | 
					"GardenaSmartBridge ($name) - unable to read password from file: $err";
 | 
				
			||||||
        return undef;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1111,7 +1259,7 @@ sub ReadPassword {
 | 
				
			|||||||
    else {
 | 
					    else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Log3 $name, 3, "GardenaSmartBridge ($name) - No password in file";
 | 
					        Log3 $name, 3, "GardenaSmartBridge ($name) - No password in file";
 | 
				
			||||||
        return undef;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
@@ -1129,59 +1277,6 @@ sub Rename {
 | 
				
			|||||||
    return;
 | 
					    return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sub ParseJSON {
 | 
					 | 
				
			||||||
    my $hash   = shift;
 | 
					 | 
				
			||||||
    my $buffer = shift;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    my $name  = $hash->{NAME};
 | 
					 | 
				
			||||||
    my $open  = 0;
 | 
					 | 
				
			||||||
    my $close = 0;
 | 
					 | 
				
			||||||
    my $msg   = '';
 | 
					 | 
				
			||||||
    my $tail  = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ($buffer) {
 | 
					 | 
				
			||||||
        for my $c ( split //, $buffer ) {
 | 
					 | 
				
			||||||
            if ( $open == $close && $open > 0 ) {
 | 
					 | 
				
			||||||
                $tail .= $c;
 | 
					 | 
				
			||||||
                Log3 $name, 5,
 | 
					 | 
				
			||||||
                  "GardenaSmartBridge ($name) - $open == $close and $open > 0";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            elsif ( ( $open == $close ) && ( $c ne '{' ) ) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Log3 $name, 5,
 | 
					 | 
				
			||||||
"GardenaSmartBridge ($name) - Garbage character before message: "
 | 
					 | 
				
			||||||
                  . $c;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if ( $c eq '{' ) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    $open++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                elsif ( $c eq '}' ) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    $close++;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                $msg .= $c;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ( $open != $close ) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $tail = $msg;
 | 
					 | 
				
			||||||
            $msg  = '';
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Log3 $name, 5,
 | 
					 | 
				
			||||||
      "GardenaSmartBridge ($name) - return msg: $msg and tail: $tail";
 | 
					 | 
				
			||||||
    return ( $msg, $tail );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sub createHttpValueStrings {
 | 
					sub createHttpValueStrings {
 | 
				
			||||||
    my ( $hash, $payload, $deviceId, $abilities, $service_id ) = @_;
 | 
					    my ( $hash, $payload, $deviceId, $abilities, $service_id ) = @_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1190,9 +1285,9 @@ sub createHttpValueStrings {
 | 
				
			|||||||
    my $uri        = '';
 | 
					    my $uri        = '';
 | 
				
			||||||
    my $method     = 'POST';
 | 
					    my $method     = 'POST';
 | 
				
			||||||
    $header .= "\r\nAuthorization: Bearer $session_id"
 | 
					    $header .= "\r\nAuthorization: Bearer $session_id"
 | 
				
			||||||
      if ( defined($hash->{helper}{session_id}) );
 | 
					      if ( defined( $hash->{helper}{session_id} ) );
 | 
				
			||||||
    $header .= "\r\nAuthorization-Provider: husqvarna"
 | 
					    $header .= "\r\nAuthorization-Provider: husqvarna"
 | 
				
			||||||
      if ( defined($hash->{helper}{session_id}) );
 | 
					      if ( defined( $hash->{helper}{session_id} ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #  $header .= "\r\nx-api-key: $session_id"
 | 
					    #  $header .= "\r\nx-api-key: $session_id"
 | 
				
			||||||
    #    if ( defined( $hash->{helper}{session_id} ) );
 | 
					    #    if ( defined( $hash->{helper}{session_id} ) );
 | 
				
			||||||
@@ -1200,20 +1295,23 @@ sub createHttpValueStrings {
 | 
				
			|||||||
    $payload = '{}'                 if ( !defined($payload) );
 | 
					    $payload = '{}'                 if ( !defined($payload) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( $payload eq '{}' ) {
 | 
					    if ( $payload eq '{}' ) {
 | 
				
			||||||
        $method = 'GET';
 | 
					        $method  = 'GET' if ( defined( $hash->{helper}{session_id} ) );
 | 
				
			||||||
        $payload = '';
 | 
					        $payload = '';
 | 
				
			||||||
        $uri .= '/locations?locatioId=null&user_id=' . $hash->{helper}{user_id}
 | 
					        $uri .= '/locations?locatioId=null&user_id=' . $hash->{helper}{user_id}
 | 
				
			||||||
          if ( exists( $hash->{helper}{user_id} )
 | 
					          if ( exists( $hash->{helper}{user_id} )
 | 
				
			||||||
            && !defined( $hash->{helper}{locations_id} ) );
 | 
					            && !defined( $hash->{helper}{locations_id} ) );
 | 
				
			||||||
        readingsSingleUpdate( $hash, 'state', 'fetch locationId', 1 )
 | 
					        readingsSingleUpdate( $hash, 'state', 'fetch locationId', 1 )
 | 
				
			||||||
          if ( !defined( $hash->{helper}{locations_id} ) );
 | 
					          if ( exists( $hash->{helper}{user_id} )
 | 
				
			||||||
        $uri .= '/auth/token' if ( !defined( $hash->{helper}{session_id} ) );
 | 
					            && !defined( $hash->{helper}{locations_id} ) );
 | 
				
			||||||
        $uri .= '/devices'
 | 
					        $uri .= '/devices'
 | 
				
			||||||
          if (!defined($abilities)
 | 
					          if (!defined($abilities)
 | 
				
			||||||
            && defined( $hash->{helper}{locations_id} ) );
 | 
					            && defined( $hash->{helper}{locations_id} ) );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $uri = '/devices/'.InternalVal($hash->{helper}{debug_device}, 'DEVICEID', 0 ) if ( exists ($hash->{helper}{debug_device}));
 | 
					    $uri =
 | 
				
			||||||
 | 
					      '/devices/' . InternalVal( $hash->{helper}{debug_device}, 'DEVICEID', 0 )
 | 
				
			||||||
 | 
					      if ( defined( $hash->{helper}{debug_device} )
 | 
				
			||||||
 | 
					        && defined( $hash->{helper}{locations_id} ) );
 | 
				
			||||||
    $uri = '/auth/token' if ( !defined( $hash->{helper}{session_id} ) );
 | 
					    $uri = '/auth/token' if ( !defined( $hash->{helper}{session_id} ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( defined( $hash->{helper}{locations_id} ) ) {
 | 
					    if ( defined( $hash->{helper}{locations_id} ) ) {
 | 
				
			||||||
@@ -1222,11 +1320,7 @@ sub createHttpValueStrings {
 | 
				
			|||||||
            $method = 'PUT';
 | 
					            $method = 'PUT';
 | 
				
			||||||
            my $dhash = $modules{GardenaSmartDevice}{defptr}{$deviceId};
 | 
					            my $dhash = $modules{GardenaSmartDevice}{defptr}{$deviceId};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $uri .=
 | 
					            $uri .= '/devices/' . $deviceId . '/settings/' . $service_id
 | 
				
			||||||
                '/devices/'
 | 
					 | 
				
			||||||
              . $deviceId
 | 
					 | 
				
			||||||
              . '/settings/'
 | 
					 | 
				
			||||||
              . $service_id
 | 
					 | 
				
			||||||
              if ( defined($abilities)
 | 
					              if ( defined($abilities)
 | 
				
			||||||
                && defined($payload)
 | 
					                && defined($payload)
 | 
				
			||||||
                && $abilities =~ /.*_settings/ );
 | 
					                && $abilities =~ /.*_settings/ );
 | 
				
			||||||
@@ -1262,7 +1356,11 @@ sub createHttpValueStrings {
 | 
				
			|||||||
              . $deviceId
 | 
					              . $deviceId
 | 
				
			||||||
              . '/abilities/'
 | 
					              . '/abilities/'
 | 
				
			||||||
              . $abilities
 | 
					              . $abilities
 | 
				
			||||||
              . ( defined($valve_id) ? '/properties/watering_timer_'. $valve_id : '/command')
 | 
					              . (
 | 
				
			||||||
 | 
					                defined($valve_id)
 | 
				
			||||||
 | 
					                ? '/properties/watering_timer_' . $valve_id
 | 
				
			||||||
 | 
					                : '/command'
 | 
				
			||||||
 | 
					              );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        elsif (defined($abilities)
 | 
					        elsif (defined($abilities)
 | 
				
			||||||
@@ -1279,6 +1377,19 @@ sub createHttpValueStrings {
 | 
				
			|||||||
              . $abilities
 | 
					              . $abilities
 | 
				
			||||||
              . '/properties/manual_watering_timer';
 | 
					              . '/properties/manual_watering_timer';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        elsif (defined($abilities)
 | 
				
			||||||
 | 
					            && defined($payload)
 | 
				
			||||||
 | 
					            && $abilities eq 'watering_button_config' )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $method = 'PUT';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $uri .=
 | 
				
			||||||
 | 
					                '/devices/'
 | 
				
			||||||
 | 
					              . $deviceId
 | 
				
			||||||
 | 
					              . '/abilities/watering'
 | 
				
			||||||
 | 
					              . '/properties/button_config_time';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        elsif (defined($abilities)
 | 
					        elsif (defined($abilities)
 | 
				
			||||||
            && defined($payload)
 | 
					            && defined($payload)
 | 
				
			||||||
@@ -1463,9 +1574,9 @@ sub DeletePassword {
 | 
				
			|||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "release_status": "stable",
 | 
					  "release_status": "stable",
 | 
				
			||||||
  "license": "GPL_2",
 | 
					  "license": "GPL_2",
 | 
				
			||||||
  "version": "v2.4.0",
 | 
					  "version": "v2.5.2",
 | 
				
			||||||
  "author": [
 | 
					  "author": [
 | 
				
			||||||
    "Marko Oldenburg <leongaultier@gmail.com>"
 | 
					    "Marko Oldenburg <fhemdevelopment@cooltux.net>"
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "x_fhem_maintainer": [
 | 
					  "x_fhem_maintainer": [
 | 
				
			||||||
    "CoolTux"
 | 
					    "CoolTux"
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,2 +1,2 @@
 | 
				
			|||||||
UPD 2021-05-22_04:53:56 46135 FHEM/73_GardenaSmartBridge.pm
 | 
					UPD 2022-07-21_19:43:48 49634 FHEM/73_GardenaSmartBridge.pm
 | 
				
			||||||
UPD 2021-05-22_04:54:14 51644 FHEM/74_GardenaSmartDevice.pm
 | 
					UPD 2022-08-11_14:24:26 107803 FHEM/74_GardenaSmartDevice.pm
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user