Compare commits

..

1 Commits

Author SHA1 Message Date
d4ae8fcdbf fix multiple variablen declaration and code rewrite 2022-03-21 10:13:34 +01:00

View File

@ -1,5 +1,7 @@
package FHEM::EaseeWallbox; package FHEM::EaseeWallbox;
# use GPUtils qw(GP_Import GP_Export); hast Du auch weiter unten stehen
use strict; use strict;
use warnings; use warnings;
use Data::Dumper; use Data::Dumper;
@ -68,7 +70,9 @@ eval {
# Import von Funktionen und/oder Variablen aus der FHEM main # Import von Funktionen und/oder Variablen aus der FHEM main
# man kann ::Funktionaname wählen und sich so den Import schenken. Variablen sollten aber # man kann ::Funktionaname wählen und sich so den Import schenken. Variablen sollten aber
# sauber importiert werden # sauber importiert werden
use GPUtils qw(GP_Import GP_Export); # use GPUtils qw(GP_Import);
use GPUtils qw(GP_Import GP_Export)
; # da Du beide Funktionen aus dem package verwendest
## Import der FHEM Funktionen ## Import der FHEM Funktionen
#-- Run before package compilation #-- Run before package compilation
@ -92,7 +96,6 @@ BEGIN {
gettimeofday gettimeofday
getUniqueId getUniqueId
Attr Attr
defs
) )
); );
} }
@ -120,6 +123,7 @@ my %sets = (
pauseCharging => "", pauseCharging => "",
resumeCharging => "", resumeCharging => "",
toggleCharging => "", toggleCharging => "",
interval => "",
refreshToken => "noArg", refreshToken => "noArg",
cableLock => "true,false", cableLock => "true,false",
reboot => "noArg", reboot => "noArg",
@ -150,8 +154,8 @@ my %dpoints = (
getCurrentSession => 'chargers/#ChargerID#/sessions/ongoing', getCurrentSession => 'chargers/#ChargerID#/sessions/ongoing',
setCableLockState => 'chargers/#ChargerID#/commands/lock_state', setCableLockState => 'chargers/#ChargerID#/commands/lock_state',
setReboot => 'chargers/#ChargerID#/commands/reboot', setReboot => 'chargers/#ChargerID#/commands/reboot',
setUpdateFirmware => 'chargers/#ChargerID#/commands/update_firmware', setUpdateFirmware => 'chargers/#ChargerID#/commands/update_firmware',
setEnableSmartCharging => 'chargers/#ChargerID#/commands/smart_charging', setEnableSmartCharging => 'chargers/#ChargerID#/commands/smart_charging',
setStartCharging => 'chargers/#ChargerID#/commands/start_charging', setStartCharging => 'chargers/#ChargerID#/commands/start_charging',
setStopCharging => 'chargers/#ChargerID#/commands/stop_charging', setStopCharging => 'chargers/#ChargerID#/commands/stop_charging',
setPauseCharging => 'chargers/#ChargerID#/commands/pause_charging', setPauseCharging => 'chargers/#ChargerID#/commands/pause_charging',
@ -226,18 +230,22 @@ my %commandCodes = (
); );
#Private function to evaluate command-lists #Private function to evaluate command-lists
# private funktionen beginnen immer mit _
#############################
sub _GetCmdList { sub _GetCmdList {
my ( $hash, $cmd, $commands ) = @_; my ( $hash, $cmd, $commands ) = @_;
my %cmdArray = %$commands; my %cmdArray = %$commands;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $retVal;
#return, if cmd is valid #return, if cmd is valid
return if ( defined($cmd) and defined( $cmdArray{$cmd} ) ); return if ( defined($cmd) and defined( $cmdArray{$cmd} ) );
#response for gui or the user, if command is invalid #response for gui or the user, if command is invalid
my $retVal;
foreach my $mySet ( keys %cmdArray ) { foreach my $mySet ( keys %cmdArray ) {
#append set-command #append set-command
$retVal = $retVal . " " $retVal = $retVal . " "
if ( defined($retVal) ) if ( defined($retVal) )
@ -251,11 +259,19 @@ sub _GetCmdList {
$retVal = $retVal . ":" . $myOpt $retVal = $retVal . ":" . $myOpt
if ( defined($myOpt) and ( length($myOpt) > 0 ) ); if ( defined($myOpt) and ( length($myOpt) > 0 ) );
$myOpt = "" if ( !defined($myOpt) ); $myOpt = "" if ( !defined($myOpt) );
#Log3 ($name, 5, "parse cmd-table - Set:$mySet, Option:$myOpt, RetVal:$retVal");
} }
if ( !defined($retVal) ) { if ( !defined($retVal) ) {
return "error while parsing set-table"; return "error while parsing set-table";
} }
return "Unknown argument $cmd, choose one of " . $retVal; return "Unknown argument $cmd, choose one of " . $retVal;
# versuche wo wenig wie möglich if else zu verwenden.
# else {
# $retVal = "Unknown argument $cmd, choose one of " . $retVal;
# }
} }
sub Initialize { sub Initialize {
@ -271,11 +287,11 @@ sub Initialize {
$hash->{AttrList} = $hash->{AttrList} =
'expertMode:yes,no ' 'expertMode:yes,no '
. 'interval ' . 'ledStuff:yes,no '
. 'SmartCharging:true,false ' . 'SmartCharging:true,false '
. $readingFnAttributes; . $readingFnAttributes;
#Log3, 'EaseeWallbox', 2, "EaseeWallbox module initialized."; #Log3, 'EaseeWallbox', 3, "EaseeWallbox module initialized.";
return; return;
} }
@ -283,17 +299,18 @@ sub Define {
my ( $hash, $def ) = @_; my ( $hash, $def ) = @_;
my @param = split( "[ \t]+", $def ); my @param = split( "[ \t]+", $def );
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $errmsg = '';
# set API URI as Internal Key # set API URI as Internal Key
$hash->{APIURI} = 'https://api.easee.cloud/api/'; $hash->{APIURI} = 'https://api.easee.cloud/api/';
Log3 $name, 3, "EaseeWallbox_Define $name: called "; Log3 $name, 3, "EaseeWallbox_Define $name: called ";
my $errmsg = '';
# Check parameter(s) - Must be min 4 in total (counts strings not purly parameter, interval is optional) # Check parameter(s) - Must be min 4 in total (counts strings not purly parameter, interval is optional)
if ( int(@param) < 4 ) { if ( int(@param) < 4 ) {
$errmsg = return $errmsg = return
"syntax error: define <name> EaseeWallbox <username> <password> [Interval]"; "syntax error: define <name> EaseeWallbox <username> <password> [Interval]";
Log3 $name, 1, "EaseeWallbox $name: " . $errmsg; Log3 $name, 1, "EaseeWallbox $name: " . $errmsg;
return $errmsg; return $errmsg;
} }
@ -306,7 +323,7 @@ sub Define {
} }
else { else {
$errmsg = $errmsg =
"specify valid email address within the field username. Format: define <name> EaseeWallbox <username> <password> [interval]"; "specify valid email address within the field username. Format: define <name> EaseeWallbox <username> <password> [interval]";
Log3 $name, 1, "EaseeWallbox $name: " . $errmsg; Log3 $name, 1, "EaseeWallbox $name: " . $errmsg;
return $errmsg; return $errmsg;
} }
@ -314,6 +331,7 @@ sub Define {
#Take password and use custom encryption. #Take password and use custom encryption.
# Encryption is taken from fitbit / withings module # Encryption is taken from fitbit / withings module
my $password = _encrypt( $param[3] ); my $password = _encrypt( $param[3] );
$hash->{Password} = $password; $hash->{Password} = $password;
if ( defined $param[4] ) { if ( defined $param[4] ) {
@ -352,18 +370,20 @@ sub Define {
#Initial load of data #Initial load of data
WriteToCloudAPI( $hash, 'getChargers', 'GET' ); WriteToCloudAPI( $hash, 'getChargers', 'GET' );
Log3 $name, 2, Log3 $name, 1,
sprintf( "EaseeWallbox_Define %s: Starting timer with interval %s", sprintf( "EaseeWallbox_Define %s: Starting timer with interval %s",
$name, InternalVal( $name, 'INTERVAL', undef ) ); $name, InternalVal( $name, 'INTERVAL', undef ) );
InternalTimer( gettimeofday() + InternalVal( $name, 'INTERVAL', undef ), InternalTimer( gettimeofday() + InternalVal( $name, 'INTERVAL', undef ),
"FHEM::EaseeWallbox::UpdateDueToTimer", $hash ) "FHEM::EaseeWallbox::UpdateDueToTimer", $hash )
if ( defined $hash ); if ( defined $hash );
## return; sollte es nicht geben, ein return; ist per see mit Rückgabe undef
return; return;
} }
sub Undef { sub Undef {
my ( $hash, $arg ) = @_; my ( $hash, $arg ) = @_;
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
return; return;
} }
@ -393,7 +413,7 @@ sub Set {
return '"set $name" needs at least one argument' if ( int(@param) < 1 ); return '"set $name" needs at least one argument' if ( int(@param) < 1 );
my $opt = shift @param; my $opt = shift @param;
my $value = join( "", @param ); $value = join( "", @param );
my %message; my %message;
#create response, if cmd is wrong or gui asks #create response, if cmd is wrong or gui asks
@ -404,7 +424,7 @@ sub Set {
# Cascading if-elsif chain. See pages 117,118 of PBP (ControlStructures::ProhibitCascadingIfElse) kann man anders machen. Später machen wir das # Cascading if-elsif chain. See pages 117,118 of PBP (ControlStructures::ProhibitCascadingIfElse) kann man anders machen. Später machen wir das
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
Log3 $name, 3, Log3 $name, 1,
"EaseeWallbox_Set $name: Stopped the timer to automatically update readings"; "EaseeWallbox_Set $name: Stopped the timer to automatically update readings";
readingsSingleUpdate( $hash, 'state', 'Initialized', 0 ); readingsSingleUpdate( $hash, 'state', 'Initialized', 0 );
return; return;
@ -419,11 +439,21 @@ sub Set {
InternalTimer( gettimeofday() + InternalVal( $name, 'INTERVAL', undef ), InternalTimer( gettimeofday() + InternalVal( $name, 'INTERVAL', undef ),
"FHEM::EaseeWallbox::UpdateDueToTimer", $hash ); "FHEM::EaseeWallbox::UpdateDueToTimer", $hash );
readingsSingleUpdate( $hash, 'state', 'Started', 0 ); readingsSingleUpdate( $hash, 'state', 'Started', 0 );
Log3 $name, 3, Log3 $name, 1,
sprintf( sprintf(
"EaseeWallbox_Set %s: Updated readings and started timer to automatically update readings with interval %s", "EaseeWallbox_Set %s: Updated readings and started timer to automatically update readings with interval %s",
$name, InternalVal( $name, 'INTERVAL', undef ) ); $name, InternalVal( $name, 'INTERVAL', undef ) );
} }
elsif ( $opt eq "interval" )
{ # interval wird immer über Attribut gesetzt. Also in die Funktion AttrFn aus Initialize
my $interval = shift @param;
$interval = 60 unless defined($interval);
if ( $interval < 5 ) { $interval = 5; }
Log3 $name, 1, "EaseeWallbox_Set $name: Set interval to" . $interval;
$hash->{INTERVAL} = $interval;
}
elsif ( $opt eq "cableLock" ) { elsif ( $opt eq "cableLock" ) {
$message{'state'} = $value; $message{'state'} = $value;
@ -502,30 +532,7 @@ sub Set {
sub Attr { sub Attr {
my ( $cmd, $name, $attrName, $attrVal ) = @_; my ( $cmd, $name, $attrName, $attrVal ) = @_;
my $hash = $defs{$name};
if ( $attrName eq 'interval' ) {
if ( $cmd eq 'set' ) {
return 'Interval must be greater than 0'
if ( $attrVal == 0 );
RemoveInternalTimer( $hash,
"FHEM::EaseeWallbox::UpdateDueToTimer" );
$hash->{INTERVAL} = $attrVal;
InternalTimer( gettimeofday() + $hash->{INTERVAL},
"FHEM::EaseeWallbox::UpdateDueToTimer", $hash );
Log3 $name, 3,
"EaseeWallbox ($name) - set interval: $attrVal";
}
elsif ( $cmd eq 'del' ) {
RemoveInternalTimer( $hash,
"FHEM::EaseeWallbox::UpdateDueToTimer" );
$hash->{INTERVAL} = 60;
InternalTimer( gettimeofday() + $hash->{INTERVAL},
"FHEM::EaseeWallbox::UpdateDueToTimer", $hash );
Log3 $name, 3,
"EaseeWallbox ($name) - delete interval and set default: 60";
}
}
# hier kannst Du das setzen des Intervals umsetzen # hier kannst Du das setzen des Intervals umsetzen
return; return;
} }
@ -552,9 +559,11 @@ sub UpdateDueToTimer {
if ( !$hash->{LOCAL} ) { if ( !$hash->{LOCAL} ) {
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
#Log3 "Test", 1, Dumper($hash);
InternalTimer( gettimeofday() + InternalVal( $name, 'INTERVAL', undef ), InternalTimer( gettimeofday() + InternalVal( $name, 'INTERVAL', undef ),
"FHEM::EaseeWallbox::UpdateDueToTimer", $hash ); "FHEM::EaseeWallbox::UpdateDueToTimer", $hash );
} }
return RefreshData($hash); return RefreshData($hash);
} }
@ -565,14 +574,12 @@ sub WriteToCloudAPI {
my $message = shift; my $message = shift;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $url = $hash->{APIURI} . $dpoints{$dpoint}; my $url = $hash->{APIURI} . $dpoints{$dpoint};
my $chargerId;
my $siteId;
my $payload;
######### #########
# CHANGE THIS # CHANGE THIS
my $deviceId = "WC1"; my $payload;
$payload = encode_json \%$message if defined $message; $payload = encode_json \%$message if defined $message;
my $deviceId = "WC1";
if ( not defined $hash ) { if ( not defined $hash ) {
my $msg = my $msg =
@ -582,30 +589,30 @@ sub WriteToCloudAPI {
} }
#Check if chargerID is required in URL and replace or alert. #Check if chargerID is required in URL and replace or alert.
if ( $url =~ m/\#ChargerID\#/x ) if ( $url =~ m/#ChargerID#/x )
{ # Regular expression without "/x" flag. See page 236 of PBP (RegularExpressions::RequireExtendedFormatting) { # Regular expression without "/x" flag. See page 236 of PBP (RegularExpressions::RequireExtendedFormatting)
$chargerId = ReadingsVal( $name, 'charger_id', undef ); my $chargerId = ReadingsVal( $name, 'charger_id', undef );
if ( not defined $chargerId ) { if ( not defined $chargerId ) {
my $error = my $error =
"Error on EaseeWallbox_WriteToCloudAPI. Missing charger_id. Please ensure basic data is available."; "Error on EaseeWallbox_WriteToCloudAPI. Missing charger_id. Please ensure basic data is available.";
Log3 'EaseeWallbox', 1, $error; Log3 'EaseeWallbox', 1, $error;
return $error; return $error;
} }
$url =~ s/\#ChargerID\#/$chargerId/xg $url =~ s/#ChargerID#/$chargerId/xg
; # Regular expression without "/x" flag. See page 236 of PBP (RegularExpressions::RequireExtendedFormatting) ; # Regular expression without "/x" flag. See page 236 of PBP (RegularExpressions::RequireExtendedFormatting)
} }
#Check if siteID is required in URL and replace or alert. #Check if siteID is required in URL and replace or alert.
if ( $url =~ m/\#SiteID\#/x ) if ( $url =~ m/#SiteID#/x )
{ # Regular expression without "/x" flag. See page 236 of PBP (RegularExpressions::RequireExtendedFormatting) { # Regular expression without "/x" flag. See page 236 of PBP (RegularExpressions::RequireExtendedFormatting)
$siteId = ReadingsVal( $name, 'site_id', undef ); my $siteId = ReadingsVal( $name, 'site_id', undef );
if ( not defined $siteId ) { if ( not defined $siteId ) {
my $error = my $error =
"Error on EaseeWallbox_WriteToCloudAPI. Missing site_id. Please ensure basic data is available."; "Error on EaseeWallbox_WriteToCloudAPI. Missing site_id. Please ensure basic data is available.";
Log3 'EaseeWallbox', 1, $error; Log3 'EaseeWallbox', 1, $error;
return $error; return $error;
} }
$url =~ s/\#SiteID\#/$siteId/xg $url =~ s/#SiteID#/$siteId/xg
; # Regular expression without "/x" flag. See page 236 of PBP (RegularExpressions::RequireExtendedFormatting) ; # Regular expression without "/x" flag. See page 236 of PBP (RegularExpressions::RequireExtendedFormatting)
} }
@ -642,14 +649,12 @@ sub ResponseHandling {
my $data = shift; my $data = shift;
my $hash = $param->{hash}; my $hash = $param->{hash};
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $decoded_json;
my $value;
Log3 $name, 4, "Callback received." . $param->{url}; Log3 $name, 4, "Callback received." . $param->{url};
if ( $err ne "" ) # wenn ein Fehler bei der HTTP Abfrage aufgetreten ist if ( $err ne "" ) # wenn ein Fehler bei der HTTP Abfrage aufgetreten ist
{ {
Log3 $name, 1, Log3 $name, 3,
"error while requesting " "error while requesting "
. $param->{url} . $param->{url}
. " - $err"; # Eintrag fürs Log . " - $err"; # Eintrag fürs Log
@ -659,7 +664,7 @@ sub ResponseHandling {
my $code = $param->{code}; my $code = $param->{code};
if ( $code == 404 and $param->{dpoint} eq 'getCurrentSession' ) if ( $code == 404 and $param->{dpoint} eq 'getCurrentSession' )
{ { # Entweder == dann number z.B. 404 oder wenn eq dann String also '404'
readingsDelete( $hash, 'session_energy' ); readingsDelete( $hash, 'session_energy' );
readingsDelete( $hash, 'session_start' ); readingsDelete( $hash, 'session_start' );
readingsDelete( $hash, 'session_end' ); readingsDelete( $hash, 'session_end' );
@ -673,7 +678,7 @@ sub ResponseHandling {
} }
if ( $code >= 400 ) { if ( $code >= 400 ) {
Log3 $name, 1, Log3 $name, 3,
"HTTPS error while requesting " "HTTPS error while requesting "
. $param->{url} . $param->{url}
. " - $code"; # Eintrag fürs Log . " - $code"; # Eintrag fürs Log
@ -682,8 +687,8 @@ sub ResponseHandling {
return; return;
} }
Log3 $name, 4, Log3 $name, 3,
"Received non-blocking data from EaseeWallbox."; "Received non-blocking data from EaseeWallbox regarding current session ";
Log3 $name, 4, "FHEM -> EaseeWallbox: " . $param->{url}; Log3 $name, 4, "FHEM -> EaseeWallbox: " . $param->{url};
Log3 $name, 4, "FHEM -> EaseeWallbox: " . $param->{message} Log3 $name, 4, "FHEM -> EaseeWallbox: " . $param->{message}
@ -691,57 +696,240 @@ sub ResponseHandling {
Log3 $name, 4, "EaseeWallbox -> FHEM: " . $data; Log3 $name, 4, "EaseeWallbox -> FHEM: " . $data;
Log3 $name, 5, '$err: ' . $err; Log3 $name, 5, '$err: ' . $err;
Log3 $name, 5, "method: " . $param->{method}; Log3 $name, 5, "method: " . $param->{method};
Log3 $name, 2, "Something gone wrong"
if ( $data =~ "/EaseeWallboxMode/" );
my $decoded_json;
eval { $decoded_json = decode_json($data) }; # statt eval ist es empfohlen catch try zu verwenden. Machen wir später eval { $decoded_json = decode_json($data) }; # statt eval ist es empfohlen catch try zu verwenden. Machen wir später
if ($@) { if ($@) {
Log3 $name, 3, "EaseeWallbox ($name) - JSON error while processing request"; Log3 $name, 3, "GardenaSmartBridge ($name) - JSON error while request";
} }
Log3 $name, 5, 'Decoded: ' . Dumper($decoded_json); Log3 $name, 5, 'Decoded: ' . Dumper($decoded_json);
Log3 $name, 5, 'Ref of d: ' . ref($decoded_json);
my $value;
if ( defined $decoded_json if ( defined $decoded_json
and $decoded_json ne '' and $decoded_json ne ''
and ref($decoded_json) eq "HASH" and ref($decoded_json) eq "HASH"
or ( ref($decoded_json) eq "ARRAY" and $decoded_json > 0 ) ) or ( ref($decoded_json) eq "ARRAY" and $decoded_json > 0 ) )
{ {
if ( $param->{dpoint} eq 'getChargers' ) { if ( $param->{dpoint} eq 'getChargers' ) {
Processing_DpointGetChargers( $hash, $decoded_json ); Processing_DpointGetChargers( $hash, $decode_json );
return; return;
} }
if ( $param->{dpoint} eq 'getChargerSessionsDaily' ) { if ( $param->{dpoint} eq 'getChargerSessionsDaily' ) {
Processing_DpointGetChargerSessionsDaily( $hash, $decoded_json ); Processing_DpointGetChargerSessionsDaily( $hash, $decode_json );
return; return;
} }
# Und so weiter und so weiter mit den einzelnen Funktionen !!!
if ( $param->{dpoint} eq 'getChargerSessionsMonthly' ) { if ( $param->{dpoint} eq 'getChargerSessionsMonthly' ) {
Processing_DpointGetChargerSessionsMonthly( $hash, $decoded_json ); Log3 $name, 5, 'Evaluating getChargerSessionsMonthly';
my @x = $decoded_json;
my @a = ( -6 .. -1 );
readingsBeginUpdate($hash);
for (@a) {
Log3 $name, 5, 'laeuft noch: ' . $_;
readingsBulkUpdate(
$hash,
"monthly_" . ( $_ + 1 ) . "_energy",
sprintf(
"%.2f", $decoded_json->[$_]->{'totalEnergyUsage'}
)
);
readingsBulkUpdate(
$hash,
"monthly_" . ( $_ + 1 ) . "_cost",
sprintf( "%.2f", $decoded_json->[$_]->{'totalCost'} )
);
}
readingsEndUpdate( $hash, 1 );
return; return;
} }
if ( $param->{dpoint} eq 'getChargerConfiguration' ) { if ( $param->{dpoint} eq 'getChargerConfiguration' ) {
Processing_DpointGetChargerConfiguration( $hash, $decoded_json ); readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "isEnabled",
$decoded_json->{isEnabled} );
readingsBulkUpdate( $hash, "isCablePermanentlyLocked",
$decoded_json->{lockCablePermanently} );
readingsBulkUpdate( $hash, "isAuthorizationRequired",
$decoded_json->{authorizationRequired} );
readingsBulkUpdate( $hash, "isRemoteStartRequired",
$decoded_json->{remoteStartRequired} );
readingsBulkUpdate( $hash, "isSmartButtonEnabled",
$decoded_json->{smartButtonEnabled} );
readingsBulkUpdate( $hash, "wiFiSSID", $decoded_json->{wiFiSSID} );
readingsBulkUpdate( $hash, "phaseModeId",
$decoded_json->{phaseMode} );
readingsBulkUpdate( $hash, "phaseMode",
$phaseModes{ $decoded_json->{phaseMode} } );
readingsBulkUpdate(
$hash,
"isLocalAuthorizationRequired",
$decoded_json->{localAuthorizationRequired}
);
readingsBulkUpdate( $hash, "maxChargerCurrent",
$decoded_json->{maxChargerCurrent} );
readingsBulkUpdate( $hash, "ledStripBrightness",
$decoded_json->{ledStripBrightness} );
#readingsBulkUpdate( $hash, "charger_offlineChargingMode",
# $decoded_json->{offlineChargingMode} );
#readingsBulkUpdate( $hash, "charger_circuitMaxCurrentP1",
# $decoded_json->{circuitMaxCurrentP1} );
#readingsBulkUpdate( $hash, "charger_circuitMaxCurrentP2",
# $decoded_json->{circuitMaxCurrentP2} );
#readingsBulkUpdate( $hash, "charger_circuitMaxCurrentP3",
# $decoded_json->{circuitMaxCurrentP3} );
#readingsBulkUpdate( $hash, "charger_enableIdleCurrent",
# $decoded_json->{enableIdleCurrent} );
#readingsBulkUpdate(
# $hash,
# "charger_limitToSinglePhaseCharging",
# $decoded_json->{limitToSinglePhaseCharging}
#);
#readingsBulkUpdate( $hash, "charger_localNodeType",
# $decoded_json->{localNodeType} );
#readingsBulkUpdate( $hash, "charger_localRadioChannel",
# $decoded_json->{localRadioChannel} );
#readingsBulkUpdate( $hash, "charger_localShortAddress",
# $decoded_json->{localShortAddress} );
#readingsBulkUpdate(
# $hash,
# "charger_localParentAddrOrNumOfNodes",
# $decoded_json->{localParentAddrOrNumOfNodes}
#);
#readingsBulkUpdate(
# $hash,
# "charger_localPreAuthorizeEnabled",
# $decoded_json->{localPreAuthorizeEnabled}
#);
#readingsBulkUpdate(
# $hash,
# "charger_allowOfflineTxForUnknownId",
# $decoded_json->{allowOfflineTxForUnknownId}
#);
#readingsBulkUpdate( $hash, "chargingSchedule",
# $decoded_json->{chargingSchedule} );
readingsBulkUpdate( $hash, "lastResponse",
'OK - getChargerConfig', 1 );
readingsEndUpdate( $hash, 1 );
return; return;
} }
if ( $param->{dpoint} eq 'getCurrentSession' ) { if ( $param->{dpoint} eq 'getCurrentSession' ) {
Processing_DpointGetCurrentSession( $hash, $decoded_json ); readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "session_energy",
sprintf( "%.2f", $decoded_json->{sessionEnergy} ) );
$value =
defined $decoded_json->{sessionStart}
? _transcodeDate( $decoded_json->{sessionStart} )
: 'N/A';
readingsBulkUpdate( $hash, "session_start", $value );
$value =
defined $decoded_json->{sessionEnd}
? _transcodeDate( $decoded_json->{sessionEnd} )
: 'N/A';
readingsBulkUpdate( $hash, "session_end", $value );
readingsBulkUpdate(
$hash,
"session_chargeDurationInSeconds",
$decoded_json->{chargeDurationInSeconds}
);
$value =
defined $decoded_json->{firstEnergyTransferPeriodStart}
? _transcodeDate(
$decoded_json->{firstEnergyTransferPeriodStart} )
: 'N/A';
readingsBulkUpdate( $hash, "session_firstEnergyTransfer", $value );
$value =
defined $decoded_json->{lastEnergyTransferPeriodStart}
? _transcodeDate( $decoded_json->{lastEnergyTransferPeriodStart} )
: 'N/A';
readingsBulkUpdate( $hash, "session_lastEnergyTransfer", $value );
readingsBulkUpdate( $hash, "session_pricePerKWH",
$decoded_json->{pricePrKwhIncludingVat} );
readingsBulkUpdate( $hash, "session_chargingCost",
sprintf( "%.2f", $decoded_json->{costIncludingVat} ) );
readingsBulkUpdate( $hash, "session_id",
$decoded_json->{sessionId} );
readingsBulkUpdate( $hash, "lastResponse",
'OK - getCurrentSession', 1 );
readingsEndUpdate( $hash, 1 );
return; return;
} }
if ( $param->{dpoint} eq 'getChargerSite' ) { if ( $param->{dpoint} eq 'getChargerSite' ) {
Processing_DpointGetChargerSite( $hash, $decoded_json ); readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "cost_perKWh",
$decoded_json->{costPerKWh} );
readingsBulkUpdate( $hash, "cost_perKwhExcludeVat",
$decoded_json->{costPerKwhExcludeVat} );
readingsBulkUpdate( $hash, "cost_vat", $decoded_json->{vat} );
readingsBulkUpdate( $hash, "cost_currency",
$decoded_json->{currencyId} );
#readingsBulkUpdate( $hash, "site_ratedCurrent", $decoded_json->{ratedCurrent} );
#readingsBulkUpdate( $hash, "site_createdOn", $decoded_json->{createdOn} );
#readingsBulkUpdate( $hash, "site_updatedOn", $decoded_json->{updatedOn} );
readingsBulkUpdate( $hash, "lastResponse",
'OK - getChargerSite', 1 );
readingsEndUpdate( $hash, 1 );
return; return;
} }
if ( $param->{dpoint} eq 'getChargerState' ) { if ( $param->{dpoint} eq 'getChargerState' ) {
Processing_DpointGetChargerState( $hash, $decoded_json ); readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "operationModeCode",
$decoded_json->{chargerOpMode} );
readingsBulkUpdate( $hash, "operationMode",
$operationModes{ $decoded_json->{chargerOpMode} } );
readingsBulkUpdate( $hash, "power",
sprintf( "%.2f", $decoded_json->{totalPower} ) );
readingsBulkUpdate( $hash, "kWhInSession",
sprintf( "%.2f", $decoded_json->{sessionEnergy} ) );
readingsBulkUpdate( $hash, "phase", $decoded_json->{outputPhase} );
readingsBulkUpdate( $hash, "latestPulse",
_transcodeDate( $decoded_json->{latestPulse} ) );
readingsBulkUpdate( $hash, "current",
$decoded_json->{outputCurrent} );
readingsBulkUpdate( $hash, "dynamicCurrent",
$decoded_json->{dynamicChargerCurrent} );
readingsBulkUpdate( $hash, "reasonCodeForNoCurrent",
$decoded_json->{reasonForNoCurrent} );
readingsBulkUpdate( $hash, "reasonForNoCurrent",
$reasonsForNoCurrent{ $decoded_json->{reasonForNoCurrent} } );
readingsBulkUpdate( $hash, "errorCode",
$decoded_json->{errorCode} );
readingsBulkUpdate( $hash, "fatalErrorCode",
$decoded_json->{fatalErrorCode} );
readingsBulkUpdate( $hash, "lifetimeEnergy",
sprintf( "%.2f", $decoded_json->{lifetimeEnergy} ) );
readingsBulkUpdate( $hash, "online", $decoded_json->{isOnline} );
readingsBulkUpdate( $hash, "voltage",
sprintf( "%.2f", $decoded_json->{voltage} ) );
readingsBulkUpdate( $hash, "wifi_rssi", $decoded_json->{wiFiRSSI} );
readingsBulkUpdate( $hash, "wifi_apEnabled",
$decoded_json->{wiFiAPEnabled} );
readingsBulkUpdate( $hash, "cell_rssi", $decoded_json->{cellRSSI} );
readingsBulkUpdate( $hash, "lastResponse",
'OK - getChargerState', 1 );
readingsEndUpdate( $hash, 1 );
return; return;
} }
$decoded_json = $decoded_json->[0] if ref($decoded_json) eq "ARRAY"; $decoded_json = $decoded_json->[0] if ref($decoded_json) eq "ARRAY";
readingsSingleUpdate( $hash, "lastResponse", readingsSingleUpdate( $hash, "lastResponse",
'OK - Action: ' . $commandCodes{ $decoded_json->{commandId} }, 1 ) 'OK - Action: ' . $commandCodes{ $decoded_json->{commandId} }, 1 )
if exists $decoded_json->{commandId}; if defined $decoded_json->{commandId};
readingsSingleUpdate( readingsSingleUpdate(
$hash, $hash,
"lastResponse", "lastResponse",
@ -750,7 +938,7 @@ sub ResponseHandling {
. $decoded_json->{status} . ')', . $decoded_json->{status} . ')',
1 1
) )
if exists $decoded_json->{status} and exists $decoded_json->{title}; if defined $decoded_json->{status} and defined $decoded_json->{title};
return; return;
} }
else { else {
@ -767,218 +955,6 @@ sub ResponseHandling {
return; return;
} }
sub Processing_DpointGetCurrentSessionNotFound {
my $hash = shift;
my $decoded_json = shift;
my $name = $hash->{NAME};
readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, 'session_energy', 'N/A' );
readingsBulkUpdate( $hash, 'session_start', 'N/A' );
readingsBulkUpdate( $hash, 'session_end', 'N/A' );
readingsBulkUpdate( $hash, 'session_chargeDurationInSeconds', 'N/A' );
readingsBulkUpdate( $hash, 'session_firstEnergyTransfer', 'N/A' );
readingsBulkUpdate( $hash, 'session_lastEnergyTransfer', 'N/A' );
readingsBulkUpdate( $hash, 'session_pricePerKWH', 'N/A' );
readingsBulkUpdate( $hash, 'session_chargingCost', 'N/A' );
readingsBulkUpdate( $hash, 'session_id', 'N/A' );
readingsEndUpdate( $hash, 1 );
return;
}
sub Processing_DpointGetChargerState {
my $hash = shift;
my $decoded_json = shift;
my $name = $hash->{NAME};
readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "operationModeCode",
$decoded_json->{chargerOpMode} );
readingsBulkUpdate( $hash, "operationMode",
$operationModes{ $decoded_json->{chargerOpMode} } );
readingsBulkUpdate( $hash, "power",
sprintf( "%.2f", $decoded_json->{totalPower} ) );
readingsBulkUpdate( $hash, "kWhInSession",
sprintf( "%.2f", $decoded_json->{sessionEnergy} ) );
readingsBulkUpdate( $hash, "phase", $decoded_json->{outputPhase} );
readingsBulkUpdate( $hash, "latestPulse",
_transcodeDate( $decoded_json->{latestPulse} ) );
readingsBulkUpdate( $hash, "current",
$decoded_json->{outputCurrent} );
readingsBulkUpdate( $hash, "dynamicCurrent",
$decoded_json->{dynamicChargerCurrent} );
readingsBulkUpdate( $hash, "reasonCodeForNoCurrent",
$decoded_json->{reasonForNoCurrent} );
readingsBulkUpdate( $hash, "reasonForNoCurrent",
$reasonsForNoCurrent{ $decoded_json->{reasonForNoCurrent} } );
readingsBulkUpdate( $hash, "errorCode",
$decoded_json->{errorCode} );
readingsBulkUpdate( $hash, "fatalErrorCode",
$decoded_json->{fatalErrorCode} );
readingsBulkUpdate( $hash, "lifetimeEnergy",
sprintf( "%.2f", $decoded_json->{lifetimeEnergy} ) );
readingsBulkUpdate( $hash, "online",
NumericToBoolean($decoded_json->{isOnline} ));
readingsBulkUpdate( $hash, "voltage",
sprintf( "%.2f", $decoded_json->{voltage} ) );
readingsBulkUpdate( $hash, "wifi_rssi", $decoded_json->{wiFiRSSI} );
readingsBulkUpdate( $hash, "wifi_apEnabled",
NumericToBoolean($decoded_json->{wiFiAPEnabled} ));
readingsBulkUpdate( $hash, "cell_rssi", $decoded_json->{cellRSSI} );
readingsBulkUpdate( $hash, "lastResponse",
'OK - getChargerState', 1 );
readingsEndUpdate( $hash, 1 );
return;
}
sub Processing_DpointGetChargerConfiguration {
my $hash = shift;
my $decoded_json = shift;
my $name = $hash->{NAME};
readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "isEnabled",
NumericToBoolean($decoded_json->{isEnabled} ));
readingsBulkUpdate( $hash, "isCablePermanentlyLocked",
NumericToBoolean($decoded_json->{lockCablePermanently} ));
readingsBulkUpdate( $hash, "isAuthorizationRequired",
NumericToBoolean($decoded_json->{authorizationRequired}) );
readingsBulkUpdate( $hash, "isRemoteStartRequired",
NumericToBoolean($decoded_json->{remoteStartRequired}) );
readingsBulkUpdate( $hash, "isSmartButtonEnabled",
NumericToBoolean($decoded_json->{smartButtonEnabled}) );
readingsBulkUpdate( $hash, "wiFiSSID", $decoded_json->{wiFiSSID} );
readingsBulkUpdate( $hash, "phaseModeId",
$decoded_json->{phaseMode} );
readingsBulkUpdate( $hash, "phaseMode",
$phaseModes{ $decoded_json->{phaseMode} } );
readingsBulkUpdate(
$hash,
"isLocalAuthorizationRequired",
NumericToBoolean($decoded_json->{localAuthorizationRequired}
));
readingsBulkUpdate( $hash, "maxChargerCurrent",
$decoded_json->{maxChargerCurrent} );
readingsBulkUpdate( $hash, "ledStripBrightness",
$decoded_json->{ledStripBrightness} );
#readingsBulkUpdate( $hash, "charger_offlineChargingMode",
# $decoded_json->{offlineChargingMode} );
#readingsBulkUpdate( $hash, "charger_circuitMaxCurrentP1",
# $decoded_json->{circuitMaxCurrentP1} );
#readingsBulkUpdate( $hash, "charger_circuitMaxCurrentP2",
# $decoded_json->{circuitMaxCurrentP2} );
#readingsBulkUpdate( $hash, "charger_circuitMaxCurrentP3",
# $decoded_json->{circuitMaxCurrentP3} );
#readingsBulkUpdate( $hash, "charger_enableIdleCurrent",
# $decoded_json->{enableIdleCurrent} );
#readingsBulkUpdate(
# $hash,
# "charger_limitToSinglePhaseCharging",
# $decoded_json->{limitToSinglePhaseCharging}
#);
#readingsBulkUpdate( $hash, "charger_localNodeType",
# $decoded_json->{localNodeType} );
#readingsBulkUpdate( $hash, "charger_localRadioChannel",
# $decoded_json->{localRadioChannel} );
#readingsBulkUpdate( $hash, "charger_localShortAddress",
# $decoded_json->{localShortAddress} );
#readingsBulkUpdate(
# $hash,
# "charger_localParentAddrOrNumOfNodes",
# $decoded_json->{localParentAddrOrNumOfNodes}
#);
#readingsBulkUpdate(
# $hash,
# "charger_localPreAuthorizeEnabled",
# $decoded_json->{localPreAuthorizeEnabled}
#);
#readingsBulkUpdate(
# $hash,
# "charger_allowOfflineTxForUnknownId",
# $decoded_json->{allowOfflineTxForUnknownId}
#);
#readingsBulkUpdate( $hash, "chargingSchedule",
# $decoded_json->{chargingSchedule} );
readingsBulkUpdate( $hash, "lastResponse",
'OK - getChargerConfig', 1 );
readingsEndUpdate( $hash, 1 );
return;
}
sub Processing_DpointGetCurrentSession {
my $hash = shift;
my $decoded_json = shift;
my $name = $hash->{NAME};
my $value;
readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "session_energy",
sprintf( "%.2f", $decoded_json->{sessionEnergy} ) );
$value =
defined $decoded_json->{sessionStart}
? _transcodeDate( $decoded_json->{sessionStart} )
: 'N/A';
readingsBulkUpdate( $hash, "session_start", $value );
$value =
defined $decoded_json->{sessionEnd}
? _transcodeDate( $decoded_json->{sessionEnd} )
: 'N/A';
readingsBulkUpdate( $hash, "session_end", $value );
readingsBulkUpdate(
$hash,
"session_chargeDurationInSeconds",
$decoded_json->{chargeDurationInSeconds}
);
$value =
defined $decoded_json->{firstEnergyTransferPeriodStart}
? _transcodeDate(
$decoded_json->{firstEnergyTransferPeriodStart} )
: 'N/A';
readingsBulkUpdate( $hash, "session_firstEnergyTransfer", $value );
$value =
defined $decoded_json->{lastEnergyTransferPeriodStart}
? _transcodeDate( $decoded_json->{lastEnergyTransferPeriodStart} )
: 'N/A';
readingsBulkUpdate( $hash, "session_lastEnergyTransfer", $value );
readingsBulkUpdate( $hash, "session_pricePerKWH",
$decoded_json->{pricePrKwhIncludingVat} );
readingsBulkUpdate( $hash, "session_chargingCost",
sprintf( "%.2f", $decoded_json->{costIncludingVat} ) );
readingsBulkUpdate( $hash, "session_id",
$decoded_json->{sessionId} );
readingsBulkUpdate( $hash, "lastResponse",
'OK - getCurrentSession', 1 );
readingsEndUpdate( $hash, 1 );
return;
}
sub Processing_DpointGetChargerSite {
my $hash = shift;
my $decoded_json = shift;
my $name = $hash->{NAME};
readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "cost_perKWh",
$decoded_json->{costPerKWh} );
readingsBulkUpdate( $hash, "cost_perKwhExcludeVat",
$decoded_json->{costPerKwhExcludeVat} );
readingsBulkUpdate( $hash, "cost_vat", $decoded_json->{vat} );
readingsBulkUpdate( $hash, "cost_currency",
$decoded_json->{currencyId} );
#readingsBulkUpdate( $hash, "site_ratedCurrent", $decoded_json->{ratedCurrent} );
#readingsBulkUpdate( $hash, "site_createdOn", $decoded_json->{createdOn} );
#readingsBulkUpdate( $hash, "site_updatedOn", $decoded_json->{updatedOn} );
readingsBulkUpdate( $hash, "lastResponse",
'OK - getChargerSite', 1 );
readingsEndUpdate( $hash, 1 );
return;
}
sub Processing_DpointGetChargers { sub Processing_DpointGetChargers {
my $hash = shift; my $hash = shift;
my $decoded_json = shift; my $decoded_json = shift;
@ -986,9 +962,9 @@ sub Processing_DpointGetChargers {
my $site = $decoded_json->[0]; my $site = $decoded_json->[0];
my $circuit = $site->{circuits}->[0]; my $circuit = $site->{circuits}->[0];
my $charger = $circuit->{chargers}->[0]; my $charger = $circuit->{chargers}->[0];
my $chargerId = $charger->{id};
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
my $chargerId = $charger->{id};
readingsBulkUpdate( $hash, "site_id", $site->{id} ); readingsBulkUpdate( $hash, "site_id", $site->{id} );
readingsBulkUpdate( $hash, "site_key", $site->{siteKey} ); readingsBulkUpdate( $hash, "site_key", $site->{siteKey} );
readingsBulkUpdate( $hash, "charger_id", $chargerId ); readingsBulkUpdate( $hash, "charger_id", $chargerId );
@ -997,17 +973,21 @@ sub Processing_DpointGetChargers {
readingsEndUpdate( $hash, 1 ); readingsEndUpdate( $hash, 1 );
WriteToCloudAPI( $hash, 'getChargerConfiguration', 'GET' ); WriteToCloudAPI( $hash, 'getChargerConfiguration', 'GET' );
return; return;
} }
sub Processing_DpointGetChargerSessionsDaily { sub Processing_DpointGetChargerSessionsDaily {
my $hash = shift; my $hash = shift;
my $decoded_json = shift; my $decoded_json = shift;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my @a = ( -5 .. -1 );
Log3 $name, 5, 'Evaluating getChargerSessionsDaily'; Log3 $name, 5, 'Evaluating getChargerSessionsDaily';
my @x = $decoded_json;
my @a = ( -5 .. -1 );
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
for (@a) { for (@a) {
Log3 $name, 5, 'laeuft noch: ' . $_; Log3 $name, 5, 'laeuft noch: ' . $_;
@ -1022,35 +1002,9 @@ sub Processing_DpointGetChargerSessionsDaily {
sprintf( "%.2f", $decoded_json->[$_]->{'totalCost'} ) sprintf( "%.2f", $decoded_json->[$_]->{'totalCost'} )
); );
} }
readingsEndUpdate( $hash, 1 ); readingsEndUpdate( $hash, 1 );
return;
}
sub Processing_DpointGetChargerSessionsMonthly {
my $hash = shift;
my $decoded_json = shift;
my $name = $hash->{NAME};
my @a = ( -6 .. -1 );
Log3 $name, 4, 'Evaluating getChargerSessionsMonthly';
readingsBeginUpdate($hash);
for (@a) {
Log3 $name, 5, 'laeuft noch: ' . $_;
readingsBulkUpdate(
$hash,
"monthly_" . ( $_ + 1 ) . "_energy",
sprintf(
"%.2f", $decoded_json->[$_]->{'totalEnergyUsage'}
)
);
readingsBulkUpdate(
$hash,
"monthly_" . ( $_ + 1 ) . "_cost",
sprintf( "%.2f", $decoded_json->[$_]->{'totalCost'} )
);
}
readingsEndUpdate( $hash, 1 );
return; return;
} }
@ -1109,7 +1063,7 @@ sub _newTokenRequest {
url => $hash->{APIURI} . $dpoints{getOAuthToken}, url => $hash->{APIURI} . $dpoints{getOAuthToken},
header => { "Content-Type" => "application/json" }, header => { "Content-Type" => "application/json" },
method => 'POST', method => 'POST',
timeout => 3, timeout => 5,
hash => $hash, hash => $hash,
data => encode_json $data data => encode_json $data
}; };
@ -1149,6 +1103,8 @@ sub _newTokenRequest {
"EaseeWallbox $name" . ": " "EaseeWallbox $name" . ": "
. "Retrived new authentication token successfully. Valid until " . "Retrived new authentication token successfully. Valid until "
. localtime( $hash->{TOKEN_LIFETIME} ); . localtime( $hash->{TOKEN_LIFETIME} );
# $hash->{STATE} = "reachable"; # niemals $hash->{STATE} über demn Hash direkt zuweisen
readingsSingleUpdate( $hash, 'state', 'reachable', 1 ); readingsSingleUpdate( $hash, 'state', 'reachable', 1 );
return $decoded_data; return $decoded_data;
} }
@ -1174,7 +1130,7 @@ sub _tokenRefresh {
url => $hash->{APIURI} . $dpoints{getRefreshToken}, url => $hash->{APIURI} . $dpoints{getRefreshToken},
header => { "Content-Type" => "application/json" }, header => { "Content-Type" => "application/json" },
method => 'POST', method => 'POST',
timeout => 3, timeout => 5,
hash => $hash, hash => $hash,
data => encode_json $data data => encode_json $data
}; };
@ -1289,14 +1245,12 @@ sub _transcodeDate {
return $dt->strftime('%Y-%m-%d %H:%M:%S'); return $dt->strftime('%Y-%m-%d %H:%M:%S');
} }
sub NumericToBoolean {
my $number = shift;
return $number == 0 ? 'false' : 'true';
}
1; # Ein Modul muss immer mit 1; enden 1; # Ein Modul muss immer mit 1; enden
=pod =pod
=begin html =begin html
=end html =end html
=cut =cut