change modul header, style code PBP confirm
This commit is contained in:
		@@ -1,8 +1,8 @@
 | 
				
			|||||||
###############################################################################
 | 
					###############################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Developed with Kate
 | 
					# Developed with VSCodium and richterger perl plugin.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  (c) 2017-2021 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
 | 
					#  (c) 2017-2022 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
 | 
				
			||||||
#  All rights reserved
 | 
					#  All rights reserved
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This script is free software; you can redistribute it and/or modify
 | 
					#  This script is free software; you can redistribute it and/or modify
 | 
				
			||||||
@@ -56,22 +56,20 @@ package FHEM::TeslaPowerwall2AC;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use strict;
 | 
					use strict;
 | 
				
			||||||
use warnings;
 | 
					use warnings;
 | 
				
			||||||
use FHEM::Meta;
 | 
					 | 
				
			||||||
use GPUtils qw(GP_Export);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use FHEM::Meta;
 | 
				
			||||||
require FHEM::Devices::Tesla::Powerwall;
 | 
					require FHEM::Devices::Tesla::Powerwall;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use GPUtils qw(GP_Import);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#-- Run before package compilation
 | 
					#-- Run before package compilation
 | 
				
			||||||
BEGIN {
 | 
					BEGIN {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    #-- Export to main context with different name
 | 
					    #-- Export to main context with different name
 | 
				
			||||||
    GP_Export(
 | 
					    GP_Import(qw( readingFnAttributes ));
 | 
				
			||||||
        qw(
 | 
					 | 
				
			||||||
            Initialize
 | 
					 | 
				
			||||||
          )
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sub ::TeslaPowerwall2AC_Initialize { goto &Initialize }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sub Initialize {
 | 
					sub Initialize {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    my $hash = shift;
 | 
					    my $hash = shift;
 | 
				
			||||||
@@ -89,7 +87,7 @@ sub Initialize {
 | 
				
			|||||||
      . 'disable:1 '
 | 
					      . 'disable:1 '
 | 
				
			||||||
      . 'devel:1 '
 | 
					      . 'devel:1 '
 | 
				
			||||||
      . 'emailaddr '
 | 
					      . 'emailaddr '
 | 
				
			||||||
                    . $::readingFnAttributes;
 | 
					      . $readingFnAttributes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $hash->{parseParams} = 1;
 | 
					    $hash->{parseParams} = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -98,7 +96,6 @@ sub Initialize {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
1;
 | 
					1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
=pod
 | 
					=pod
 | 
				
			||||||
 | 
					
 | 
				
			||||||
=item device
 | 
					=item device
 | 
				
			||||||
@@ -199,9 +196,9 @@ sub Initialize {
 | 
				
			|||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "release_status": "stable",
 | 
					  "release_status": "stable",
 | 
				
			||||||
  "license": "GPL_2",
 | 
					  "license": "GPL_2",
 | 
				
			||||||
  "version": "v2.0.0",
 | 
					  "version": "v2.0.1",
 | 
				
			||||||
  "author": [
 | 
					  "author": [
 | 
				
			||||||
    "Marko Oldenburg <leongaultier@gmail.com>"
 | 
					    "Marko Oldenburg <fhemdevelopment@cooltux.net>"
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "x_fhem_maintainer": [
 | 
					  "x_fhem_maintainer": [
 | 
				
			||||||
    "CoolTux"
 | 
					    "CoolTux"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,2 +1,2 @@
 | 
				
			|||||||
UPD 2021-04-23_08:24:15 6944 FHEM/46_TeslaPowerwall2AC.pm
 | 
					UPD 2022-01-07_07:25:06 6874 FHEM/46_TeslaPowerwall2AC.pm
 | 
				
			||||||
UPD 2021-07-05_13:05:54 29269 lib/FHEM/Devices/Tesla/Powerwall.pm
 | 
					UPD 2022-01-07_08:33:19 27498 lib/FHEM/Devices/Tesla/Powerwall.pm
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
###############################################################################
 | 
					###############################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Developed with Kate
 | 
					# Developed with VSCodium and richterger perl plugin
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  (c) 2017-2021 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
 | 
					#  (c) 2016-2021 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
 | 
				
			||||||
#  All rights reserved
 | 
					#  All rights reserved
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  This script is free software; you can redistribute it and/or modify
 | 
					#  This script is free software; you can redistribute it and/or modify
 | 
				
			||||||
@@ -56,10 +56,19 @@ package FHEM::Devices::Tesla::Powerwall;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use strict;
 | 
					use strict;
 | 
				
			||||||
use warnings;
 | 
					use warnings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use HttpUtils;
 | 
					use HttpUtils;
 | 
				
			||||||
 | 
					use GPUtils qw(GP_Import);
 | 
				
			||||||
use FHEM::Core::Authentication::Passwords qw(:ALL);
 | 
					use FHEM::Core::Authentication::Passwords qw(:ALL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Data::Dumper;
 | 
					BEGIN {
 | 
				
			||||||
 | 
					    # Import from main context
 | 
				
			||||||
 | 
					    GP_Import(
 | 
				
			||||||
 | 
					        qw( init_done
 | 
				
			||||||
 | 
					          defs
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# try to use JSON::MaybeXS wrapper
 | 
					# try to use JSON::MaybeXS wrapper
 | 
				
			||||||
#   for chance of better performance + open code
 | 
					#   for chance of better performance + open code
 | 
				
			||||||
@@ -67,15 +76,11 @@ eval {
 | 
				
			|||||||
    require JSON::MaybeXS;
 | 
					    require JSON::MaybeXS;
 | 
				
			||||||
    import JSON::MaybeXS qw( decode_json encode_json );
 | 
					    import JSON::MaybeXS qw( decode_json encode_json );
 | 
				
			||||||
    1;
 | 
					    1;
 | 
				
			||||||
};
 | 
					} or do {
 | 
				
			||||||
 | 
					 | 
				
			||||||
if ($@) {
 | 
					 | 
				
			||||||
    $@ = undef;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # try to use JSON wrapper
 | 
					    # try to use JSON wrapper
 | 
				
			||||||
    #   for chance of better performance
 | 
					    #   for chance of better performance
 | 
				
			||||||
    eval {
 | 
					    eval {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        # JSON preference order
 | 
					        # JSON preference order
 | 
				
			||||||
        local $ENV{PERL_JSON_BACKEND} =
 | 
					        local $ENV{PERL_JSON_BACKEND} =
 | 
				
			||||||
          'Cpanel::JSON::XS,JSON::XS,JSON::PP,JSON::backportPP'
 | 
					          'Cpanel::JSON::XS,JSON::XS,JSON::PP,JSON::backportPP'
 | 
				
			||||||
@@ -84,10 +89,7 @@ if ($@) {
 | 
				
			|||||||
        require JSON;
 | 
					        require JSON;
 | 
				
			||||||
        import JSON qw( decode_json encode_json );
 | 
					        import JSON qw( decode_json encode_json );
 | 
				
			||||||
        1;
 | 
					        1;
 | 
				
			||||||
    };
 | 
					    } or do {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ($@) {
 | 
					 | 
				
			||||||
        $@ = undef;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # In rare cases, Cpanel::JSON::XS may
 | 
					        # In rare cases, Cpanel::JSON::XS may
 | 
				
			||||||
        #   be installed but JSON|JSON::MaybeXS not ...
 | 
					        #   be installed but JSON|JSON::MaybeXS not ...
 | 
				
			||||||
@@ -95,10 +97,7 @@ if ($@) {
 | 
				
			|||||||
            require Cpanel::JSON::XS;
 | 
					            require Cpanel::JSON::XS;
 | 
				
			||||||
            import Cpanel::JSON::XS qw(decode_json encode_json);
 | 
					            import Cpanel::JSON::XS qw(decode_json encode_json);
 | 
				
			||||||
            1;
 | 
					            1;
 | 
				
			||||||
        };
 | 
					        } or do {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ($@) {
 | 
					 | 
				
			||||||
            $@ = undef;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # In rare cases, JSON::XS may
 | 
					            # In rare cases, JSON::XS may
 | 
				
			||||||
            #   be installed but JSON not ...
 | 
					            #   be installed but JSON not ...
 | 
				
			||||||
@@ -106,10 +105,7 @@ if ($@) {
 | 
				
			|||||||
                require JSON::XS;
 | 
					                require JSON::XS;
 | 
				
			||||||
                import JSON::XS qw(decode_json encode_json);
 | 
					                import JSON::XS qw(decode_json encode_json);
 | 
				
			||||||
                1;
 | 
					                1;
 | 
				
			||||||
            };
 | 
					            } or do {
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if ($@) {
 | 
					 | 
				
			||||||
                $@ = undef;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # Fallback to built-in JSON which SHOULD
 | 
					                # Fallback to built-in JSON which SHOULD
 | 
				
			||||||
                #   be available since 5.014 ...
 | 
					                #   be available since 5.014 ...
 | 
				
			||||||
@@ -117,21 +113,17 @@ if ($@) {
 | 
				
			|||||||
                    require JSON::PP;
 | 
					                    require JSON::PP;
 | 
				
			||||||
                    import JSON::PP qw(decode_json encode_json);
 | 
					                    import JSON::PP qw(decode_json encode_json);
 | 
				
			||||||
                    1;
 | 
					                    1;
 | 
				
			||||||
                };
 | 
					                } or do {
 | 
				
			||||||
 | 
					 | 
				
			||||||
                if ($@) {
 | 
					 | 
				
			||||||
                    $@ = undef;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    # Fallback to JSON::backportPP in really rare cases
 | 
					                    # Fallback to JSON::backportPP in really rare cases
 | 
				
			||||||
                    require JSON::backportPP;
 | 
					                    require JSON::backportPP;
 | 
				
			||||||
                    import JSON::backportPP qw(decode_json encode_json);
 | 
					                    import JSON::backportPP qw(decode_json encode_json);
 | 
				
			||||||
                    1;
 | 
					                    1;
 | 
				
			||||||
                }
 | 
					                };
 | 
				
			||||||
            }
 | 
					            };
 | 
				
			||||||
        }
 | 
					        };
 | 
				
			||||||
    }
 | 
					    };
 | 
				
			||||||
}
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
my %paths = (
 | 
					my %paths = (
 | 
				
			||||||
    'statussoe'    => 'system_status/soe',
 | 
					    'statussoe'    => 'system_status/soe',
 | 
				
			||||||
@@ -155,9 +147,12 @@ my %cmdPaths = (
 | 
				
			|||||||
sub Define {
 | 
					sub Define {
 | 
				
			||||||
    my $hash = shift;
 | 
					    my $hash = shift;
 | 
				
			||||||
    my $aArg = shift;
 | 
					    my $aArg = shift;
 | 
				
			||||||
 | 
					    my $version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return $@ unless ( FHEM::Meta::SetInternals($hash) );
 | 
					    return $@ unless ( FHEM::Meta::SetInternals($hash) );
 | 
				
			||||||
    use version 0.60; our $VERSION = FHEM::Meta::Get( $hash, 'version' );
 | 
					
 | 
				
			||||||
 | 
					    $version = FHEM::Meta::Get( $hash, 'version' );
 | 
				
			||||||
 | 
					    our $VERSION = $version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return q{too few parameters: define <name> TeslaPowerwall2AC <HOST>}
 | 
					    return q{too few parameters: define <name> TeslaPowerwall2AC <HOST>}
 | 
				
			||||||
      if ( scalar( @{$aArg} ) != 3 );
 | 
					      if ( scalar( @{$aArg} ) != 3 );
 | 
				
			||||||
@@ -173,30 +168,13 @@ sub Define {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    ::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}));
 | 
					"TeslaPowerwall2AC ($name) - defined TeslaPowerwall2AC Device with Host $host and Interval $hash->{INTERVAL}"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ### create password object to handle pass keystore
 | 
					    ### create password object to handle pass keystore
 | 
				
			||||||
    $hash->{helper}->{passObj}  = FHEM::Core::Authentication::Passwords->new($hash->{TYPE});
 | 
					    $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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -206,24 +184,24 @@ sub Undef {
 | 
				
			|||||||
    my $name = shift;
 | 
					    my $name = shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ::RemoveInternalTimer($hash);
 | 
					    ::RemoveInternalTimer($hash);
 | 
				
			||||||
    ::Log3($name, 3, qq(TeslaPowerwall2AC ($name) - Device $name deleted));
 | 
					    ::Log3( $name, 3, "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, "TeslaPowerwall2AC ($name) - disabled" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        elsif ( $cmd eq 'del' ) {
 | 
					        elsif ( $cmd eq 'del' ) {
 | 
				
			||||||
            ::Log3($name, 3, qq(TeslaPowerwall2AC ($name) - enabled));
 | 
					            ::Log3( $name, 3, "TeslaPowerwall2AC ($name) - enabled" );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -231,13 +209,14 @@ sub Attr {
 | 
				
			|||||||
        if ( $cmd eq 'set' ) {
 | 
					        if ( $cmd eq 'set' ) {
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
'check disabledForIntervals Syntax HH:MM-HH:MM or \'HH:MM-HH:MM HH:MM-HH:MM ...\''
 | 
					'check disabledForIntervals Syntax HH:MM-HH:MM or \'HH:MM-HH:MM HH:MM-HH:MM ...\''
 | 
				
			||||||
              unless ( $attrVal =~ /^((\d{2}:\d{2})-(\d{2}:\d{2})\s?)+$/ );
 | 
					              unless ( $attrVal =~ /^((\d{2}:\d{2})-(\d{2}:\d{2})\s?)+$/x );
 | 
				
			||||||
            ::Log3($name, 3, qq(TeslaPowerwall2AC ($name) - disabledForIntervals));
 | 
					            ::Log3( $name, 3,
 | 
				
			||||||
 | 
					                "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, "TeslaPowerwall2AC ($name) - enabled" );
 | 
				
			||||||
            ::readingsSingleUpdate( $hash, 'state', 'active', 1 );
 | 
					            ::readingsSingleUpdate( $hash, 'state', 'active', 1 );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -245,8 +224,9 @@ sub Attr {
 | 
				
			|||||||
    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)));
 | 
					"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)};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -254,16 +234,16 @@ 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));
 | 
					                    "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));
 | 
					                "TeslaPowerwall2AC ($name) - set interval to default" );
 | 
				
			||||||
            Timer_GetData($hash);
 | 
					            Timer_GetData($hash);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -285,12 +265,14 @@ sub Notify {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Timer_GetData($hash)
 | 
					    Timer_GetData($hash)
 | 
				
			||||||
      if (
 | 
					      if (
 | 
				
			||||||
           ( grep /^INITIALIZED$/, @{$events}
 | 
					        (
 | 
				
			||||||
          or grep /^ATTR.$name.emailaddr$/, @{$events}
 | 
					               grep { /^INITIALIZED$/x } @{$events}
 | 
				
			||||||
          or grep /^DELETEATTR.$name.disable$/, @{$events}
 | 
					            or grep { /^ATTR.$name.emailaddr$/x } @{$events}
 | 
				
			||||||
          or grep /^DELETEATTR.$name.interval$/, @{$events}
 | 
					            or grep { /^DELETEATTR.$name.disable$/x } @{$events}
 | 
				
			||||||
          or grep /^DEFINED.$name$/, @{$events} )
 | 
					            or grep { /^DELETEATTR.$name.interval$/x } @{$events}
 | 
				
			||||||
        and $::init_done
 | 
					            or grep { /^DEFINED.$name$/x } @{$events}
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        && $init_done
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -343,10 +325,10 @@ 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'
 | 
				
			||||||
    && exists($hash->{helper}->{passObj})
 | 
					            && exists( $hash->{helper}->{passObj} )
 | 
				
			||||||
    && defined($hash->{helper}->{passObj}->getReadPassword($name))
 | 
					            && 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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -361,7 +343,7 @@ sub Get {
 | 
				
			|||||||
    return;
 | 
					    return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sub Set {
 | 
					sub Set {    ## no critic (Subroutine with high complexity score)
 | 
				
			||||||
    my $hash = shift;
 | 
					    my $hash = shift;
 | 
				
			||||||
    my $aArg = shift;
 | 
					    my $aArg = shift;
 | 
				
			||||||
    my $hArg = shift;
 | 
					    my $hArg = shift;
 | 
				
			||||||
@@ -370,52 +352,58 @@ sub Set {
 | 
				
			|||||||
    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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ( $cmd eq 'powerwalls' ) {
 | 
					    if ( $cmd eq 'powerwalls' ) {
 | 
				
			||||||
        $arg = lc( $cmd . $aArg->[0] );
 | 
					        $arg = lc( $cmd . $aArg->[0] );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    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
 | 
					
 | 
				
			||||||
                                                   || scalar(keys %{$hArg}) != 1 );
 | 
					        return qq(usage: $cmd pass=<password>)
 | 
				
			||||||
        my ($passResp,$passErr);
 | 
					          if ( scalar( @{$aArg} ) != 0
 | 
				
			||||||
        ($passResp,$passErr) = $hash->{helper}->{passObj}->setStorePassword($name,$hArg->{'pass'});
 | 
					            || scalar( keys %{$hArg} ) != 1 );
 | 
				
			||||||
 | 
					        my ( $passResp, $passErr );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ( $passResp, $passErr ) = $hash->{helper}->{passObj}
 | 
				
			||||||
 | 
					          ->setStorePassword( $name, $hArg->{'pass'} );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return qq{error while saving the password - $passErr}
 | 
					        return qq{error while saving the password - $passErr}
 | 
				
			||||||
          if ( !defined($passResp)
 | 
					          if (!defined($passResp)
 | 
				
			||||||
           and defined($passErr) );
 | 
					            && defined($passErr) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return Timer_GetData($hash)
 | 
					        return Timer_GetData($hash)
 | 
				
			||||||
          if ( defined($passResp)
 | 
					          if ( defined($passResp)
 | 
				
			||||||
           and !defined($passErr) );
 | 
					            && !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 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        my ($passResp,$passErr);
 | 
					        my ( $passResp, $passErr );
 | 
				
			||||||
        ($passResp,$passErr) = $hash->{helper}->{passObj}->setDeletePassword($name);
 | 
					        ( $passResp, $passErr ) =
 | 
				
			||||||
 | 
					          $hash->{helper}->{passObj}->setDeletePassword($name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return qq{error while saving the password - $passErr}
 | 
					        return qq{error while saving the password - $passErr}
 | 
				
			||||||
          if ( !defined($passResp)
 | 
					          if (!defined($passResp)
 | 
				
			||||||
           and defined($passErr) );
 | 
					            && defined($passErr) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return q{password successfully removed}
 | 
					        return q{password successfully removed}
 | 
				
			||||||
          if ( defined($passResp)
 | 
					          if ( defined($passResp)
 | 
				
			||||||
           and !defined($passErr) );
 | 
					            && !defined($passErr) );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        my $list = ( exists($hash->{helper}->{passObj})
 | 
					        my $list = (
 | 
				
			||||||
            && defined($hash->{helper}->{passObj}->getReadPassword($name))
 | 
					            exists( $hash->{helper}->{passObj} )
 | 
				
			||||||
 | 
					              && defined( $hash->{helper}->{passObj}->getReadPassword($name) )
 | 
				
			||||||
            ? 'removePassword:noArg '
 | 
					            ? 'removePassword:noArg '
 | 
				
			||||||
          : 'setPassword ');
 | 
					            : 'setPassword '
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $list .= 'powerwalls:run,stop'
 | 
					        $list .= 'powerwalls:run,stop'
 | 
				
			||||||
          if ( ::AttrVal( $name, 'devel', 0 ) == 1
 | 
					          if ( ::AttrVal( $name, 'devel', 0 ) == 1
 | 
				
			||||||
            && exists($hash->{helper}->{passObj})
 | 
					            && exists( $hash->{helper}->{passObj} )
 | 
				
			||||||
            && defined($hash->{helper}->{passObj}->getReadPassword($name))
 | 
					            && 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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -441,13 +429,17 @@ sub Timer_GetData {
 | 
				
			|||||||
              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 (   !exists($hash->{helper}->{passObj})
 | 
					              if (
 | 
				
			||||||
                  || ( exists($hash->{helper}->{passObj})
 | 
					                !exists( $hash->{helper}->{passObj} )
 | 
				
			||||||
                    && !defined($hash->{helper}->{passObj}->getReadPassword($name))
 | 
					                || (
 | 
				
			||||||
 | 
					                    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' );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else {
 | 
					            else {
 | 
				
			||||||
@@ -465,8 +457,11 @@ sub Timer_GetData {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    ::InternalTimer( ::gettimeofday() + $hash->{INTERVAL},
 | 
					    ::InternalTimer( ::gettimeofday() + $hash->{INTERVAL},
 | 
				
			||||||
        \&FHEM::Devices::Tesla::Powerwall::Timer_GetData, $hash );
 | 
					        \&FHEM::Devices::Tesla::Powerwall::Timer_GetData, $hash );
 | 
				
			||||||
    ::Log3($name, 4,
 | 
					
 | 
				
			||||||
      qq(TeslaPowerwall2AC ($name) - Call ::InternalTimer Timer_GetData));
 | 
					    ::Log3( $name, 4,
 | 
				
			||||||
 | 
					        "TeslaPowerwall2AC ($name) - Call ::InternalTimer Timer_GetData" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sub Write {
 | 
					sub Write {
 | 
				
			||||||
@@ -494,13 +489,15 @@ 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 },
 | 
					            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));
 | 
					    return ::Log3( $name, 4,
 | 
				
			||||||
 | 
					        "TeslaPowerwall2AC ($name) - Send with URI: https://$uri" );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sub ErrorHandling {
 | 
					sub ErrorHandling {
 | 
				
			||||||
@@ -521,7 +518,8 @@ sub ErrorHandling {
 | 
				
			|||||||
            ::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,
 | 
				
			||||||
 | 
					                "TeslaPowerwall2AC ($name) - RequestERROR: $err" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $hash->{actionQueue} = [];
 | 
					            $hash->{actionQueue} = [];
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
@@ -529,7 +527,7 @@ sub ErrorHandling {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (   $data eq ''
 | 
					    if (   $data eq ''
 | 
				
			||||||
      && exists($param->{code})
 | 
					        && exists( $param->{code} )
 | 
				
			||||||
        && $param->{code} != 200 )
 | 
					        && $param->{code} != 200 )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -538,21 +536,20 @@ sub ErrorHandling {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        ::readingsBulkUpdate( $hash, 'lastRequestError', $param->{code}, 1 );
 | 
					        ::readingsBulkUpdate( $hash, 'lastRequestError', $param->{code}, 1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ::Log3($name, 3,
 | 
					        ::Log3( $name, 3,
 | 
				
			||||||
          qq(TeslaPowerwall2AC ($name) - RequestERROR: " . $param->{code}));
 | 
					            "TeslaPowerwall2AC ($name) - RequestERROR: $param->{code}" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ::readingsEndUpdate( $hash, 1 );
 | 
					        ::readingsEndUpdate( $hash, 1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ::Log3($name, 5,
 | 
					        ::Log3( $name, 5,
 | 
				
			||||||
            qq(TeslaPowerwall2AC ($name) - RequestERROR: received http code "
 | 
					"TeslaPowerwall2AC ($name) - RequestERROR: received http code $param->{code} without any data after requesting"
 | 
				
			||||||
          . $param->{code}
 | 
					        );
 | 
				
			||||||
          . " without any data after requesting));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $hash->{actionQueue} = [];
 | 
					        $hash->{actionQueue} = [];
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( $data =~ m#{"code":(\d+),"error":"(.+)","message":"(.+)"}$# ) {
 | 
					    if ( $data =~ m#{"code":(\d+),"error":"(.+)","message":"(.+)"}$#xms ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ::readingsBeginUpdate($hash);
 | 
					        ::readingsBeginUpdate($hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -572,15 +569,16 @@ sub ErrorHandling {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        ::readingsEndUpdate( $hash, 1 );
 | 
					        ::readingsEndUpdate( $hash, 1 );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    #### End Error Handling
 | 
					    ### End Error Handling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ::InternalTimer( ::gettimeofday() + 3, \&FHEM::Devices::Tesla::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, "TeslaPowerwall2AC ($name) - Recieve JSON data: $data" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ResponseProcessing( $hash, $param->{setCmd}, $data );
 | 
					    return ResponseProcessing( $hash, $param->{setCmd}, $data );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sub ResponseProcessing {
 | 
					sub ResponseProcessing {
 | 
				
			||||||
@@ -594,7 +592,8 @@ 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,
 | 
				
			||||||
 | 
					            "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' );
 | 
				
			||||||
@@ -604,9 +603,9 @@ sub ResponseProcessing {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return
 | 
					    return
 | 
				
			||||||
      if ( ref($decode_json) eq 'HASH'
 | 
					      if ( ref($decode_json) eq 'HASH'
 | 
				
			||||||
        && defined($decode_json->{error})
 | 
					        && defined( $decode_json->{error} )
 | 
				
			||||||
        && $decode_json->{error}
 | 
					        && $decode_json->{error}
 | 
				
			||||||
        && defined($decode_json->{code})
 | 
					        && defined( $decode_json->{code} )
 | 
				
			||||||
        && $decode_json->{code} );
 | 
					        && $decode_json->{code} );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #### Verarbeitung der Readings zum passenden Path
 | 
					    #### Verarbeitung der Readings zum passenden Path
 | 
				
			||||||
@@ -631,7 +630,7 @@ sub ResponseProcessing {
 | 
				
			|||||||
        $readings = $decode_json;
 | 
					        $readings = $decode_json;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    WriteReadings( $hash, $path, $readings );
 | 
					    return WriteReadings( $hash, $path, $readings );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sub WriteReadings {
 | 
					sub WriteReadings {
 | 
				
			||||||
@@ -641,7 +640,7 @@ sub WriteReadings {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    my $name = $hash->{NAME};
 | 
					    my $name = $hash->{NAME};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ::Log3($name, 4, qq(TeslaPowerwall2AC ($name) - Write Readings));
 | 
					    ::Log3( $name, 4, "TeslaPowerwall2AC ($name) - Write Readings" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ::readingsBeginUpdate($hash);
 | 
					    ::readingsBeginUpdate($hash);
 | 
				
			||||||
    while ( my ( $r, $v ) = each %{$readings} ) {
 | 
					    while ( my ( $r, $v ) = each %{$readings} ) {
 | 
				
			||||||
@@ -657,8 +656,8 @@ sub WriteReadings {
 | 
				
			|||||||
        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 )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
@@ -678,6 +677,8 @@ sub WriteReadings {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ::readingsEndUpdate( $hash, 1 );
 | 
					    ::readingsEndUpdate( $hash, 1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sub ReadingsProcessing_Aggregates {
 | 
					sub ReadingsProcessing_Aggregates {
 | 
				
			||||||
@@ -709,42 +710,45 @@ sub ReadingsProcessing_Powerwalls {
 | 
				
			|||||||
    my %readings;
 | 
					    my %readings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( ref($decode_json) eq 'HASH' ) {
 | 
					    if ( ref($decode_json) eq 'HASH' ) {
 | 
				
			||||||
        for (keys %{$decode_json}) {
 | 
					        for ( keys %{$decode_json} ) {
 | 
				
			||||||
            $readings{$_} = $decode_json->{$_}
 | 
					            $readings{$_} = $decode_json->{$_}
 | 
				
			||||||
            if ( ref($decode_json->{$_}) ne 'ARRAY'
 | 
					              if ( ref( $decode_json->{$_} ) ne 'ARRAY'
 | 
				
			||||||
              && defined($decode_json->{$_}) );
 | 
					                && defined( $decode_json->{$_} ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ( ref($decode_json->{$_}) eq 'ARRAY' ) {
 | 
					            if ( ref( $decode_json->{$_} ) eq 'ARRAY' ) {
 | 
				
			||||||
                my $i  = 0;
 | 
					                my $i  = 0;
 | 
				
			||||||
                my $r1 = $_;
 | 
					                my $r1 = $_;
 | 
				
			||||||
                for my $hRef (@{$decode_json->{$_}}) {
 | 
					                my $hRef;
 | 
				
			||||||
                    for (keys %{$hRef}) {
 | 
					                for my $hRef ( @{ $decode_json->{$_} } ) {
 | 
				
			||||||
                        $r1 =~ s/s$//g;
 | 
					                    for ( keys %{$hRef} ) {
 | 
				
			||||||
 | 
					                        $r1 =~ s/s$//xg;
 | 
				
			||||||
                        $readings{qq(${r1}_${i}_${_})} = $hRef->{$_}
 | 
					                        $readings{qq(${r1}_${i}_${_})} = $hRef->{$_}
 | 
				
			||||||
                        if ( ref($hRef->{$_}) ne 'ARRAY'
 | 
					                          if ( ref( $hRef->{$_} ) ne 'ARRAY'
 | 
				
			||||||
                          && ref($hRef->{$_}) ne 'HASH'
 | 
					                            && ref( $hRef->{$_} ) ne 'HASH'
 | 
				
			||||||
                          && defined($hRef->{$_}) );
 | 
					                            && defined( $hRef->{$_} ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        if ( ref($hRef->{$_}) eq 'HASH' ) {
 | 
					                        if ( ref( $hRef->{$_} ) eq 'HASH' ) {
 | 
				
			||||||
                            my $r2 = $_;
 | 
					                            my $r2 = $_;
 | 
				
			||||||
                            my $r3 = $hRef->{$_};
 | 
					                            my $r3 = $hRef->{$_};
 | 
				
			||||||
                            for (keys %{$r3}) {
 | 
					                            for ( keys %{$r3} ) {
 | 
				
			||||||
                                $readings{qq(${r1}_${i}_${r2}_${_})} = $r3->{$_}
 | 
					                                $readings{qq(${r1}_${i}_${r2}_${_})} = $r3->{$_}
 | 
				
			||||||
                                if ( ref($r3->{$_}) ne 'ARRAY'
 | 
					                                  if ( ref( $r3->{$_} ) ne 'ARRAY'
 | 
				
			||||||
                                  && defined($r3->{$_}) );
 | 
					                                    && defined( $r3->{$_} ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                if ( ref($r3->{$_}) eq 'ARRAY' ) {
 | 
					                                if ( ref( $r3->{$_} ) eq 'ARRAY' ) {
 | 
				
			||||||
                                    my $ii = 0;
 | 
					                                    my $ii = 0;
 | 
				
			||||||
                                    my $r4 = $_;
 | 
					                                    my $r4 = $_;
 | 
				
			||||||
                                    for $hRef (@{$r3->{$_}}) {
 | 
					                                    for $hRef ( @{ $r3->{$_} } ) {
 | 
				
			||||||
                                        for (keys %{$hRef}) {
 | 
					                                        for ( keys %{$hRef} ) {
 | 
				
			||||||
                                            $r4 =~ s/s$//g;
 | 
					                                            $r4 =~ s/s$//xg;
 | 
				
			||||||
                                            $readings{qq(${r1}_${i}_${r2}_${r4}_${ii}_${_})} = $hRef->{$_}
 | 
					                                            $readings{
 | 
				
			||||||
                                            if ( ref($hRef->{$_}) ne 'HASH'
 | 
					qq(${r1}_${i}_${r2}_${r4}_${ii}_${_})
 | 
				
			||||||
                                              && defined($hRef->{$_}) );
 | 
					                                            } = $hRef->{$_}
 | 
				
			||||||
 | 
					                                              if ( ref( $hRef->{$_} ) ne 'HASH'
 | 
				
			||||||
 | 
					                                                && defined( $hRef->{$_} ) );
 | 
				
			||||||
                                        }
 | 
					                                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                        $ii++
 | 
					                                        $ii++;
 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
@@ -890,12 +894,19 @@ sub CreateUri {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    my $name   = $hash->{NAME};
 | 
					    my $name   = $hash->{NAME};
 | 
				
			||||||
    my $host   = $hash->{HOST};
 | 
					    my $host   = $hash->{HOST};
 | 
				
			||||||
    my $header      = ( defined($hash->{TOKEN}) ? 'Cookie: AuthCookie=' . $hash->{TOKEN} : undef );
 | 
					    my $header = (
 | 
				
			||||||
 | 
					        defined( $hash->{TOKEN} )
 | 
				
			||||||
 | 
					        ? 'Cookie: AuthCookie=' . $hash->{TOKEN}
 | 
				
			||||||
 | 
					        : undef
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
    my $method = 'GET';
 | 
					    my $method = 'GET';
 | 
				
			||||||
    my $uri         = ( $path ne 'login' ? $host . '/api/' . $paths{$path} : $host . '/api/login/Basic' );
 | 
					    my $uri    = (
 | 
				
			||||||
 | 
					          $path ne 'login'
 | 
				
			||||||
 | 
					        ? $host . '/api/' . $paths{$path}
 | 
				
			||||||
 | 
					        : $host . '/api/login/Basic'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
    my $data;
 | 
					    my $data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ( $path eq 'login' ) {
 | 
					    if ( $path eq 'login' ) {
 | 
				
			||||||
        $method = 'POST';
 | 
					        $method = 'POST';
 | 
				
			||||||
        $header = 'Content-Type: application/json';
 | 
					        $header = 'Content-Type: application/json';
 | 
				
			||||||
@@ -903,10 +914,10 @@ sub CreateUri {
 | 
				
			|||||||
            '{"username":"customer","password":"'
 | 
					            '{"username":"customer","password":"'
 | 
				
			||||||
          . $hash->{helper}->{passObj}->getReadPassword($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'
 | 
				
			||||||
        || $path eq 'powerwallsruns' )
 | 
					        || $path eq 'powerwallsruns' )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $uri = $host . '/api/' . $cmdPaths{$path};
 | 
					        $uri = $host . '/api/' . $cmdPaths{$path};
 | 
				
			||||||
@@ -915,85 +926,29 @@ sub CreateUri {
 | 
				
			|||||||
    return ( $uri, $method, $header, $data, $path );
 | 
					    return ( $uri, $method, $header, $data, $path );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Kann nach einiger Zeit entfernt werden
 | 
					 | 
				
			||||||
sub ReadPassword {
 | 
					 | 
				
			||||||
    my $hash = shift;
 | 
					 | 
				
			||||||
    my $name = shift;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    my $index = $hash->{TYPE} . q{_} . $name . q{_passwd};
 | 
					 | 
				
			||||||
    my $key   = ::getUniqueId() . $index;
 | 
					 | 
				
			||||||
    my ( $password, $err );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ::Log3($name, 4, qq(TeslaPowerwall2AC ($name) - Read password from file));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ( $err, $password ) = ::getKeyValue($index);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ( defined($err) ) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ::Log3($name, 3,
 | 
					 | 
				
			||||||
qq(TeslaPowerwall2AC ($name) - unable to read password from file: $err));
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ( defined($password) ) {
 | 
					 | 
				
			||||||
        if ( eval qq(use Digest::MD5;1) ) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $key = Digest::MD5::md5_hex( unpack "H*", $key );
 | 
					 | 
				
			||||||
            $key .= Digest::MD5::md5_hex($key);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        my $dec_pwd = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for my $char ( map { pack( 'C', hex($_) ) } ( $password =~ /(..)/g ) ) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            my $decode = chop($key);
 | 
					 | 
				
			||||||
            $dec_pwd .= chr( ord($char) ^ ord($decode) );
 | 
					 | 
				
			||||||
            $key = $decode . $key;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $dec_pwd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ::Log3($name, 3, qq(TeslaPowerwall2AC ($name) - No password in file));
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### kann nach einiger Zeit gelöscht werden, entferne auch Code aus der Define Fn
 | 
					 | 
				
			||||||
sub DeletePassword {
 | 
					 | 
				
			||||||
    my $hash    = shift;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ::setKeyValue( $hash->{TYPE} . q(_) . $hash->{NAME} . q(_passwd), undef );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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);
 | 
					    my ( $passResp, $passErr );
 | 
				
			||||||
    ($passResp,$passErr) = $hash->{helper}->{passObj}->setRename($new,$old);
 | 
					    ( $passResp, $passErr ) =
 | 
				
			||||||
 | 
					      $hash->{helper}->{passObj}->setRename( $new, $old );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ::Log3($new, 1,
 | 
					    ::Log3( $new, 1,
 | 
				
			||||||
qq(TeslaPowerwall2AC ($new) - error while change the password hash after rename - $passErr))
 | 
					"TeslaPowerwall2AC ($new) - error while change the password hash after rename - $passErr"
 | 
				
			||||||
        if ( !defined($passResp)
 | 
					      )
 | 
				
			||||||
        and defined($passErr) );
 | 
					      if (!defined($passResp)
 | 
				
			||||||
 | 
					        && defined($passErr) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ::Log3($new, 1,
 | 
					    ::Log3( $new, 1,
 | 
				
			||||||
qq(TeslaPowerwall2AC ($new) - change password hash after rename successfully))
 | 
					"TeslaPowerwall2AC ($new) - change password hash after rename successfully"
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
      if ( defined($passResp)
 | 
					      if ( defined($passResp)
 | 
				
			||||||
        and !defined($passErr) );
 | 
					        && !defined($passErr) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
1;
 | 
					1;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user