add email and password fn
This commit is contained in:
parent
1b3fb852b6
commit
0d36ac8957
@ -144,6 +144,9 @@ BEGIN {
|
|||||||
readingsBulkUpdateIfChanged
|
readingsBulkUpdateIfChanged
|
||||||
readingsBeginUpdate
|
readingsBeginUpdate
|
||||||
readingsEndUpdate
|
readingsEndUpdate
|
||||||
|
setKeyValue
|
||||||
|
getKeyValue
|
||||||
|
getUniqueId
|
||||||
CommandAttr
|
CommandAttr
|
||||||
defs
|
defs
|
||||||
Log3
|
Log3
|
||||||
@ -193,34 +196,38 @@ sub Initialize {
|
|||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
|
|
||||||
# Consumer
|
# Consumer
|
||||||
$hash->{GetFn} = 'FHEM::TeslaPowerwall2AC::Get';
|
$hash->{GetFn} = \&Get;
|
||||||
$hash->{SetFn} = 'FHEM::TeslaPowerwall2AC::Set';
|
$hash->{SetFn} = \&Set;
|
||||||
$hash->{DefFn} = 'FHEM::TeslaPowerwall2AC::Define';
|
$hash->{DefFn} = \&Define;
|
||||||
$hash->{UndefFn} = 'FHEM::TeslaPowerwall2AC::Undef';
|
$hash->{UndefFn} = \&Undef;
|
||||||
$hash->{NotifyFn} = 'FHEM::TeslaPowerwall2AC::Notify';
|
$hash->{NotifyFn} = \&Notify;
|
||||||
|
$hash->{RenameFn} = \&Rename;
|
||||||
|
|
||||||
$hash->{AttrFn} = 'FHEM::TeslaPowerwall2AC::Attr';
|
$hash->{AttrFn} = \&Attr;
|
||||||
$hash->{AttrList} =
|
$hash->{AttrList} =
|
||||||
'interval ' . 'disable:1 ' . 'devel:1 ' . $readingFnAttributes;
|
'interval '
|
||||||
|
. 'disable:1 '
|
||||||
|
. 'devel:1 '
|
||||||
|
. 'emailaddr '
|
||||||
|
. $readingFnAttributes;
|
||||||
|
$hash->{parseParams} = 1;
|
||||||
|
|
||||||
return FHEM::Meta::InitMod( __FILE__, $hash );
|
return FHEM::Meta::InitMod( __FILE__, $hash );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Define {
|
sub Define {
|
||||||
my $hash = shift;
|
my $hash = shift // return;
|
||||||
my $def = shift;
|
my $aArg = shift // return;
|
||||||
|
|
||||||
my @a = split( '[ \t][ \t]*', $def );
|
|
||||||
|
|
||||||
return $@ unless ( FHEM::Meta::SetInternals($hash) );
|
return $@ unless ( FHEM::Meta::SetInternals($hash) );
|
||||||
use version 0.60; our $VERSION = FHEM::Meta::Get( $hash, 'version' );
|
use version 0.60; our $VERSION = FHEM::Meta::Get( $hash, 'version' );
|
||||||
|
|
||||||
return 'too few parameters: define <name> TeslaPowerwall2AC <HOST>'
|
return 'too few parameters: define <name> TeslaPowerwall2AC <HOST>'
|
||||||
if ( @a != 3 );
|
if ( scalar( @{$aArg} ) != 3 );
|
||||||
|
|
||||||
my $name = $a[0];
|
my $name = $aArg->[0];
|
||||||
|
my $host = $aArg->[2];
|
||||||
|
|
||||||
my $host = $a[2];
|
|
||||||
$hash->{HOST} = $host;
|
$hash->{HOST} = $host;
|
||||||
$hash->{INTERVAL} = 300;
|
$hash->{INTERVAL} = 300;
|
||||||
$hash->{VERSION} = version->parse($VERSION)->normal;
|
$hash->{VERSION} = version->parse($VERSION)->normal;
|
||||||
@ -237,9 +244,7 @@ sub Define {
|
|||||||
|
|
||||||
sub Undef {
|
sub Undef {
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
my $arg = shift;
|
my $name = shift;
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
|
||||||
|
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
Log3 $name, 3, "TeslaPowerwall2AC ($name) - Device $name deleted";
|
Log3 $name, 3, "TeslaPowerwall2AC ($name) - Device $name deleted";
|
||||||
@ -292,7 +297,6 @@ sub Attr {
|
|||||||
$hash->{INTERVAL} = $attrVal;
|
$hash->{INTERVAL} = $attrVal;
|
||||||
Log3 $name, 3,
|
Log3 $name, 3,
|
||||||
"TeslaPowerwall2AC ($name) - set interval to $attrVal";
|
"TeslaPowerwall2AC ($name) - set interval to $attrVal";
|
||||||
Timer_GetData($hash);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( $cmd eq 'del' ) {
|
elsif ( $cmd eq 'del' ) {
|
||||||
@ -300,7 +304,6 @@ sub Attr {
|
|||||||
$hash->{INTERVAL} = 300;
|
$hash->{INTERVAL} = 300;
|
||||||
Log3 $name, 3,
|
Log3 $name, 3,
|
||||||
"TeslaPowerwall2AC ($name) - set interval to default";
|
"TeslaPowerwall2AC ($name) - set interval to default";
|
||||||
Timer_GetData($hash);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,18 +324,24 @@ sub Notify {
|
|||||||
|
|
||||||
Timer_GetData($hash)
|
Timer_GetData($hash)
|
||||||
if (
|
if (
|
||||||
grep /^INITIALIZED$/,
|
( grep /^INITIALIZED$/, @{$events}
|
||||||
@{$events} or grep /^DELETEATTR.$name.disable$/,
|
or grep /^ATTR.$name.emailaddr$/, @{$events}
|
||||||
@{$events} or grep /^DELETEATTR.$name.interval$/,
|
or grep /^ATTR.$name.interval$/, @{$events}
|
||||||
@{$events} or ( grep /^DEFINED.$name$/, @{$events} and $init_done )
|
or grep /^ATTR.$name.disable$/, @{$events}
|
||||||
|
or grep /^DELETEATTR.$name.disable$/, @{$events}
|
||||||
|
or grep /^DELETEATTR.$name.interval$/, @{$events}
|
||||||
|
or grep /^DEFINED.$name$/, @{$events} )
|
||||||
|
and $init_done
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Get {
|
sub Get {
|
||||||
my $hash = shift;
|
my $hash = shift // return;
|
||||||
my $name = shift;
|
my $aArg = shift // return;
|
||||||
my $cmd = shift;
|
|
||||||
|
my $name = shift @$aArg;
|
||||||
|
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' ) {
|
||||||
@ -372,8 +381,11 @@ sub Get {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
my $list =
|
my $list = '';
|
||||||
'statusSOE:noArg aggregates:noArg siteinfo:noArg sitemaster:noArg powerwalls:noArg registration:noArg status:noArg';
|
$list .=
|
||||||
|
'statusSOE:noArg aggregates:noArg siteinfo:noArg sitemaster:noArg powerwalls:noArg registration:noArg status:noArg'
|
||||||
|
if( AttrVal($name,'emailaddr','none') ne 'none'
|
||||||
|
&& defined(ReadPassword($hash, $name)) );
|
||||||
|
|
||||||
return 'Unknown argument ' . $cmd . ', choose one of ' . $list;
|
return 'Unknown argument ' . $cmd . ', choose one of ' . $list;
|
||||||
}
|
}
|
||||||
@ -389,15 +401,33 @@ sub Get {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub Set {
|
sub Set {
|
||||||
my ( $hash, $name, $cmd, @args ) = @_;
|
my $hash = shift // return;
|
||||||
|
my $aArg = shift // return;
|
||||||
|
|
||||||
|
my $name = shift @$aArg;
|
||||||
|
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 . $args[0] );
|
$arg = lc( $cmd . $aArg->[0] );
|
||||||
|
}
|
||||||
|
elsif ( lc $cmd eq 'setpassword' ) {
|
||||||
|
return "please set Attribut emailaddr first"
|
||||||
|
if ( AttrVal( $name, 'emailaddr', 'none' ) eq 'none' );
|
||||||
|
return "usage: $cmd <password>" if ( scalar( @{$aArg} ) != 1 );
|
||||||
|
|
||||||
|
StorePassword( $hash, $name, $aArg->[0] );
|
||||||
|
return Timer_GetData($hash);
|
||||||
|
}
|
||||||
|
elsif ( lc $cmd eq 'removepassword' ) {
|
||||||
|
return "usage: $cmd" if ( scalar( @{$aArg} ) != 0 );
|
||||||
|
|
||||||
|
DeletePassword($hash);
|
||||||
|
return Timer_GetData($hash);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
my $list = '';
|
my $list = ( defined(ReadPassword($hash, $name)) ? 'removePassword:noArg ' : 'setPassword ');
|
||||||
$list .= 'powerwalls:run,stop'
|
$list .= 'powerwalls:run,stop'
|
||||||
if ( AttrVal( $name, 'devel', 0 ) == 1 );
|
if ( AttrVal( $name, 'devel', 0 ) == 1 );
|
||||||
|
|
||||||
@ -419,7 +449,14 @@ sub Timer_GetData {
|
|||||||
if ( defined( $hash->{actionQueue} )
|
if ( defined( $hash->{actionQueue} )
|
||||||
and scalar( @{ $hash->{actionQueue} } ) == 0 )
|
and scalar( @{ $hash->{actionQueue} } ) == 0 )
|
||||||
{
|
{
|
||||||
if ( not IsDisabled($name) ) {
|
if ( !IsDisabled($name) ) {
|
||||||
|
return readingsSingleUpdate( $hash, 'state',
|
||||||
|
'please set Attribut emailaddr first', 1 )
|
||||||
|
if ( AttrVal( $name, 'emailaddr', 'none' ) eq 'none' );
|
||||||
|
return readingsSingleUpdate( $hash, 'state',
|
||||||
|
'please set password first', 1 )
|
||||||
|
if ( !defined( ReadPassword( $hash, $name ) ) );
|
||||||
|
|
||||||
if ( !defined( $hash->{TOKEN}) ) {
|
if ( !defined( $hash->{TOKEN}) ) {
|
||||||
unshift( @{ $hash->{actionQueue} }, 'login' );
|
unshift( @{ $hash->{actionQueue} }, 'login' );
|
||||||
}
|
}
|
||||||
@ -432,7 +469,7 @@ sub Timer_GetData {
|
|||||||
Write($hash);
|
Write($hash);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
|
return readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -824,10 +861,11 @@ sub CreateUri {
|
|||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
my $path = shift;
|
my $path = shift;
|
||||||
|
|
||||||
|
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 = ( defined($paths{$path}) ? $host . '/api/' . $paths{$path} : undef );
|
my $uri = ( $path ne 'login' ? $host . '/api/' . $paths{$path} : undef );
|
||||||
my $data;
|
my $data;
|
||||||
|
|
||||||
|
|
||||||
@ -835,10 +873,10 @@ sub CreateUri {
|
|||||||
$method = 'POST';
|
$method = 'POST';
|
||||||
$header = 'Content-Type: application/json';
|
$header = 'Content-Type: application/json';
|
||||||
$uri = 'login/Basic',
|
$uri = 'login/Basic',
|
||||||
$data = '{"username":"","password":"S'
|
$data = '{"username":"customer","password":"' . ReadPassword( $hash, $name ) . '","email":"' . AttrVal($name,'emailaddr','test@test.de') . '","force_sm_off":false}'
|
||||||
. ReadingsVal( $hash->{NAME},
|
|
||||||
'powerwalls-wall_0_PackageSerialNumber', 0 )
|
|
||||||
. '","force_sm_off":false}';
|
|
||||||
}
|
}
|
||||||
elsif ( $path eq 'powerwallsstop'
|
elsif ( $path eq 'powerwallsstop'
|
||||||
|| $path eq 'powerwallsruns' )
|
|| $path eq 'powerwallsruns' )
|
||||||
@ -849,6 +887,104 @@ sub CreateUri {
|
|||||||
return ( $uri, $method, $header, $data, $path );
|
return ( $uri, $method, $header, $data, $path );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub StorePassword {
|
||||||
|
my $hash = shift;
|
||||||
|
my $name = shift;
|
||||||
|
my $password = shift;
|
||||||
|
|
||||||
|
my $index = $hash->{TYPE} . "_" . $name . "_passwd";
|
||||||
|
my $key = getUniqueId() . $index;
|
||||||
|
my $enc_pwd = "";
|
||||||
|
|
||||||
|
if ( eval "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 "error while saving the password - $err" if ( defined($err) );
|
||||||
|
|
||||||
|
return "password successfully saved";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub ReadPassword {
|
||||||
|
my $hash = shift;
|
||||||
|
my $name = shift;
|
||||||
|
|
||||||
|
my $index = $hash->{TYPE} . "_" . $name . "_passwd";
|
||||||
|
my $key = getUniqueId() . $index;
|
||||||
|
my ( $password, $err );
|
||||||
|
|
||||||
|
Log3 $name, 4, "TeslaPowerwall2AC ($name) - Read password from file";
|
||||||
|
|
||||||
|
( $err, $password ) = getKeyValue($index);
|
||||||
|
|
||||||
|
if ( defined($err) ) {
|
||||||
|
|
||||||
|
Log3 $name, 3,
|
||||||
|
"TeslaPowerwall2AC ($name) - unable to read password from file: $err";
|
||||||
|
return undef;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( defined($password) ) {
|
||||||
|
if ( eval "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, "TeslaPowerwall2AC ($name) - No password in file";
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sub DeletePassword {
|
||||||
|
my $hash = shift;
|
||||||
|
|
||||||
|
setKeyValue( $hash->{TYPE} . "_" . $hash->{NAME} . "_passwd", undef );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub Rename {
|
||||||
|
my $new = shift;
|
||||||
|
my $old = shift;
|
||||||
|
|
||||||
|
my $hash = $defs{$new};
|
||||||
|
|
||||||
|
StorePassword( $hash, $new, ReadPassword( $hash, $old ) );
|
||||||
|
setKeyValue( $hash->{TYPE} . "_" . $old . "_passwd", undef );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
@ -894,6 +1030,8 @@ sub CreateUri {
|
|||||||
<li>state - information about internel modul processes</li>
|
<li>state - information about internel modul processes</li>
|
||||||
<li>status-* - readings of the /api/status response</li>
|
<li>status-* - readings of the /api/status response</li>
|
||||||
<li>statussoe-* - readings of the /api/system_status/soe response</li>
|
<li>statussoe-* - readings of the /api/system_status/soe response</li>
|
||||||
|
<li>setPassword - write password encrypted to password file</li>
|
||||||
|
<li>removePassword - remove password from password file</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a name="TeslaPowerwall2ACget"></a>
|
<a name="TeslaPowerwall2ACget"></a>
|
||||||
<b>get</b>
|
<b>get</b>
|
||||||
@ -910,6 +1048,7 @@ sub CreateUri {
|
|||||||
<b>Attribute</b>
|
<b>Attribute</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li>interval - interval in seconds for automatically fetch data (default 300)</li>
|
<li>interval - interval in seconds for automatically fetch data (default 300)</li>
|
||||||
|
<li>emailaddr - emailadress to get cookie token</li>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
UPD 2021-02-27_04:38:01 26844 FHEM/46_TeslaPowerwall2AC.pm
|
UPD 2021-02-27_12:10:30 30701 FHEM/46_TeslaPowerwall2AC.pm
|
||||||
|
Loading…
x
Reference in New Issue
Block a user