| 
						
					 | 
					 | 
					@@ -30,9 +30,9 @@
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					# $data = eval{decode_json($data)};
 | 
					 | 
					 | 
					 | 
					# $data = eval{decode_json($data)};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#
 | 
					 | 
					 | 
					 | 
					#
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					# if($@){
 | 
					 | 
					 | 
					 | 
					# if($@){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#   Log3($SELF, 2, "$TYPE ($SELF) - error while request: $@");
 | 
					 | 
					 | 
					 | 
					#   ::Log3($SELF, 2, "$TYPE ($SELF) - error while request: $@");
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#
 | 
					 | 
					 | 
					 | 
					#
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#   readingsSingleUpdate($hash, "state", "error", 1);
 | 
					 | 
					 | 
					 | 
					#   ::readingsSingleUpdate($hash, "state", "error", 1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#
 | 
					 | 
					 | 
					 | 
					#
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#   return;
 | 
					 | 
					 | 
					 | 
					#   return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					# }
 | 
					 | 
					 | 
					 | 
					# }
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -52,12 +52,13 @@
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					##
 | 
					 | 
					 | 
					 | 
					##
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					##
 | 
					 | 
					 | 
					 | 
					##
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					package FHEM::Tesla::Powerwall;
 | 
					 | 
					 | 
					 | 
					package FHEM::Devices::Tesla::Powerwall;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use strict;
 | 
					 | 
					 | 
					 | 
					use strict;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use warnings;
 | 
					 | 
					 | 
					 | 
					use warnings;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use GPUtils qw(GP_Import GP_Export);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use HttpUtils;
 | 
					 | 
					 | 
					 | 
					use HttpUtils;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					use FHEM::Core::Authentication::Passwords qw(:ALL);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use Data::Dumper;
 | 
					 | 
					 | 
					 | 
					use Data::Dumper;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					# try to use JSON::MaybeXS wrapper
 | 
					 | 
					 | 
					 | 
					# try to use JSON::MaybeXS wrapper
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -131,45 +132,6 @@ if ($@) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					## Import der FHEM Funktionen
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#-- Run before package compilation
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					BEGIN {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    # Import from main context
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    GP_Import(
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        qw(
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          readingsSingleUpdate
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          readingsBulkUpdate
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          readingsBulkUpdateIfChanged
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          readingsBeginUpdate
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          readingsEndUpdate
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          setKeyValue
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          getKeyValue
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          getUniqueId
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          CommandAttr
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          defs
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          Log3
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          readingFnAttributes
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          HttpUtils_NonblockingGet
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          AttrVal
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          ReadingsVal
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          IsDisabled
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          deviceEvents
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          init_done
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          gettimeofday
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          InternalTimer
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          RemoveInternalTimer)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    );
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#-- Export to main context with different name
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					GP_Export(
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    qw(
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Initialize
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Timer_GetData
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Write
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      )
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					my %paths = (
 | 
					 | 
					 | 
					 | 
					my %paths = (
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    'statussoe'         => 'system_status/soe',
 | 
					 | 
					 | 
					 | 
					    'statussoe'         => 'system_status/soe',
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -206,13 +168,35 @@ sub Define {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    $hash->{HOST}        = $host;
 | 
					 | 
					 | 
					 | 
					    $hash->{HOST}        = $host;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    $hash->{INTERVAL}    = 300;
 | 
					 | 
					 | 
					 | 
					    $hash->{INTERVAL}    = 300;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    $hash->{VERSION}     = version->parse($VERSION)->normal;
 | 
					 | 
					 | 
					 | 
					    $hash->{VERSION}     = version->parse($VERSION)->normal;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    $hash->{NOTIFYDEV}   = qq(global,${name});
 | 
					 | 
					 | 
					 | 
					    $hash->{NOTIFYDEV}   = qq(global,$name);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    $hash->{actionQueue} = [];
 | 
					 | 
					 | 
					 | 
					    $hash->{actionQueue} = [];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    CommandAttr( undef, $name . q{ room Tesla} )
 | 
					 | 
					 | 
					 | 
					    ::CommandAttr( undef, $name . q{ room Tesla} )
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if ( AttrVal( $name, 'room', 'none' ) eq 'none' );
 | 
					 | 
					 | 
					 | 
					      if ( ::AttrVal( $name, 'room', 'none' ) eq 'none' );
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Log3($name, 3,
 | 
					 | 
					 | 
					 | 
					    ::Log3($name, 3,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					qq(TeslaPowerwall2AC \(${name}\) - defined TeslaPowerwall2AC Device with Host ${host} and Interval $hash->{INTERVAL}));
 | 
					 | 
					 | 
					 | 
					qq(TeslaPowerwall2AC ($name) - defined TeslaPowerwall2AC Device with Host $host and Interval $hash->{INTERVAL}));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ### create password object to handle pass keystore
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    $hash->{helper}->{passObj}  = FHEM::Core::Authentication::Passwords->new($hash->{TYPE});
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ## kann nach einiger Zeit gelöscht werden genauso wie auch ReadPassword und DeletePassword
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    if ( defined( ReadPassword( $hash, $name ) ) ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        my ($passResp,$passErr);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        ($passResp,$passErr) = $hash->{helper}->{passObj}->setStorePassword($name,ReadPassword( $hash, $name ));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        ::Log3($name, 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					qq(TeslaPowerwall2AC ($name) - error while saving the password - $passErr))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          if ( !defined($passResp)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					           and defined($passErr) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        ::Log3($name, 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					qq(TeslaPowerwall2AC ($name) - password successfully saved))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          if ( defined($passResp)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					           and !defined($passErr) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					           
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        DeletePassword($hash);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return;
 | 
					 | 
					 | 
					 | 
					    return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -221,25 +205,25 @@ sub Undef {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $hash    = shift;
 | 
					 | 
					 | 
					 | 
					    my $hash    = shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $name    = shift;
 | 
					 | 
					 | 
					 | 
					    my $name    = shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    RemoveInternalTimer($hash);
 | 
					 | 
					 | 
					 | 
					    ::RemoveInternalTimer($hash);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Log3($name, 3, qq(TeslaPowerwall2AC \(${name}\) - Device ${name} deleted));
 | 
					 | 
					 | 
					 | 
					    ::Log3($name, 3, qq(TeslaPowerwall2AC ($name) - Device $name deleted));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return;
 | 
					 | 
					 | 
					 | 
					    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' && $attrVal eq '1' ) {
 | 
					 | 
					 | 
					 | 
					        if ( $cmd eq 'set' && $attrVal eq '1' ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            RemoveInternalTimer($hash);
 | 
					 | 
					 | 
					 | 
					            ::RemoveInternalTimer($hash);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
 | 
					 | 
					 | 
					 | 
					            ::readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Log3($name, 3, qq(TeslaPowerwall2AC \(${name}\) - disabled));
 | 
					 | 
					 | 
					 | 
					            ::Log3($name, 3, qq(TeslaPowerwall2AC ($name) - disabled));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        elsif ( $cmd eq 'del' ) {
 | 
					 | 
					 | 
					 | 
					        elsif ( $cmd eq 'del' ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Log3($name, 3, qq(TeslaPowerwall2AC \(${name}\) - enabled));
 | 
					 | 
					 | 
					 | 
					            ::Log3($name, 3, qq(TeslaPowerwall2AC ($name) - enabled));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -248,38 +232,38 @@ sub Attr {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            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?)+$/ );
 | 
					 | 
					 | 
					 | 
					              unless ( $attrVal =~ /^((\d{2}:\d{2})-(\d{2}:\d{2})\s?)+$/ );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Log3($name, 3, qq(TeslaPowerwall2AC \(${name}\) - disabledForIntervals));
 | 
					 | 
					 | 
					 | 
					            ::Log3($name, 3, qq(TeslaPowerwall2AC ($name) - disabledForIntervals));
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
 | 
					 | 
					 | 
					 | 
					            ::readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        elsif ( $cmd eq 'del' ) {
 | 
					 | 
					 | 
					 | 
					        elsif ( $cmd eq 'del' ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Log3($name, 3, qq(TeslaPowerwall2AC \(${name}\) - enabled));
 | 
					 | 
					 | 
					 | 
					            ::Log3($name, 3, qq(TeslaPowerwall2AC ($name) - enabled));
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            readingsSingleUpdate( $hash, 'state', 'active', 1 );
 | 
					 | 
					 | 
					 | 
					            ::readingsSingleUpdate( $hash, 'state', 'active', 1 );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if ( $attrName eq 'interval' ) {
 | 
					 | 
					 | 
					 | 
					    if ( $attrName eq 'interval' ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if ( $cmd eq 'set' ) {
 | 
					 | 
					 | 
					 | 
					        if ( $cmd eq 'set' ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if ( $attrVal < 60 ) {
 | 
					 | 
					 | 
					 | 
					            if ( $attrVal < 60 ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                Log3($name, 3,
 | 
					 | 
					 | 
					 | 
					                ::Log3($name, 3,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					qq(TeslaPowerwall2AC \(${name}\) - interval too small, please use something >= 60 (sec), default is 300 (sec)));
 | 
					 | 
					 | 
					 | 
					qq(TeslaPowerwall2AC ($name) - interval too small, please use something >= 60 (sec), default is 300 (sec)));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                return
 | 
					 | 
					 | 
					 | 
					                return
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					q{interval too small, please use something >= 60 (sec), default is 300 (sec)};
 | 
					 | 
					 | 
					 | 
					q{interval too small, please use something >= 60 (sec), default is 300 (sec)};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }
 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            else {
 | 
					 | 
					 | 
					 | 
					            else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                RemoveInternalTimer($hash);
 | 
					 | 
					 | 
					 | 
					                ::RemoveInternalTimer($hash);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                $hash->{INTERVAL} = $attrVal;
 | 
					 | 
					 | 
					 | 
					                $hash->{INTERVAL} = $attrVal;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                Log3($name, 3,
 | 
					 | 
					 | 
					 | 
					                ::Log3($name, 3,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                  qq(TeslaPowerwall2AC \(${name}\) - set interval to ${attrVal}));
 | 
					 | 
					 | 
					 | 
					                  qq(TeslaPowerwall2AC ($name) - set interval to $attrVal));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                Timer_GetData($hash);
 | 
					 | 
					 | 
					 | 
					                Timer_GetData($hash);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }
 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        elsif ( $cmd eq 'del' ) {
 | 
					 | 
					 | 
					 | 
					        elsif ( $cmd eq 'del' ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            RemoveInternalTimer($hash);
 | 
					 | 
					 | 
					 | 
					            ::RemoveInternalTimer($hash);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            $hash->{INTERVAL} = 300;
 | 
					 | 
					 | 
					 | 
					            $hash->{INTERVAL} = 300;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Log3($name, 3,
 | 
					 | 
					 | 
					 | 
					            ::Log3($name, 3,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              qq(TeslaPowerwall2AC \(${name}\) - set interval to default));
 | 
					 | 
					 | 
					 | 
					              qq(TeslaPowerwall2AC ($name) - set interval to default));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Timer_GetData($hash);
 | 
					 | 
					 | 
					 | 
					            Timer_GetData($hash);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -292,11 +276,11 @@ sub Notify {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $dev     = shift;
 | 
					 | 
					 | 
					 | 
					    my $dev     = shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    
 | 
					 | 
					 | 
					 | 
					    
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $name    = $hash->{NAME};
 | 
					 | 
					 | 
					 | 
					    my $name    = $hash->{NAME};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return if ( IsDisabled($name) );
 | 
					 | 
					 | 
					 | 
					    return if ( ::IsDisabled($name) );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $devname = $dev->{NAME};
 | 
					 | 
					 | 
					 | 
					    my $devname = $dev->{NAME};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $devtype = $dev->{TYPE};
 | 
					 | 
					 | 
					 | 
					    my $devtype = $dev->{TYPE};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $events  = deviceEvents( $dev, 1 );
 | 
					 | 
					 | 
					 | 
					    my $events  = ::deviceEvents( $dev, 1 );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return if ( !$events );
 | 
					 | 
					 | 
					 | 
					    return if ( !$events );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Timer_GetData($hash)
 | 
					 | 
					 | 
					 | 
					    Timer_GetData($hash)
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -306,7 +290,7 @@ sub Notify {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          or grep /^DELETEATTR.$name.disable$/, @{$events}
 | 
					 | 
					 | 
					 | 
					          or grep /^DELETEATTR.$name.disable$/, @{$events}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          or grep /^DELETEATTR.$name.interval$/, @{$events}
 | 
					 | 
					 | 
					 | 
					          or grep /^DELETEATTR.$name.interval$/, @{$events}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          or grep /^DEFINED.$name$/, @{$events} )
 | 
					 | 
					 | 
					 | 
					          or grep /^DEFINED.$name$/, @{$events} )
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        and $init_done
 | 
					 | 
					 | 
					 | 
					        and $::init_done
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      );
 | 
					 | 
					 | 
					 | 
					      );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return;
 | 
					 | 
					 | 
					 | 
					    return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -316,7 +300,7 @@ sub Get {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $aArg = shift;
 | 
					 | 
					 | 
					 | 
					    my $aArg = shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $name = shift @$aArg;
 | 
					 | 
					 | 
					 | 
					    my $name = shift @$aArg;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $cmd  = shift @$aArg // return qq(get ${name} needs at least one argument);
 | 
					 | 
					 | 
					 | 
					    my $cmd  = shift @$aArg // return qq(get $name needs at least one argument);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $arg;
 | 
					 | 
					 | 
					 | 
					    my $arg;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if ( $cmd eq 'statusSOE' ) {
 | 
					 | 
					 | 
					 | 
					    if ( $cmd eq 'statusSOE' ) {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -359,8 +343,9 @@ sub Get {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        my $list = '';
 | 
					 | 
					 | 
					 | 
					        my $list = '';
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        $list .=
 | 
					 | 
					 | 
					 | 
					        $list .=
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					'statusSOE:noArg aggregates:noArg siteinfo:noArg sitemaster:noArg powerwalls:noArg registration:noArg status:noArg'
 | 
					 | 
					 | 
					 | 
					'statusSOE:noArg aggregates:noArg siteinfo:noArg sitemaster:noArg powerwalls:noArg registration:noArg status:noArg'
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if(  AttrVal($name,'emailaddr','none') ne 'none'
 | 
					 | 
					 | 
					 | 
					  if(  ::AttrVal($name,'emailaddr','none') ne 'none'
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    && defined(ReadPassword($hash, $name))
 | 
					 | 
					 | 
					 | 
					    && exists($hash->{helper}->{passObj})
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    && defined($hash->{helper}->{passObj}->getReadPassword($name))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    && defined($hash->{TOKEN}) );
 | 
					 | 
					 | 
					 | 
					    && defined($hash->{TOKEN}) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return 'Unknown argument ' . $cmd . ', choose one of ' . $list;
 | 
					 | 
					 | 
					 | 
					        return 'Unknown argument ' . $cmd . ', choose one of ' . $list;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -382,7 +367,7 @@ sub Set {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $hArg = shift;
 | 
					 | 
					 | 
					 | 
					    my $hArg = shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $name = shift @$aArg;
 | 
					 | 
					 | 
					 | 
					    my $name = shift @$aArg;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    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);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $arg;
 | 
					 | 
					 | 
					 | 
					    my $arg;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -391,25 +376,45 @@ sub Set {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    elsif ( lc $cmd eq 'setpassword' ) {
 | 
					 | 
					 | 
					 | 
					    elsif ( lc $cmd eq 'setpassword' ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return q{please set Attribut emailaddr first}
 | 
					 | 
					 | 
					 | 
					        return q{please set Attribut emailaddr first}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if ( AttrVal( $name, 'emailaddr', 'none' ) eq 'none' );
 | 
					 | 
					 | 
					 | 
					          if ( ::AttrVal( $name, 'emailaddr', 'none' ) eq 'none' );
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return qq(usage: ${cmd} pass=<password>) if ( scalar( @{$aArg} ) != 0
 | 
					 | 
					 | 
					 | 
					        return qq(usage: $cmd pass=<password>) if ( scalar( @{$aArg} ) != 0
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                                   || scalar(keys %{$hArg}) != 1 );
 | 
					 | 
					 | 
					 | 
					                                                   || scalar(keys %{$hArg}) != 1 );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        my ($passResp,$passErr);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        ($passResp,$passErr) = $hash->{helper}->{passObj}->setStorePassword($name,$hArg->{'pass'});
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        return qq{error while saving the password - $passErr}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          if ( !defined($passResp)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					           and defined($passErr) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        StorePassword( $hash, $name, $hArg->{'pass'} );
 | 
					 | 
					 | 
					 | 
					        return Timer_GetData($hash)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return Timer_GetData($hash);
 | 
					 | 
					 | 
					 | 
					          if ( defined($passResp)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					           and !defined($passErr) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    elsif ( lc $cmd eq 'removepassword' ) {
 | 
					 | 
					 | 
					 | 
					    elsif ( lc $cmd eq 'removepassword' ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return "usage: $cmd" if ( scalar( @{$aArg} ) != 0 );
 | 
					 | 
					 | 
					 | 
					        return "usage: $cmd" if ( scalar( @{$aArg} ) != 0 );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        DeletePassword($hash);
 | 
					 | 
					 | 
					 | 
					        my ($passResp,$passErr);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return Timer_GetData($hash);
 | 
					 | 
					 | 
					 | 
					        ($passResp,$passErr) = $hash->{helper}->{passObj}->setDeletePassword($name);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        return qq{error while saving the password - $passErr}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          if ( !defined($passResp)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					           and defined($passErr) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        return q{password successfully removed}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          if ( defined($passResp)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					           and !defined($passErr) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    else {
 | 
					 | 
					 | 
					 | 
					    else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        my $list = ( defined(ReadPassword($hash, $name)) ? 'removePassword:noArg ' : 'setPassword ');
 | 
					 | 
					 | 
					 | 
					        my $list = ( exists($hash->{helper}->{passObj})
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            && defined($hash->{helper}->{passObj}->getReadPassword($name))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          ? 'removePassword:noArg '
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          : 'setPassword ');
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        $list .= 'powerwalls:run,stop'
 | 
					 | 
					 | 
					 | 
					        $list .= 'powerwalls:run,stop'
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if ( AttrVal( $name, 'devel', 0 ) == 1
 | 
					 | 
					 | 
					 | 
					          if ( ::AttrVal( $name, 'devel', 0 ) == 1
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            && defined(ReadPassword($hash, $name))
 | 
					 | 
					 | 
					 | 
					            && exists($hash->{helper}->{passObj})
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            && defined($hash->{helper}->{passObj}->getReadPassword($name))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            && defined($hash->{TOKEN}) );
 | 
					 | 
					 | 
					 | 
					            && defined($hash->{TOKEN}) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return 'Unknown argument ' . $cmd . ', choose one of ' . $list;
 | 
					 | 
					 | 
					 | 
					        return 'Unknown argument ' . $cmd . ', choose one of ' . $list;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -425,18 +430,22 @@ sub Timer_GetData {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $hash = shift;
 | 
					 | 
					 | 
					 | 
					    my $hash = shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $name = $hash->{NAME};
 | 
					 | 
					 | 
					 | 
					    my $name = $hash->{NAME};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    RemoveInternalTimer($hash);
 | 
					 | 
					 | 
					 | 
					    ::RemoveInternalTimer($hash);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if ( defined( $hash->{actionQueue} )
 | 
					 | 
					 | 
					 | 
					    if ( defined( $hash->{actionQueue} )
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      && scalar( @{ $hash->{actionQueue} } ) == 0 )
 | 
					 | 
					 | 
					 | 
					      && scalar( @{ $hash->{actionQueue} } ) == 0 )
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    {
 | 
					 | 
					 | 
					 | 
					    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if ( !IsDisabled($name) ) {
 | 
					 | 
					 | 
					 | 
					        if ( !::IsDisabled($name) ) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return readingsSingleUpdate( $hash, 'state',
 | 
					 | 
					 | 
					 | 
					            return ::readingsSingleUpdate( $hash, 'state',
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              'please set Attribut emailaddr first', 1 )
 | 
					 | 
					 | 
					 | 
					              'please set Attribut emailaddr first', 1 )
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if ( AttrVal( $name, 'emailaddr', 'none' ) eq 'none' );
 | 
					 | 
					 | 
					 | 
					                if ( ::AttrVal( $name, 'emailaddr', 'none' ) eq 'none' );
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return readingsSingleUpdate( $hash, 'state',
 | 
					 | 
					 | 
					 | 
					            return ::readingsSingleUpdate( $hash, 'state',
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              'please set password first', 1 )
 | 
					 | 
					 | 
					 | 
					              'please set password first', 1 )
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if ( !defined( ReadPassword( $hash, $name ) ) );
 | 
					 | 
					 | 
					 | 
					                if (   !exists($hash->{helper}->{passObj})
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                  || ( exists($hash->{helper}->{passObj})
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    && !defined($hash->{helper}->{passObj}->getReadPassword($name))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                  )
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if ( !defined( $hash->{TOKEN}) ) {
 | 
					 | 
					 | 
					 | 
					            if ( !defined( $hash->{TOKEN}) ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                unshift( @{ $hash->{actionQueue} }, 'login' );
 | 
					 | 
					 | 
					 | 
					                unshift( @{ $hash->{actionQueue} }, 'login' );
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -450,14 +459,14 @@ sub Timer_GetData {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Write($hash);
 | 
					 | 
					 | 
					 | 
					            Write($hash);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        else {
 | 
					 | 
					 | 
					 | 
					        else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
 | 
					 | 
					 | 
					 | 
					            return ::readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    InternalTimer( gettimeofday() + $hash->{INTERVAL},
 | 
					 | 
					 | 
					 | 
					    ::InternalTimer( ::gettimeofday() + $hash->{INTERVAL},
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        'Powerwall_Timer_GetData', $hash );
 | 
					 | 
					 | 
					 | 
					        \&FHEM::Devices::Tesla::Powerwall::Timer_GetData, $hash );
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Log3($name, 4,
 | 
					 | 
					 | 
					 | 
					    ::Log3($name, 4,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      qq(TeslaPowerwall2AC \(${name}\) - Call InternalTimer Timer_GetData));
 | 
					 | 
					 | 
					 | 
					      qq(TeslaPowerwall2AC ($name) - Call ::InternalTimer Timer_GetData));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					sub Write {
 | 
					 | 
					 | 
					 | 
					sub Write {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -467,7 +476,7 @@ sub Write {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my ( $uri, $method, $header, $data, $path ) =
 | 
					 | 
					 | 
					 | 
					    my ( $uri, $method, $header, $data, $path ) =
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      CreateUri( $hash, pop( @{ $hash->{actionQueue} } ) );
 | 
					 | 
					 | 
					 | 
					      CreateUri( $hash, pop( @{ $hash->{actionQueue} } ) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    readingsSingleUpdate(
 | 
					 | 
					 | 
					 | 
					    ::readingsSingleUpdate(
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        $hash,
 | 
					 | 
					 | 
					 | 
					        $hash,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        'state',
 | 
					 | 
					 | 
					 | 
					        'state',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        'fetch data - '
 | 
					 | 
					 | 
					 | 
					        'fetch data - '
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -476,7 +485,7 @@ sub Write {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        1
 | 
					 | 
					 | 
					 | 
					        1
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    );
 | 
					 | 
					 | 
					 | 
					    );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    HttpUtils_NonblockingGet(
 | 
					 | 
					 | 
					 | 
					    ::HttpUtils_NonblockingGet(
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        {
 | 
					 | 
					 | 
					 | 
					        {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            url       => 'https://' . $uri,
 | 
					 | 
					 | 
					 | 
					            url       => 'https://' . $uri,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            timeout   => 5,
 | 
					 | 
					 | 
					 | 
					            timeout   => 5,
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -485,12 +494,13 @@ sub Write {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            header    => $header,
 | 
					 | 
					 | 
					 | 
					            header    => $header,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            hash      => $hash,
 | 
					 | 
					 | 
					 | 
					            hash      => $hash,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            setCmd    => $path,
 | 
					 | 
					 | 
					 | 
					            setCmd    => $path,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            sslargs => { SSL_hostname => 0, verify_hostname => 0, SSL_verify_mode => 0 },
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            doTrigger => 1,
 | 
					 | 
					 | 
					 | 
					            doTrigger => 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            callback  => \&ErrorHandling,
 | 
					 | 
					 | 
					 | 
					            callback  => \&ErrorHandling,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    );
 | 
					 | 
					 | 
					 | 
					    );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Log3($name, 4, qq(TeslaPowerwall2AC \(${name}\) - Send with URI: https://${uri}));
 | 
					 | 
					 | 
					 | 
					    ::Log3($name, 4, qq(TeslaPowerwall2AC ($name) - Send with URI: https://$uri));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					sub ErrorHandling {
 | 
					 | 
					 | 
					 | 
					sub ErrorHandling {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -506,12 +516,12 @@ sub ErrorHandling {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if ( defined($err) ) {
 | 
					 | 
					 | 
					 | 
					    if ( defined($err) ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if ( $err ne '' ) {
 | 
					 | 
					 | 
					 | 
					        if ( $err ne '' ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            readingsBeginUpdate($hash);
 | 
					 | 
					 | 
					 | 
					            ::readingsBeginUpdate($hash);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            readingsBulkUpdate( $hash, 'state',            $err, 1 );
 | 
					 | 
					 | 
					 | 
					            ::readingsBulkUpdate( $hash, 'state',            $err, 1 );
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            readingsBulkUpdate( $hash, 'lastRequestError', $err, 1 );
 | 
					 | 
					 | 
					 | 
					            ::readingsBulkUpdate( $hash, 'lastRequestError', $err, 1 );
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            readingsEndUpdate( $hash, 1 );
 | 
					 | 
					 | 
					 | 
					            ::readingsEndUpdate( $hash, 1 );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Log3($name, 3, qq(TeslaPowerwall2AC \(${name}\) - RequestERROR: ${err}));
 | 
					 | 
					 | 
					 | 
					            ::Log3($name, 3, qq(TeslaPowerwall2AC ($name) - RequestERROR: $err));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            $hash->{actionQueue} = [];
 | 
					 | 
					 | 
					 | 
					            $hash->{actionQueue} = [];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return;
 | 
					 | 
					 | 
					 | 
					            return;
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -523,18 +533,18 @@ sub ErrorHandling {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      && $param->{code} != 200 )
 | 
					 | 
					 | 
					 | 
					      && $param->{code} != 200 )
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    {
 | 
					 | 
					 | 
					 | 
					    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsBeginUpdate($hash);
 | 
					 | 
					 | 
					 | 
					        ::readingsBeginUpdate($hash);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsBulkUpdate( $hash, 'state', $param->{code}, 1 );
 | 
					 | 
					 | 
					 | 
					        ::readingsBulkUpdate( $hash, 'state', $param->{code}, 1 );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsBulkUpdate( $hash, 'lastRequestError', $param->{code}, 1 );
 | 
					 | 
					 | 
					 | 
					        ::readingsBulkUpdate( $hash, 'lastRequestError', $param->{code}, 1 );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Log3($name, 3,
 | 
					 | 
					 | 
					 | 
					        ::Log3($name, 3,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          qq(TeslaPowerwall2AC \(${name}\) - RequestERROR: " . $param->{code}));
 | 
					 | 
					 | 
					 | 
					          qq(TeslaPowerwall2AC ($name) - RequestERROR: " . $param->{code}));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsEndUpdate( $hash, 1 );
 | 
					 | 
					 | 
					 | 
					        ::readingsEndUpdate( $hash, 1 );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Log3($name, 5,
 | 
					 | 
					 | 
					 | 
					        ::Log3($name, 5,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            qq(TeslaPowerwall2AC \(${name}\) - RequestERROR: received http code "
 | 
					 | 
					 | 
					 | 
					            qq(TeslaPowerwall2AC ($name) - RequestERROR: received http code "
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          . $param->{code}
 | 
					 | 
					 | 
					 | 
					          . $param->{code}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          . " without any data after requesting));
 | 
					 | 
					 | 
					 | 
					          . " without any data after requesting));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -544,10 +554,10 @@ sub ErrorHandling {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if ( $data =~ m#{"code":(\d+),"error":"(.+)","message":"(.+)"}$# ) {
 | 
					 | 
					 | 
					 | 
					    if ( $data =~ m#{"code":(\d+),"error":"(.+)","message":"(.+)"}$# ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsBeginUpdate($hash);
 | 
					 | 
					 | 
					 | 
					        ::readingsBeginUpdate($hash);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsBulkUpdate( $hash, 'state', $1, 1 );
 | 
					 | 
					 | 
					 | 
					        ::readingsBulkUpdate( $hash, 'state', $1, 1 );
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsBulkUpdate(
 | 
					 | 
					 | 
					 | 
					        ::readingsBulkUpdate(
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            $hash,
 | 
					 | 
					 | 
					 | 
					            $hash,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            'lastRequestError',
 | 
					 | 
					 | 
					 | 
					            'lastRequestError',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            'Path: '
 | 
					 | 
					 | 
					 | 
					            'Path: '
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -560,15 +570,15 @@ sub ErrorHandling {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            1
 | 
					 | 
					 | 
					 | 
					            1
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        );
 | 
					 | 
					 | 
					 | 
					        );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsEndUpdate( $hash, 1 );
 | 
					 | 
					 | 
					 | 
					        ::readingsEndUpdate( $hash, 1 );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    #### End Error Handling
 | 
					 | 
					 | 
					 | 
					    #### End Error Handling
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    InternalTimer( gettimeofday() + 3, 'Powerwall_Write', $hash )
 | 
					 | 
					 | 
					 | 
					    ::InternalTimer( ::gettimeofday() + 3, \&FHEM::Devices::Tesla::Powerwall::Write, $hash )
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if ( defined( $hash->{actionQueue} )
 | 
					 | 
					 | 
					 | 
					      if ( defined( $hash->{actionQueue} )
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        && scalar( @{ $hash->{actionQueue} } ) > 0 );
 | 
					 | 
					 | 
					 | 
					        && scalar( @{ $hash->{actionQueue} } ) > 0 );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Log3($name, 4, qq(TeslaPowerwall2AC \(${name}\) - Recieve JSON data: ${data}));
 | 
					 | 
					 | 
					 | 
					    ::Log3($name, 4, qq(TeslaPowerwall2AC ($name) - Recieve JSON data: $data));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    ResponseProcessing( $hash, $param->{setCmd}, $data );
 | 
					 | 
					 | 
					 | 
					    ResponseProcessing( $hash, $param->{setCmd}, $data );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -584,11 +594,11 @@ sub ResponseProcessing {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    $decode_json = eval { decode_json($json) };
 | 
					 | 
					 | 
					 | 
					    $decode_json = eval { decode_json($json) };
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if ($@) {
 | 
					 | 
					 | 
					 | 
					    if ($@) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Log3($name, 4, qq(TeslaPowerwall2AC \(${name}\) - error while request: $@));
 | 
					 | 
					 | 
					 | 
					        ::Log3($name, 4, qq(TeslaPowerwall2AC ($name) - error while request: $@));
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsBeginUpdate($hash);
 | 
					 | 
					 | 
					 | 
					        ::readingsBeginUpdate($hash);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsBulkUpdate( $hash, 'JSON Error', $@ );
 | 
					 | 
					 | 
					 | 
					        ::readingsBulkUpdate( $hash, 'JSON Error', $@ );
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsBulkUpdate( $hash, 'state',      'JSON error' );
 | 
					 | 
					 | 
					 | 
					        ::readingsBulkUpdate( $hash, 'state',      'JSON error' );
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsEndUpdate( $hash, 1 );
 | 
					 | 
					 | 
					 | 
					        ::readingsEndUpdate( $hash, 1 );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return;
 | 
					 | 
					 | 
					 | 
					        return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -631,31 +641,31 @@ sub WriteReadings {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $name        = $hash->{NAME};
 | 
					 | 
					 | 
					 | 
					    my $name        = $hash->{NAME};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Log3($name, 4, qq(TeslaPowerwall2AC \(${name}\) - Write Readings));
 | 
					 | 
					 | 
					 | 
					    ::Log3($name, 4, qq(TeslaPowerwall2AC ($name) - Write Readings));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    readingsBeginUpdate($hash);
 | 
					 | 
					 | 
					 | 
					    ::readingsBeginUpdate($hash);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    while ( my ( $r, $v ) = each %{$readings} ) {
 | 
					 | 
					 | 
					 | 
					    while ( my ( $r, $v ) = each %{$readings} ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        readingsBulkUpdate( $hash, $path . '-' . $r, $v );
 | 
					 | 
					 | 
					 | 
					        ::readingsBulkUpdate( $hash, $path . '-' . $r, $v );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    readingsBulkUpdate( $hash, 'batteryLevel',
 | 
					 | 
					 | 
					 | 
					    ::readingsBulkUpdate( $hash, 'batteryLevel',
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        sprintf( "%.1f", $readings->{percentage} ) )
 | 
					 | 
					 | 
					 | 
					        sprintf( "%.1f", $readings->{percentage} ) )
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if ( defined( $readings->{percentage} ) );
 | 
					 | 
					 | 
					 | 
					      if ( defined( $readings->{percentage} ) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    readingsBulkUpdate(
 | 
					 | 
					 | 
					 | 
					    ::readingsBulkUpdate(
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        $hash,
 | 
					 | 
					 | 
					 | 
					        $hash,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        'batteryPower',
 | 
					 | 
					 | 
					 | 
					        'batteryPower',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        sprintf(
 | 
					 | 
					 | 
					 | 
					        sprintf(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            "%.1f",
 | 
					 | 
					 | 
					 | 
					            "%.1f",
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            (
 | 
					 | 
					 | 
					 | 
					            (
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                ReadingsVal( $name, 'siteinfo-nominal_system_energy_kWh', 0 ) /
 | 
					 | 
					 | 
					 | 
					                ::ReadingsVal( $name, 'siteinfo-nominal_system_energy_kWh', 0 ) /
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                  100
 | 
					 | 
					 | 
					 | 
					                  100
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            ) * ReadingsVal( $name, 'statussoe-percentage', 0 )
 | 
					 | 
					 | 
					 | 
					            ) * ::ReadingsVal( $name, 'statussoe-percentage', 0 )
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        )
 | 
					 | 
					 | 
					 | 
					        )
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    );
 | 
					 | 
					 | 
					 | 
					    );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    readingsBulkUpdateIfChanged( $hash, 'actionQueue',
 | 
					 | 
					 | 
					 | 
					    ::readingsBulkUpdateIfChanged( $hash, 'actionQueue',
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        scalar( @{ $hash->{actionQueue} } ) . ' entries in the Queue' );
 | 
					 | 
					 | 
					 | 
					        scalar( @{ $hash->{actionQueue} } ) . ' entries in the Queue' );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    readingsBulkUpdateIfChanged(
 | 
					 | 
					 | 
					 | 
					    ::readingsBulkUpdateIfChanged(
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        $hash, 'state',
 | 
					 | 
					 | 
					 | 
					        $hash, 'state',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        (
 | 
					 | 
					 | 
					 | 
					        (
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            defined( $hash->{actionQueue} )
 | 
					 | 
					 | 
					 | 
					            defined( $hash->{actionQueue} )
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -667,7 +677,7 @@ sub WriteReadings {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        )
 | 
					 | 
					 | 
					 | 
					        )
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    );
 | 
					 | 
					 | 
					 | 
					    );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    readingsEndUpdate( $hash, 1 );
 | 
					 | 
					 | 
					 | 
					    ::readingsEndUpdate( $hash, 1 );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					sub ReadingsProcessing_Aggregates {
 | 
					 | 
					 | 
					 | 
					sub ReadingsProcessing_Aggregates {
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -891,9 +901,9 @@ sub CreateUri {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        $header     = 'Content-Type: application/json';
 | 
					 | 
					 | 
					 | 
					        $header     = 'Content-Type: application/json';
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        $data       = 
 | 
					 | 
					 | 
					 | 
					        $data       = 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              '{"username":"customer","password":"'
 | 
					 | 
					 | 
					 | 
					              '{"username":"customer","password":"'
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            . ReadPassword( $hash, $name )
 | 
					 | 
					 | 
					 | 
					            . $hash->{helper}->{passObj}->getReadPassword($name)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            . '","email":"'
 | 
					 | 
					 | 
					 | 
					            . '","email":"'
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            . AttrVal($name,'emailaddr','test@test.de')
 | 
					 | 
					 | 
					 | 
					            . ::AttrVal($name,'emailaddr','test@test.de')
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            . '","force_sm_off":false}'
 | 
					 | 
					 | 
					 | 
					            . '","force_sm_off":false}'
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    elsif ( $path eq 'powerwallsstop'
 | 
					 | 
					 | 
					 | 
					    elsif ( $path eq 'powerwallsstop'
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -905,51 +915,23 @@ sub CreateUri {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return ( $uri, $method, $header, $data, $path );
 | 
					 | 
					 | 
					 | 
					    return ( $uri, $method, $header, $data, $path );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					sub StorePassword {
 | 
					 | 
					 | 
					 | 
					### Kann nach einiger Zeit entfernt werden
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $hash     = shift;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $name     = shift;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $password = shift;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $index   = $hash->{TYPE} . q{_} . $name . q{_passwd};
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $key     = getUniqueId() . $index;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $enc_pwd = q{};
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if ( eval qq(use Digest::MD5;1) ) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        $key = Digest::MD5::md5_hex( unpack "H*", $key );
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        $key .= Digest::MD5::md5_hex($key);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    for my $char ( split //, $password ) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        my $encode = chop($key);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        $enc_pwd .= sprintf( "%.2x", ord($char) ^ ord($encode) );
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        $key = $encode . $key;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $err = setKeyValue( $index, $enc_pwd );
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return qq(error while saving the password - ${err})
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if ( defined($err) );
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return q{password successfully saved};
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					sub ReadPassword {
 | 
					 | 
					 | 
					 | 
					sub ReadPassword {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $hash = shift;
 | 
					 | 
					 | 
					 | 
					    my $hash = shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $name = shift;
 | 
					 | 
					 | 
					 | 
					    my $name = shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $index = $hash->{TYPE} . q{_} . $name . q{_passwd};
 | 
					 | 
					 | 
					 | 
					    my $index = $hash->{TYPE} . q{_} . $name . q{_passwd};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $key   = getUniqueId() . $index;
 | 
					 | 
					 | 
					 | 
					    my $key   = ::getUniqueId() . $index;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my ( $password, $err );
 | 
					 | 
					 | 
					 | 
					    my ( $password, $err );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Log3($name, 4, qq(TeslaPowerwall2AC \(${name}\) - Read password from file));
 | 
					 | 
					 | 
					 | 
					    ::Log3($name, 4, qq(TeslaPowerwall2AC ($name) - Read password from file));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    ( $err, $password ) = getKeyValue($index);
 | 
					 | 
					 | 
					 | 
					    ( $err, $password ) = ::getKeyValue($index);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if ( defined($err) ) {
 | 
					 | 
					 | 
					 | 
					    if ( defined($err) ) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Log3($name, 3,
 | 
					 | 
					 | 
					 | 
					        ::Log3($name, 3,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					qq(TeslaPowerwall2AC \(${name}\) - unable to read password from file: ${err}));
 | 
					 | 
					 | 
					 | 
					qq(TeslaPowerwall2AC ($name) - unable to read password from file: $err));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return;
 | 
					 | 
					 | 
					 | 
					        return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -975,19 +957,18 @@ qq(TeslaPowerwall2AC \(${name}\) - unable to read password from file: ${err}));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    else {
 | 
					 | 
					 | 
					 | 
					    else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        Log3($name, 3, qq(TeslaPowerwall2AC \(${name}\) - No password in file));
 | 
					 | 
					 | 
					 | 
					        ::Log3($name, 3, qq(TeslaPowerwall2AC ($name) - No password in file));
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return;
 | 
					 | 
					 | 
					 | 
					        return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return;
 | 
					 | 
					 | 
					 | 
					    return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					#### kann nach einiger Zeit gelöscht werden, entferne auch Code aus der Define Fn
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					sub DeletePassword {
 | 
					 | 
					 | 
					 | 
					sub DeletePassword {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $hash    = shift;
 | 
					 | 
					 | 
					 | 
					    my $hash    = shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    setKeyValue( $hash->{TYPE} . q{_} . $hash->{NAME} . q{_passwd}, undef );
 | 
					 | 
					 | 
					 | 
					    ::setKeyValue( $hash->{TYPE} . q(_) . $hash->{NAME} . q(_passwd), undef );
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return;
 | 
					 | 
					 | 
					 | 
					    return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
	
		
		
			
				
					
					| 
						
					 | 
					 | 
					@@ -995,40 +976,24 @@ sub DeletePassword {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					sub Rename {
 | 
					 | 
					 | 
					 | 
					sub Rename {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $new     = shift;
 | 
					 | 
					 | 
					 | 
					    my $new     = shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $old     = shift;
 | 
					 | 
					 | 
					 | 
					    my $old     = shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    my $hash    = $::defs{$new};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $hash    = $defs{$new};
 | 
					 | 
					 | 
					 | 
					    my ($passResp,$passErr);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ($passResp,$passErr) = $hash->{helper}->{passObj}->setRename($new,$old);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ::Log3($new, 1,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					qq(TeslaPowerwall2AC ($new) - error while change the password hash after rename - $passErr))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if ( !defined($passResp)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        and defined($passErr) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    StorePassword( $hash, $new, ReadPassword( $hash, $old ) );
 | 
					 | 
					 | 
					 | 
					    ::Log3($new, 1,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    setKeyValue( $hash->{TYPE} . q{_} . $old . q{_passwd}, undef );
 | 
					 | 
					 | 
					 | 
					qq(TeslaPowerwall2AC ($new) - change password hash after rename successfully))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if ( defined($passResp)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        and !defined($passErr) );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return;
 | 
					 | 
					 | 
					 | 
					    return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					# My little Helpers
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					sub PathTimestamp {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $hash = shift;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $path = shift // return;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    $hash->{helper}->{pathTimestamp}->{$path}->{TIME} =
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      gettimeofday();
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					sub PathTimeAge {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $hash = shift;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $path = shift;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    $hash->{helper}{updateTimeCallBattery} = 0
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if ( not defined( $hash->{helper}{updateTimeCallBattery} ) );
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $UpdateTimeAge = gettimeofday() - $hash->{helper}{updateTimeCallBattery};
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return $UpdateTimeAge;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					sub IsPathTimeAgeToOld {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $hash   = shift;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    my $maxAge = shift;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return ( CallBattery_UpdateTimeAge($hash) > $maxAge ? 1 : 0 );
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					1;
 | 
					 | 
					 | 
					 | 
					1;
 |