From 25e436732765af5add9e736e66771be4d28a6d00 Mon Sep 17 00:00:00 2001 From: jual <> Date: Sun, 2 Jan 2022 13:27:45 +0000 Subject: [PATCH] 76_SMAEVCharger.pm: Initial Commit (Forum #116543) git-svn-id: https://svn.fhem.de/fhem/trunk@25409 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/76_SMAEVCharger.pm | 1781 ++++++++++++++++++++++++++++++++++ 1 file changed, 1781 insertions(+) create mode 100755 fhem/FHEM/76_SMAEVCharger.pm diff --git a/fhem/FHEM/76_SMAEVCharger.pm b/fhem/FHEM/76_SMAEVCharger.pm new file mode 100755 index 000000000..74e920ea3 --- /dev/null +++ b/fhem/FHEM/76_SMAEVCharger.pm @@ -0,0 +1,1781 @@ +################################################################################################################# +# $Id$ +# 76_SMAEVCharger.pm author: Jürgen Allmich +################################################################################################################# +# +# Copyright notice +# +# Published according Creative Commons : Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0) +# Details: https://creativecommons.org/licenses/by-nc-sa/3.0/ +# +# Credits: +# - used 73_SMAInverter.pm as template +# - +# - +# - +# - +# +# Description: +# This is an FHEM-Module for SMA EV Chargers. +# +################################################################################################################# +# +# Date Version Description +# 22.01.2022 0.0.92 Bugfixes: insert 'use JSON' +# 12.12.2021 0.0.91 Bugfixes: check for undefined parameter in SMAEVCharger_getReadableCode($) +# 14.11.2021 0.0.9 Bugfixes: when setting an incorrect value, the set command was executed anyway. No there is no setting, if value are incorrect +# Error on setting Laden_mit_Vorgabe while values Param_Energiemenge_Ladevorgang and Param_Dauer_Ladevorgang are set correctly +# On logon, if there is no body or header now an error will be returned (otherwise some fhem may be killed) +# Value "Schnellladen" on setting is not possible so it has been deleted from the options for Param_Betriebsart_Ladevorgang +# 05.07.2021 0.0.8 Bugfixing (Warnings of uninitialized values), Added Livedata "Drehschalter" +# 07.02.2021 0.0.7 'Schnellabschaltung' change detail-level to 0, Documentation for the module +# 30.01.2021 0.0.6 Attr setting-level, Setting Readings for advanced and expert, on setting Lademenge set correct end_time +# 24.01.2021 0.0.5 Bug fixing and new Readings Startzeit_Ladung, Anzahl_Ladevorgaenge, +# Attr detail-level for config which values the use would like to see (0: basic, 1: advanced, 2: expert) +# 14.01.2021 0.0.4 Set cmd for all charging values +# 11.01.2021 0.0.3 Read Params (not all), Set all values for charging +# 10.01.2021 0.0.2 Read Live Data +# 09.01.2021 0.0.1 Initial Modul +# +# +################################################################################################################# +# +# Todos +# Maybe Timesheets for automated charging (Weekplan) would be nice (actual solution with doif) +# Integration user function for individual SOC Modules (trying first with my kia) +# Look for better coding +# +################################################################################################################# + +package main; + +use strict; +use warnings; +eval "use DateTime;1" or my $MissModulDateTime = "DateTime"; +use Time::HiRes qw(gettimeofday tv_interval); +use Blocking; +use Time::Local; +use JSON; + + +############################################################### +# SMAEVCharger - help functions and variables +############################################################### + +# These readings are updateble +my %update_readings = ( + "Param_Betriebsart_Ladevorgang" => {values => ":Optimiertes_Laden,Laden_mit_Vorgabe,Ladestopp", level => 0}, + "Param_Minimaler_Ladestrom" => {values => ":slider,6,1,32", level => 0}, + "Param_Dauer_Ladevorgang" => {values => ":time", level => 0}, + "Param_Energiemenge_Ladevorgang" => {values => ":slider,1,1,100", level => 0}, + #"Param_Ende_Ladevorgang" => {values => "", will be calculated with Param_Dauer_Ladevorgang but could also be set an Param_Dauer_Ladevorgang will be calculated + + #advanced + "Param_Minimale_Schaltdauer_Relais" => {values => ":slider,0,5,600", level => 1}, + "Param_Trennung_nach_Vollladung" => {values => ":ja,nein", level => 1}, + "Param_Ladebereitschaft_bis_Trennung" => {values => "", level => 1}, + "Param_Betrieb_mit_Netzanschlusspunktzaehler" => {values => ":ja,nein", level => 1}, + "Param_Nennstrom_Netzanschluss" => {values => ":slider,0,1,100", level => 1}, + "Param_Nennwirkleistung_WMaxOut" => {values => ":slider,1380,230,22000", level => 1}, + "Param_Nennwirkleistung_WMaxIn" => {values => ":slider,1380,230,22000", level => 1}, + "Param_Maximale_Schieflast" => {values => ":slider,0,230,10000", level => 1}, + "Param_Fallback_Wirkleistungsbegrenzung" => {values => ":slider,0,230,22000", level => 1}, + + #expert + "Param_Timeout_nach_Kommunikationsverlust" => {values => ":slider,200,100,60000", level => 2}, + "Param_IGMP_Query_Intervall" => {values => ":slider,11,10,31744", level => 2}, + "Param_Auto_Update_an" => {values => ":ja,nein", level => 2}, + "Param_Geraeteneustart_ausloesen" => {values => ":---,Ausführen", level => 2}, + "Param_WLAN_suchen" => {values => ":---,Scan-durchführen", level => 2}, + "Param_WPS_aktivieren" => {values => ":---,WPS-aktivieren", level => 2}, + "Param_WLAN_eingeschaltet" => {values => ":ja,nein", level => 2}, + "Param_Verschluesselung_WLAN" => {values => ":WPA2-MIXED,WPA,WPA2", level => 2}, + "Param_WLAN-Passwort" => {values => "", level => 2}, + "Param_SSID_WLAN" => {values => "", level => 2}, + "Param_Soft_Access_Point_an" => {values => ":ja,nein", level => 2}, + ); + + +my %reading_codes = ( + "Optimiertes_Laden" => "4719", + "Laden_mit_Vorgabe" => "4720", + "Schnellladen" => "4718", + "Ladestopp" => "4721", + "ja" => "1129", + "nein" => "1130", + "nicht verbunden" => "200111", + "verbunden" => "200112", + "Ladevorgang aktiv" => "200113", + "Phase L1 L2 L3" => "326", + "---" => "302", + "Ok" => "307", + "Ein" => "308", + "Ausführen" => "1146", + "Scan-durchführen" => "3342", + "WPS-aktivieren" => "3321", + "WPA" => "3323", + "WPA2" => "3324", + "WPA2-MIXED" => "3398", + "intelligente Ladung" => "4950" + ); + +############################################################### +# SMAEVCharger getReadableCode +############################################################### +sub SMAEVCharger_getReadableCode($) +{ + my ($code) = @_; + + if(defined($code)) + { + foreach my $key (keys %reading_codes) + { + if($reading_codes{$key} eq $code) + { + return $key; + } + } + + return $code; + } + else + { + return ''; + } +} + +############################################################### +# SMAEVCharger getReadingCode +############################################################### +sub SMAEVCharger_getReadingCode($) +{ + my ($readable_code) = @_; + + if(defined($reading_codes{$readable_code})) + { + return $reading_codes{$readable_code}; + } + else + { + return $readable_code; + }; +} + + +############################################################### +# SMAEVCharger checkPossibleValue +############################################################### +sub SMAEVCharger_checkPossibleValues($$$) +{ + my ($name, $reading,$val) = @_; + + my $return = undef; + + Log3 $name, 4, "$name -> Check if values are in range"; + + if ($reading eq "Param_Betriebsart_Ladevorgang" and $val == 4720 and + (ReadingsVal($name,"Param_Dauer_Ladevorgang", "0") == 0 + or ReadingsVal($name,"Param_Energiemenge_Ladevorgang", "0") == 0 + or ReadingsVal($name,"Status_Ladevorgang", "nicht verbunden") eq 'nicht verbunden')) + { + if(ReadingsVal($name,"Status_Ladevorgang", "nicht verbunden") eq 'nicht verbunden') + { + $return = "Car is not connected to the charger"; + } + else + { + $return = "Please first set values Param_Energiemenge_Ladevorgang and Param_Dauer_Ladevorgang"; + } + } + elsif ((my $min = ReadingsVal($name,".".$reading."_min", "ERR")) ne "ERR") + { + Log3 $name, 4, "$name -> Check for min / max:".$reading.":".$val." min=".$min; + + if ($val >= $min and $val <= ReadingsVal($name,".".$reading."_max", 0)) + { + $return = undef; + } + else + { + $return = "Value not allowed! Possible Values must be between: ".$min." and ".ReadingsVal($name,".".$reading."_max", 0); + } + } + elsif ((my $possibleValues = ReadingsVal($name,".".$reading."_possibleValues", "ERR")) ne "ERR") + { + #Log3 $name, 4, "$name -> Check for array for ".$reading.":".$val; + $return = "Value not allowed! Possible Values: ".$possibleValues; + #Log3 $name, 4, "$name -> Check for array possible values:".$possibleValues; + + my @possibleValues = split('; ',$possibleValues); + + foreach my $tmp (@possibleValues){ + $return = undef if ($val == $tmp); + } + } + + return $return; +} + + +############################################################### +# SMAEVCharger getCurlcmd +############################################################### +sub SMAEVCharger_getCurlcmd($$;$) +{ + # get the curlcmd infos for the api call + my ($hash, $api, $data) = @_; + + # get all basic infos for the curl command + my $baseurl = $hash->{HELPER}{BASEURL}; + my $curlcmd = ""; + my $url = ""; + my $special_header = ""; + my $cmd_call = "curl -i -s -k -X "; + my $method = "'POST' "; + my $header = "-H 'Host: $hash->{HOST}' -H 'Connection: close' -H 'Accept: application/json, text/plain, */*' -H 'User-Agent: okhttp/3.10.0' -H 'Sec-Fetch-Site: same-origin' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Dest: empty' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7' "; + my $cookies = "-b '$hash->{HELPER}{SESSIONID}' "; + my $token = "-H 'Authorization: Bearer $hash->{HELPER}{ACCESS_TOKEN}' " if (defined($hash->{HELPER}{ACCESS_TOKEN})); + my $len_corr = 0; # maybe there are chars in data which should not be count for header content_len + + Log3 $hash->{NAME}, 5, "$hash->{NAME} -> SMAEVCgarger_getCurlcmd"; + + #correct string len with count of masking char \ + if (defined ($data)) + { + $len_corr = () = $data =~ /\\/g; + } + + # check wich command we have to build + if ($api eq "login") + { + $url = $baseurl."/api/v1/token"; + my $content_len = length($data) - $len_corr; + $data = "--data-binary '$data' "; + $special_header = "-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' -H 'Content-Length: $content_len' -H 'Origin: $baseurl' -H 'Referer: $baseurl/webui/login' "; + $cookies = ""; + $token = ""; + } + elsif ($api eq "refresh_token") + { + my $refresh_token = $hash->{HELPER}{REFRESH_TOKEN}; + $url = $baseurl."/api/v1/token"; + $data = "grant_type=refresh_token&refresh_token=$refresh_token "; + my $content_len = length($data); + $data = " --data-binary '$data' "; + $special_header = "-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' -H 'Content-Length: $content_len' -H 'Origin: $baseurl' -H 'Referer: $baseurl/webui/login' "; + } + elsif ($api eq "livedata") + { + $url = $baseurl.'/api/v1/measurements/live/'; + $data = '[{"componentId":"IGULD:SELF"}]'; # cmd to get live data from wallbox + my $content_len = length($data); + $data = "--data-binary '$data' "; + $special_header = "-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' -H 'Content-Length: $content_len' -H 'Referer: $baseurl/webui/login' "; + } + elsif ($api eq "read_params") + { + $url = $baseurl.'/api/v1/parameters/search/'; + my $content_len = length($data) - $len_corr; + $data = "--data-binary '$data' "; + $special_header = "-H 'Content-Type: application/json' -H 'Content-Length: $content_len' -H 'Referer: $baseurl/webui/Plant:1,IGULD:SELF/configuration/view-parameters' "; + } + elsif ($api eq "write_params") + { + $url = $baseurl.'/api/v1/parameters/IGULD:SELF'; + my $content_len = length($data); + $data = "--data-binary '$data' "; + $special_header = "-H 'Content-Type: application/json' -H 'Content-Length: $content_len' -H 'Referer: $baseurl/webui/Plant:1,IGULD:SELF/configuration/view-parameters' "; + $method = "'PUT' "; + + #my $curlcmd = "curl -i -s -k -X 'PUT' -H 'Host: $host' -H 'Connection: close' -H 'Content-Length: $content_len' -H 'Accept: application/json, text/plain, */*' -H 'Authorization: Bearer $access_token' -H 'User-Agent: okhttp/3.10.0' -H 'Content-Type: application/json' -H 'Origin: $baseurl' -H 'Sec-Fetch-Site: same-origin' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Dest: empty' -H 'Referer: $baseurl/webui/Plant:1,IGULD:SELF/configuration/view-parameters' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7' -b 'JSESSIONID=$cookies' --data-binary '$data' '$baseurl/api/v1/parameters/IGULD:SELF'"; + } + elsif ($api eq "easyget") + { + $url = $baseurl.'/api/v1/plants/Plant:1'; + $special_header = "-H 'Referer: $baseurl/webui/Plant:1/dashboard' "; + $method = "'GET' "; + $data = " "; + } + else + { + $cmd_call = ""; + } + + if ($cmd_call ne "") + { + $curlcmd = $cmd_call.$method.$header.$special_header.$token.$cookies.$data.$url; + } + else + { + $curlcmd = ""; + } + + return $curlcmd; +} + + +############################################################### +# SMAEVCharger Initialize +############################################################### +sub SMAEVCharger_Initialize($) +{ + my ($hash) = @_; + + $hash->{DefFn} = "SMAEVCharger_Define"; + $hash->{UndefFn} = "SMAEVCharger_Undef"; + $hash->{GetFn} = "SMAEVCharger_Get"; + $hash->{SetFn} = "SMAEVCharger_Set"; + $hash->{AttrList} = "interval " . + "disable:1,0 " . + "detail-level:0,1,2 " . + "setting-level:0,1,2 " . + $readingFnAttributes; + $hash->{AttrFn} = "SMAEVCharger_Attr"; + + return; +} + +############################################################### +# SMAEVCharger Define +############################################################### +sub SMAEVCharger_Define($$) +{ + my ($hash, $def) = @_; + my @a = split("[ \t][ \t]*", $def); + + return "Error: Perl module ".$MissModulDateTime." is missing. + Install it on Debian with: sudo apt-get install libdatetime-perl" if($MissModulDateTime); + + return "Wrong syntax: use define SMAEVCharger " if ((int(@a) < 5) and (int(@a) > 6)); + + my $name = $hash->{NAME}; + $hash->{LASTUPDATE} = 0; + $hash->{INTERVAL} = $hash->{HELPER}{INTERVAL} = AttrVal($name, "interval", 60); + $hash->{HELPER}{SESSIONID} = ""; + $hash->{HELPER}{ACCESS_TOKEN} = ""; + $hash->{HELPER}{REFRESH_TOKEN} = ""; + $hash->{HELPER}{EXPIRE_TOKEN} = 0; + + my ($Host); + + my $User = $a[3]; + my $Pass = $a[4]; #todo evtl. verschlüsseln und mit set befehl änderbar machen? + + # extract IP or Hostname from $a[4] + if (!defined $Host) + { + #if ( $a[2] =~ /^([A-Za-z0-9_.])/ ) + # Test if IP + if ($a[2] =~ /^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$/) + { + $Host = $a[2]; + + # extract protocol if in definition + my ($protocoll, $ip) = $Host =~m/(https:\/\/)(.*)/; + if($protocoll){ $Host = $ip; }; + + $hash->{HELPER}{BASEURL} = "https://".$Host; + } + } + + if (!defined $Host) + { + return "Argument:{$a[2]} not accepted as Host or IP. Read device specific help file."; + } + + $hash->{USER} = $User; + $hash->{PASS} = $Pass; + $hash->{HOST} = $Host; + + InternalTimer(gettimeofday()+5, "SMAEVCharger_GetData", $hash, 0); # Start Hauptroutine + + return undef; +} + +############################################################### +# SMAEVCharger Undefine +############################################################### +sub SMAEVCharger_Undef($$) +{ + my ($hash, $name) = @_; + RemoveInternalTimer($hash); + BlockingKill($hash->{HELPER}{RUNNING_PID}); + return undef; +} + +############################################################### +# SMAEVCharger Get +############################################################### +sub SMAEVCharger_Get($$) +{ + my ($hash, @a) = @_; + return "\"get X\" needs at least an argument" if ( @a < 2 ); + my $name = shift @a; + my $opt = shift @a; + + my $getlist = "Unknown argument $opt, choose one of ". + "data:noArg "; + + return "module is disabled" if(IsDisabled($name)); + + if ($opt eq "data") + { + SMAEVCharger_GetData($hash); + } + else + { + return "$getlist"; + } + return undef; +} + +############################################################### +# SMAEVCharger Set +############################################################### + +sub SMAEVCharger_Set($$@) +{ + my ($hash, $name, $cmd, $val) = @_; + return "\"set $name\" needs at least one argument" unless(defined($cmd)); + my $resultStr = ""; + my @cList; + my $setting_level = AttrVal($name, "setting-level", 0); + + push(@cList, " "); + + foreach my $key (keys(%update_readings)) + { + if( $update_readings{$key}{level} <= $setting_level ) + { + push(@cList, $key.$update_readings{$key}{values}); + } + } + + my $return = "Unknown argument $cmd, choose one of " . join(" ", @cList); + + return $return if $cmd eq '?'; + + if(join(" ", @cList) =~ m/$cmd/) + { + Log3 $name, 5, "$name - Set command exists:".$cmd; + + $return = SMAEVCharger_SMAcmd($hash, $cmd, $val); + } + + return $return; +} + + +############################################################### +# SMAEVCharger Attr +############################################################### +sub SMAEVCharger_Attr(@) +{ + my ($cmd,$name,$aName,$aVal) = @_; + # $cmd can be "del" or "set" + # $name is device name + # aName and aVal are Attribute name and value + my $hash = $defs{$name}; + my $do; + + if ($aName eq "disable") + { + if($cmd eq "set") + { + $do = ($aVal) ? 1 : 0; + } + $do = 0 if($cmd eq "del"); + my $val = ($do == 1 ? "disabled" : "initialized"); + + readingsSingleUpdate($hash, "state", $val, 1); + + if ($do == 0) + { + RemoveInternalTimer($hash); + InternalTimer(time+5, 'SMAEVCharger_GetData', $hash, 0); + } + else + { + RemoveInternalTimer($hash); + } + } + + if ($aName eq "detail-level") { + if ($cmd eq "set" and AttrVal($name,"setting-level", 0) > $aVal) + { + + return "ERROR: first set setting-level because detail-level must be >= setting-level"; + } + else + { + delete $defs{$name}{READINGS}; + RemoveInternalTimer($hash); + InternalTimer(time+5, 'SMAEVCharger_GetData', $hash, 0); + } + } + + if ($aName eq "setting-level") { + + if ($cmd eq "set" and AttrVal($name,"detail-level", 0) < $aVal) + { + return "ERROR: for higher setting-level attribute detail-level must have same or higher level"; + } + else + { + delete $defs{$name}{READINGS}; + RemoveInternalTimer($hash); + InternalTimer(time+5, 'SMAEVCharger_GetData', $hash, 0); + } + } + + + if ($aName eq "interval") + { + if ($cmd eq "set") + { + $hash->{HELPER}{INTERVAL} = $aVal; + $hash->{INTERVAL} = $aVal; + Log3 $name, 3, "$name - Set $aName to $aVal"; + } else + { + $hash->{INTERVAL} = $hash->{HELPER}{INTERVAL} = 60; + } + } + + + return; +} + +############################################################### +# Main Loop - Get Data from EV Charger +############################################################### +sub SMAEVCharger_GetData($) +{ + my ($hash) = @_; + my $name = $hash->{NAME}; + my $interval = AttrVal($name, "interval", 60); + + RemoveInternalTimer($hash, "SMAEVCharger_GetData"); + + if ($init_done != 1) + { + InternalTimer(gettimeofday()+5, "SMAEVCharger_GetData", $hash, 0); + return; + } + + return if(IsDisabled($name)); + + if (exists($hash->{HELPER}{RUNNING_PID})) + { + Log3 ($name, 4, "SMAEVCharger $name - WARNING - old process $hash->{HELPER}{RUNNING_PID}{pid} will be killed now to start a new BlockingCall"); + BlockingKill($hash->{HELPER}{RUNNING_PID}); + } + + Log3 ($name, 3, "$name - ########## SMAEVCharger get all data ##########"); + + # do operation + InternalTimer(gettimeofday()+$interval, "SMAEVCharger_GetData", $hash, 0); + + $hash->{HELPER}{RUNNING_PID} = BlockingCall("SMAEVCharger_Run", "$name", "SMAEVCharger_Done", 60, "SMAEVCharger_Aborted", $hash); + $hash->{HELPER}{RUNNING_PID}{loglevel} = 4; + + return; +} + +############################################################### +# non-blocking EVCharger data transfer +############################################################### +sub SMAEVCharger_Run($) +{ + my ($name) = @_; + my $hash = $defs{$name}; + my $interval = AttrVal($name, "interval", 60); + my $response = ""; + my $code = 0; + my $ret = 0; + + Log3 ($name, 4, "$name -> Start BlockingCall SMAEVCharger_Run"); + + # login to EV Charger + if(SMAEVCharger_SMAlogon($hash->{HOST}, $hash->{PASS},$hash->{USER}, $hash)) + { + Log3 $name, 4, "$name - login succes / start getting live data"; + + my $baseurl = $hash->{HELPER}{BASEURL}; + my $host = $hash->{HOST}; + my $cookies = $hash->{HELPER}{SESSIONID}; + my $access_token = $hash->{HELPER}{ACCESS_TOKEN}; + my $url = $baseurl.'/api/v1/measurements/live/'; + my $data = '\'[{"componentId":"IGULD:SELF"}]\''; # cmd to get live data from wallbox + + my $curlcmd = SMAEVCharger_getCurlcmd($hash, "livedata"); + Log3 $name, 5, "$name - Curl cmd livedata: ".$curlcmd; + + $response = `$curlcmd`; + my ($head,$body) = split( m{\r?\n\r?\n}, $response,2 ); + ($code) = $head =~m{\A\S+ (\d+)}; + + if($code == 200) # all ok for live data + { + Log3 $name, 5, "$name - Actual Live Data: ".$body; + $response = $body; + $ret = 1; + + #if live data is ok we should also get param data + + $url = $baseurl.'/api/v1/parameters/search/'; + $data = '{"queryItems":[{"componentId":"IGULD:SELF"}]}'; # cmd to get params + $access_token = $hash->{HELPER}{ACCESS_TOKEN}; + + $curlcmd = SMAEVCharger_getCurlcmd($hash, "read_params", $data); + + Log3 $name, 5, "$name - Curl cmd to read param: ".$curlcmd; + + my $response_param = `$curlcmd`; + my ($head,$body) = split( m{\r?\n\r?\n}, $response_param,2 ); + ($code) = $head =~m{\A\S+ (\d+)}; + + if($code == 200) # all ok for param data + { + Log3 $name, 5, "$name - Parameter: ".$body; + $response = $response.'|'.$body; + } + else + { + Log3 $name, 3, "$name - Parameter Error: ".$code; + $response = $response.'|[{"componentId":"ERR"}]'; + + Log3 $name, 5, "$name Response in Error: ".$response; + } + } + else + { + #todo err handling + Log3 $name, 3, "$name - Actual Live Data Error: ".$code; + $response = "Error: Get Data with code:".$code; + $ret = 0; + } + } + else + { + Log3 $name, 3, "$name - Login failed"; + $response = "Error: Login with code:".$code; + $ret = 0; + } + + # all data received + #SMAEVCharger_SMAlogout($hash,$hash->{HOST}); + + # store session info for blocking call parent + my $session_info = encode_base64($hash->{HELPER}{SESSIONID}."|".$hash->{HELPER}{ACCESS_TOKEN}."|".$hash->{HELPER}{REFRESH_TOKEN}."|".$hash->{HELPER}{EXPIRE_TOKEN},""); + + $response = encode_base64($response,""); + + Log3 ($name, 4, "$name -> BlockingCall SMAEVCharger_Run finished"); + + return "$name|$ret|$session_info|$response"; +} + +############################################################### +# Helper to change readings into user readable names +############################################################### +sub SMAEVCharger_handledata($$$) +{ + my ($hash, $data, $param) = @_; + my $name = $hash->{NAME}; + + # Get the current detail-level attribute + my $detail_level = AttrVal($name, "detail-level", 0); + + my $livedata->{"Measurement.ChaSess.WhIn"} = "Energie_Ladevorgang"; # in Wh + $livedata->{"Measurement.Chrg.ModSw"} = "Schalterstellung_Drehschalter"; + $livedata->{"Measurement.GridMs.A.phsA"} = "Netzstrom_Phase_L1"; + $livedata->{"Measurement.GridMs.A.phsB"} = "Netzstrom_Phase_L2"; + $livedata->{"Measurement.GridMs.A.phsC"} = "Netzstrom_Phase_L3"; + $livedata->{"Measurement.GridMs.PhV.phsA"} = "Netzspannung_Phase_L1"; + $livedata->{"Measurement.GridMs.PhV.phsB"} = "Netzspannung_Phase_L2"; + $livedata->{"Measurement.GridMs.PhV.phsC"} = "Netzspannung_Phase_L3"; + $livedata->{"Measurement.Metering.GridMs.TotWIn"} = "Leistung_Bezug"; # in W + $livedata->{"Measurement.Metering.GridMs.TotWIn.ChaSta"} = "Leistung_Ladestation"; # in W + $livedata->{"Measurement.Metering.GridMs.TotWhIn"} = "Zaehlerstand_Bezugszaehler"; # in Wh + $livedata->{"Measurement.Metering.GridMs.TotWhIn.ChaSta"} = "Zaehlerstand_Ladestation"; #in Wh + $livedata->{"Measurement.Operation.EVeh.ChaStt"} = "Status_Ladevorgang"; # 200111 -> nicht verbunden, 200112 -> verbunden 200113 -> wird geladen + $livedata->{"Measurement.Operation.EVeh.Health"} = "Status_verbundenes_Fahrzeug"; # 307 -> "Ok" + $livedata->{"Measurement.Operation.Evt.Msg"} = "Status_Meldung"; # 302 -> "ok" ? + $livedata->{"Measurement.Operation.Health"} = "Status_Zustand"; # 307 -> "Ok" + $livedata->{"Setpoint.PlantControl.Inverter.FstStop"} = "Schnellabschaltung"; # 1467 -> "Start" + + # advanced infos + if ($detail_level > 0) + { + $livedata->{"Measurement.GridMs.Hz"} = "Netzfrequenz"; + $livedata->{"Measurement.GridMs.TotPF"} = "Verschiebungsfaktor"; + $livedata->{"Measurement.GridMs.TotVA"} = "Scheinleistung"; + $livedata->{"Measurement.GridMs.TotVAr"} = "Blindleistung"; + $livedata->{"Measurement.Wl.AcqStt"} = "Status_WLAN_Scan"; + $livedata->{"Measurement.Wl.ConnStt"} = "Status_WLAN_Verbindung"; # 1725 -> keine Verbindung + $livedata->{"Measurement.Wl.SigPwr"} = "Signalstaerke_Netzwerk"; + } + + # expert infos + if ($detail_level > 1) + { + $livedata->{"Measurement.InOut.GI1"} = "digitaler_Gruppeneingang"; + $livedata->{"Measurement.Operation.WMaxLimSrc"} = "Digitaler_Eingang"; # eigentlich uninteressant + $livedata->{"Measurement.Wl.SoftAcsConnStt"} = "Status_Soft_Access_Point"; # 308 -> "Ein" + } + + my $readings = { "Measurement.ChaSess.WhIn" => "Energie_Ladevorgang", # in Wh + "Measurement.GridMs.A.phsA" => "Netzstrom_Phase_L1", + "Measurement.GridMs.A.phsB" => "Netzstrom_Phase_L2", + "Measurement.GridMs.A.phsC" => "Netzstrom_Phase_L3", + "Measurement.GridMs.Hz" => "Netzfrequenz", + "Measurement.GridMs.PhV.phsA" => "Netzspannung_Phase_L1", + "Measurement.GridMs.PhV.phsB" => "Netzspannung_Phase_L2", + "Measurement.GridMs.PhV.phsC" => "Netzspannung_Phase_L3", + "Measurement.GridMs.TotPF" => "Verschiebungsfaktor", + "Measurement.GridMs.TotVA" => "Scheinleistung", + "Measurement.GridMs.TotVAr" => "Blindleistung", + "Measurement.InOut.GI1" => "digitaler_Gruppeneingang", + "Measurement.Metering.GridMs.TotWIn" => "Leistung_Bezug", # in W + "Measurement.Metering.GridMs.TotWIn.ChaSta" => "Leistung_Ladestation", # in W + "Measurement.Metering.GridMs.TotWhIn" => "Zaehlerstand_Bezugszaehler", # in Wh + "Measurement.Metering.GridMs.TotWhIn.ChaSta" => "Zaehlerstand_Ladestation", #in Wh + "Measurement.Operation.EVeh.ChaStt" => "Status_Ladevorgang", # 200111 -> nicht verbunden, 200112 -> verbunden 200113 -> wird geladen + "Measurement.Operation.EVeh.Health" => "Status_verbundenes_Fahrzeug", # 307 -> "Ok" + "Measurement.Operation.Evt.Msg" => "Status_Meldung", # 302 -> "ok" ? + "Measurement.Operation.Health" => "Status_Zustand", # 307 -> "Ok" + "Measurement.Operation.WMaxLimSrc" => "Digitaler_Eingang", # eigentlich uninteressant + "Measurement.Wl.AcqStt" => "Status_WLAN_Scan", + "Measurement.Wl.ConnStt" => "Status_WLAN_Verbindung", # 1725 -> keine Verbindung + "Measurement.Wl.SigPwr" => "Signalstaerke_Netzwerk", + "Measurement.Wl.SoftAcsConnStt" => "Status_Soft_Access_Point", # 308 -> "Ein" + "Setpoint.PlantControl.Inverter.FstStop" => "Schnellabschaltung" # 1467 -> "Start" + }; + + # basic params + my $params->{"Parameter.Chrg.ActChaMod"} = "Param_Betriebsart_Ladevorgang"; + $params->{"Parameter.Chrg.AMinCha"} = "Param_Minimaler_Ladestrom"; + $params->{"Parameter.Chrg.Plan.DurTmm"} = "Param_Dauer_Ladevorgang"; + $params->{"Parameter.Chrg.Plan.En"} = "Param_Energiemenge_Ladevorgang"; + $params->{"Parameter.Chrg.Plan.StopTm"} = "Param_Ende_Ladevorgang"; + $params->{"Parameter.Chrg.StpWhenFl"} = "Param_Trennung_nach_Vollladung"; + $params->{"Parameter.Chrg.StpWhenFlTm"} = "Param_Ladebereitschaft_bis_Trennung"; + $params->{"Parameter.GridGuard.Cntry.VRtg"} = "Param_Netz_Nennspannung"; + $params->{"Parameter.PCC.ARtg"} = "Param_Nennstrom_Netzanschluss"; + $params->{"Parameter.PCC.FlbInv.WMax"} = "Param_Fallback_Wirkleistungsbegrenzung"; + + + + + # advanced params + if ($detail_level > 0) + { + $params->{"Parameter.Chrg.MinSwTms"} = "Param_Minimale_Schaltdauer_Relais"; + $params->{"Parameter.Chrg.UseEnergyMeter"} = "Param_Betrieb_mit_Netzanschlusspunktzaehler"; + $params->{"Parameter.Inverter.WMax"} = "Param_Nennwirkleistung_WMaxOut"; + $params->{"Parameter.Inverter.WMaxIn"} = "Param_Nennwirkleistung_WMaxIn"; + $params->{"Parameter.Inverter.WMaxInRtg"} = "Param_Bemessungswirkleistung_WMaxInRtg"; + $params->{"Parameter.Nameplate.ARtg"} = "Param_Nennstrom_alle_Phasen"; + $params->{"Parameter.Nameplate.Location"} = "Param_Geraetename"; + $params->{"Parameter.PCC.WMaxAsym"} = "Param_Maximale_Schieflast"; + + } + + # expert params + if ($detail_level > 1) + { + $params->{"Parameter.Spdwr.IgmpQryTms"} = "Param_IGMP_Query_Intervall"; + $params->{"Parameter.Spdwr.IgmpQryTx"} = "Param_IGMP_Anfragen_senden"; + $params->{"Parameter.Upd.AutoUpdIsOn"} = "Param_Auto_Update_an"; + $params->{"Parameter.DevUpd.IsOn"} = "Param_Geraete_Update_ein"; + $params->{"Parameter.Inverter.OutPhs"} = "Param_Phasenzuordnung"; + $params->{"Parameter.Nameplate.ChrgCtrl.ChrgTypTxt"} = "Param_Typ_Ladecontroller"; + $params->{"Parameter.Nameplate.ChrgCtrl.SerNumTxt"} = "Param_Seriennummer_Ladecontrollers"; + $params->{"Parameter.Nameplate.ChrgCtrl.SusyId"} = "Param_SusyID_Ladecontrollers"; + $params->{"Parameter.Nameplate.ChrgCtrl.SwRevTxt"} = "Param_SWVersion_Ladecontroller"; + $params->{"Parameter.Nameplate.CmpMain.HwRev"} = "Param_HWVersion_Hauptprozessor"; + $params->{"Parameter.Nameplate.CmpMain.Rev"} = "Param_Umbaustand_Hauptprozessor"; + $params->{"Parameter.Nameplate.CmpMain.SerNum"} = "Param_Seriennummer_Hauptprozessor"; + $params->{"Parameter.Nameplate.CmpMain.SusyId"} = "Param_SUSyID_Hauptprozessor"; + $params->{"Parameter.Nameplate.CmpOS.SwRev"} = "Param_Firmware_Version_Betriebssystem"; + $params->{"Parameter.Nameplate.MacId"} = "Param_MAC-Adresse"; + $params->{"Parameter.Nameplate.MainModel"} = "Param_Geraeteklasse"; + $params->{"Parameter.Nameplate.Model"} = "Param_Geraetetyp"; + $params->{"Parameter.Nameplate.ModelStr"} = "Param_Typenbezeichnung"; + $params->{"Parameter.Nameplate.PkgRev"} = "Param_Softwarepaket"; + $params->{"Parameter.Nameplate.SerNum"} = "Param_Seriennummer"; + $params->{"Parameter.Nameplate.Vendor"} = "Param_Hersteller"; + $params->{"Parameter.Nameplate.WlMacId"} = "Param_WLAN_MAC"; + $params->{"Parameter.Operation.ComTmOut"} = "Param_Timeout_nach_Kommunikationsverlust"; + $params->{"Parameter.Spdwr.ActlDnsSrvIp"} = "Param_Akt_Speedwire_Serveradresse"; + $params->{"Parameter.Spdwr.ActlGwIp"} = "Param_Akt_Speedwire_Gateway"; + $params->{"Parameter.Spdwr.ActlIp"} = "Param_Akt_Speedwire_IP"; + $params->{"Parameter.Spdwr.ActlSnetMsk"} = "Param_Akt_Speedwire_Subnetzmaske"; + $params->{"Parameter.Spdwr.AutoCfgIsOn"} = "Automatische_Speedwire-Konfig_an"; + $params->{"Parameter.SwCmp.CmpEnnexOS.Frwk.SwRev"} = "Param_ennexOS_Framework_Version"; + $params->{"Parameter.Sys.DevRstr"} = "Param_Geraeteneustart_ausloesen"; + $params->{"Parameter.Upd.AvalChkIstl"} = "Param_Auto_Speedwire_Konfig_an"; + $params->{"Parameter.Wl.ActlDnsSrvIp"} = "Aktuelle_Speedwire-DNS-Serveradresse"; + $params->{"Parameter.Wl.ActlGwIp"} = "Param_IP_Gateway_WLAN"; + $params->{"Parameter.Wl.ActlIp"} = "Param_IP_WLAN"; + $params->{"Parameter.Wl.ActlSnetMsk"} = "Param_IP_Subnetz_WLAN"; + $params->{"Parameter.Wl.AutoCfgIsOn"} = "Param_Auto_Update_an"; + $params->{"Parameter.Wl.DoAcq"} = "Param_WLAN_suchen"; + $params->{"Parameter.Wl.DoWPS"} = "Param_WPS_aktivieren"; + $params->{"Parameter.Wl.ExsNetw[]"} = "Param_Gefundenes_WLAN"; + $params->{"Parameter.Wl.IsOn"} = "Param_WLAN_eingeschaltet"; + $params->{"Parameter.Wl.Sec.Cry"} = "Param_Verschluesselung_WLAN"; + $params->{"Parameter.Wl.Sec.Psk"} = "Param_WLAN-Passwort"; + $params->{"Parameter.Wl.Sec.Ssid"} = "Param_SSID_WLAN"; + $params->{"Parameter.Wl.SoftAcsIsOn"} = "Param_Soft_Access_Point_an"; + } + + + # Update Live Data Readings + my $json = decode_json( $data ); + + foreach my $item ( @$json ) + { + my $val = SMAEVCharger_getReadableCode($item->{"values"}->[0]->{"value"}); + + #old readingsBulkUpdate($hash, $readings->{$item->{"channelId"}} , $val); + readingsBulkUpdate($hash, $livedata->{$item->{"channelId"}} , $val); + + if(defined($livedata->{$item->{"channelId"}})) + { + Log3 $name, 5, "$name - Livedata:".$item->{"channelId"}." Reading:".$livedata->{$item->{"channelId"}}." Wert:".$val; + } + + #Log3 $name, 5, "$name - Readings Update:".$item->{"channelId"}." Reading:".$readings->{$item->{"channelId"}}." Wert:".$val; + } + + Log3 $name, 4, "$name - Loop Readings update done"; + + # Update Param Readings + $json = decode_json( $param ); + + # only if param is from the charger + if ($json->[0]->{"componentId"} eq "IGULD:SELF") + { + $json = $json->[0]->{values}; + + foreach my $item ( @$json ) + { + if(defined($item->{"channelId"})) + { + #read possible values: + if(defined($item->{"min"})) + { + # save as non visible reading + Log3 $name, 4, "$name - Readings Update possible Values: min=".$item->{"min"}." max=".$item->{"max"}; + if(defined($params->{$item->{"channelId"}})) + { + readingsBulkUpdate($hash, ".".$params->{$item->{"channelId"}}."_min" , $item->{"min"}); + readingsBulkUpdate($hash, ".".$params->{$item->{"channelId"}}."_max" , $item->{"max"}); + } + } + + if(defined($item->{"possibleValues"})) + { + # save as non visible reading + + Log3 $name, 4, "$name - Readings Update possible Values:".join("; ",@{$item->{"possibleValues"}}); + if(defined($params->{$item->{"channelId"}})) + { + readingsBulkUpdate($hash, ".".$params->{$item->{"channelId"}}."_possibleValues" , join("; ",@{$item->{"possibleValues"}})); + } + } + + if ($item->{"channelId"} eq "Parameter.Chrg.Plan.StopTm") + { + my $time = FmtDateTime($item->{"value"}); + readingsBulkUpdate($hash, $params->{$item->{"channelId"}} , $time); + } + else + { + my $val = SMAEVCharger_getReadableCode($item->{"value"}); + readingsBulkUpdate($hash, $params->{$item->{"channelId"}} , $val); + } + + if(defined($params->{$item->{"channelId"}})) + { + Log3 $name, 5, "$name - Readings Update:".$item->{"channelId"}.' Reading:'.$params->{$item->{"channelId"}}.' Wert:'.$item->{"value"}; + } + } + } + + Log3 $name, 4, "$name - Loop Params update done"; + + #calculate additional readings + SMAEVCharger_CalculateReadings($hash); + } + + return; +} + + +############################################################### +# Calculate Specials Readings which are not in Charger +############################################################### +sub SMAEVCharger_CalculateReadings ($) +{ + my ($hash) = @_; + my $name = $hash->{NAME}; + + + # Remember last plugin time + if($hash->{HELPER}{Status_Ladevorgang} eq "nicht verbunden" and ReadingsVal($name, "Status_Ladevorgang", "nicht verbunden") ne "nicht verbunden") + { + readingsBulkUpdate($hash, "Startzeit_Verbindung" , TimeNow()); + readingsBulkUpdate($hash, "Anzahl_Ladevorgaenge" , 0); + } + elsif(ReadingsVal($name, "Status_Ladevorgang", "nicht verbunden") eq "nicht verbunden") + { + readingsBulkUpdate($hash, "Startzeit_Verbindung" , "nicht verbunden"); + } + + # count charges since last plugin time, will be shown until next plugin + if($hash->{HELPER}{Status_Ladevorgang} eq "verbunden" and ReadingsVal($name, "Status_Ladevorgang", "") eq "Ladevorgang aktiv") + { + readingsBulkUpdate($hash, "Anzahl_Ladevorgaenge" , ReadingsNum($name, "Anzahl_Ladevorgaenge", "") + 1); + } +} + + +############################################################### +# Auswertung non-blocking Charger Datenabruf +############################################################### +sub SMAEVCharger_Done ($) +{ + my ($string) = @_; + return unless defined $string; + + my ($name, $success, $session_info, $data) = split("\\|", $string); + my $hash = $defs{$name}; + + Log3 ($name, 4, "$name -> Start BlockingCall SMAEVCharger_Done"); + + #save the actual session infos + $session_info = decode_base64($session_info); + ($hash->{HELPER}{SESSIONID}, $hash->{HELPER}{ACCESS_TOKEN}, $hash->{HELPER}{REFRESH_TOKEN},$hash->{HELPER}{EXPIRE_TOKEN}) = split("\\|", $session_info); + + #remember old values for calculating extra readings + $hash->{HELPER}{Status_Ladevorgang} = ReadingsVal($name, "Status_Ladevorgang", "nicht verbunden"); + + + + readingsBeginUpdate($hash); + + if ($success == 1) + { + $data = decode_base64($data); + my ($livedata, $param) = split("\\|", $data); + + # Get current time + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(); + $hash->{LASTUPDATE} = sprintf "%02d.%02d.%04d / %02d:%02d:%02d" , $mday , $mon+=1 ,$year+=1900 , $hour , $min , $sec ; + + #$livedata = decode_base64($livedata); + Log3 ($name, 5, "$name -> livedata after decoding:".$livedata); + + #$param = decode_base64($param); + Log3 ($name, 5, "$name -> param after decoding:".$param); + + SMAEVCharger_handledata($hash, $livedata, $param); + readingsBulkUpdate($hash, "state", "Data retrieved"); + } + else + { + readingsBulkUpdate($hash, "state", "Error retrieving data"); + Log3 ($name, 3, "$name - Error retrieving data"); + } + + readingsEndUpdate( $hash, 1 ); + + delete($hash->{HELPER}{RUNNING_PID}); + Log3 ($name, 4, "$name -> BlockingCall SMAEVCharger_Done finished"); + + return; +} + +############################################################### +# Abbruchroutine Timeout Charger Abfrage +############################################################### +sub SMAEVCharger_Aborted(@) +{ + my ($hash,$cause) = @_; + my $name = $hash->{NAME}; + $cause = $cause?$cause:"Timeout: process terminated"; + + Log3 ($name, 1, "SMAEVCgarger $name -> BlockingCall $hash->{HELPER}{RUNNING_PID}{fn} $cause"); + readingsSingleUpdate($hash,"state",$cause, 1); + + delete($hash->{HELPER}{RUNNING_PID}); + + return; +} + +########################################################################## +# SMA Command Execution +########################################################################## +sub SMAEVCharger_SMAcmd($$$) { + + my ($hash, $cmd, $value) = @_; + + my $baseurl = $hash->{HELPER}{BASEURL}; + my $host = $hash->{HOST}; + my $cookies = $hash->{HELPER}{SESSIONID}; + my $access_token = $hash->{HELPER}{ACCESS_TOKEN}; + my $url = $baseurl.'/api/v1/measurements/live/'; + my $name = $hash->{NAME}; + my $return = undef; + + # Get the current setting-level attribute + my $setting_level = AttrVal($name, "setting-level", 0); + + my $params->{"Param_Betriebsart_Ladevorgang"} = "Parameter.Chrg.ActChaMod"; + $params->{"Param_Minimaler_Ladestrom"} = "Parameter.Chrg.AMinCha"; + $params->{"Param_Dauer_Ladevorgang"} = "Parameter.Chrg.Plan.DurTmm"; + $params->{"Param_Energiemenge_Ladevorgang"} = "Parameter.Chrg.Plan.En"; + + + # advanced params + if ($setting_level > 0) + { + $params->{"Param_Minimale_Schaltdauer_Relais"} = "Parameter.Chrg.MinSwTms"; + $params->{"Param_Trennung_nach_Vollladung"} = "Parameter.Chrg.StpWhenFl"; + $params->{"Param_Ladebereitschaft_bis_Trennung"} = "Parameter.Chrg.StpWhenFlTm"; + $params->{"Param_Betrieb_mit_Netzanschlusspunktzaehler"} = "Parameter.Chrg.UseEnergyMeter"; + $params->{"Param_Nennstrom_Netzanschluss"} = "Parameter.PCC.ARtg"; + $params->{"Param_Nennwirkleistung_WMaxOut"} = "Parameter.Inverter.WMax"; + $params->{"Param_Nennwirkleistung_WMaxIn"} = "Parameter.Inverter.WMaxIn"; + $params->{"Param_Maximale_Schieflast"} = "Parameter.PCC.WMaxAsym"; + $params->{"Param_Fallback_Wirkleistungsbegrenzung"} = "Parameter.PCC.FlbInv.WMax"; + } + + # expert params + if ($setting_level > 1) + { + $params->{"Param_Timeout_nach_Kommunikationsverlust"} = "Parameter.Operation.ComTmOut"; + $params->{"Param_IGMP_Query_Intervall"} = "Parameter.Spdwr.IgmpQryTms"; + $params->{"Param_Auto_Update_an"} = "Parameter.Upd.AutoUpdIsOn"; + $params->{"Param_Geraeteneustart_ausloesen"} = "Parameter.Sys.DevRstr"; + $params->{"Param_WLAN_suchen"} = "Parameter.Wl.DoAcq"; + $params->{"Param_WPS_aktivieren"} = "Parameter.Wl.DoWPS"; + $params->{"Param_WLAN_eingeschaltet"} = "Parameter.Wl.IsOn"; + $params->{"Param_Verschluesselung_WLAN"} = "Parameter.Wl.Sec.Cry"; + $params->{"Param_WLAN-Passwort"} = "Parameter.Wl.Sec.Psk"; + $params->{"Param_SSID_WLAN"} = "Parameter.Wl.Sec.Ssid"; + $params->{"Param_Soft_Access_Point_an"} = "Parameter.Wl.SoftAcsIsOn"; + } + + Log3 $name, 5, "$name - PUT Parameter: ".$cmd." : ".$value; + + if (defined($params->{$cmd}) + and SMAEVCharger_SMAlogon($hash->{HOST}, $hash->{PASS}, $hash->{USER}, $hash)) + { + my $timestamp = POSIX::strftime("%Y-%m-%dT%H:%M:%S.000Z",gmtime()); + + if( $cmd eq "Param_Dauer_Ladevorgang" and $value =~ m/:/) + { + my ($hour, $min) = split(":",$value); + $value = $hour * 60 + $min; + } + + # if charging volume changes during predefined charging methode, set ending time correct + my $add_update = ""; + if ( $cmd eq "Param_Energiemenge_Ladevorgang" and ReadingsVal($name, "Param_Betriebsart_Ladevorgang", "") eq "Laden_mit_Vorgabe") + { + my $charging_stop = time_str2num(ReadingsVal($name, "Param_Ende_Ladevorgang","")); + $add_update = " ,{\"channelId\":\"Parameter.Chrg.Plan.StopTm\",\"timestamp\":\"$timestamp\",\"value\":$charging_stop}"; + } + + my $val = $value; + + if ( $reading_codes{$value} ) + { + $val = $reading_codes{$value}; + } + + #check if value is in range + if(! defined ($return = SMAEVCharger_checkPossibleValues($name, $cmd, $val))) + { + my $data = "{\"values\":[{\"channelId\":\"$params->{$cmd}\",\"timestamp\":\"$timestamp\",\"value\":\"$val\"}$add_update]}"; + my $content_len = length($data); + + Log3 $name, 4, "$name - PUT data: ".$data; + + + my $curlcmd = SMAEVCharger_getCurlcmd($hash, "write_params",$data); + + Log3 $name, 5, "$name - PUT data: ".$curlcmd; + + my $response = `$curlcmd`; + + my ($head,$body) = split( m{\r?\n\r?\n}, $response,2 ); + my ($code) = $head =~m{\A\S+ (\d+)}; + + Log3 $name, 4, "$name - PUT data response: ".$response; + + if ($code == 204) + { + readingsSingleUpdate($hash, $cmd, $value, 1); + $return = undef; + } + else + { + $return = "Error: Couldn't send Info to Charger"; + } + } + } + else + { + $return = "Error: Couldn't send Info to Charger"; + } + + return $return; +} + +########################################################################## +# Login +########################################################################## +sub SMAEVCharger_SMAlogon($$$$) +{ + # Parameters: host - passcode + my ($host,$pass, $user, $hash) = @_; + my $name = $hash->{NAME}; + my ($cmd, $timestmp, $myID, $target_ID, $spkt_ID, $cmd_ID); + + Log3 $name, 4, "$name - Starting login or refresh token process "; + + #Login / SessionID / Token + my $baseurl = "https://".$host; + my $url = $baseurl."/api/v1/token"; + my $content_len=length($user.$pass)+39; + my $data = 'grant_type=password&username='.$user.'&password='.$pass; + + # all things for handle the web calls + my $curlcmd = ""; + my $response = ""; + my $head = ""; + my $body = ""; + my $code = 200; + + # for now using curl because in trouble to get certificate verification with httputils-calls?! + # login call + + Log3 $name, 5, "$name - aktueller Token:".$hash->{HELPER}{ACCESS_TOKEN}.":" if (defined($hash->{HELPER}{ACCESS_TOKEN})); + + #first, look if we need to login + if (defined($hash->{HELPER}{ACCESS_TOKEN}) and $hash->{HELPER}{ACCESS_TOKEN} ne "") + { + if ((time()+300) > $hash->{HELPER}{EXPIRE_TOKEN}) # token will be expired + { + Log3 $name, 4, "$name - check for refresh token "; + + $curlcmd = SMAEVCharger_getCurlcmd($hash, "refresh_token"); + + Log3 $name, 5, "$name - Curlaufruf für refresh: ".$curlcmd; + $response = `$curlcmd`; + ($head,$body) = split( m{\r?\n\r?\n}, $response,2 ); + ($code) = $head =~m{\A\S+ (\d+)}; + + if ($code == 200) + { + $hash->{HELPER}{ACCESS_TOKEN} = $body->{"access_token"}; + $hash->{HELPER}{REFRESH_TOKEN} = $body->{"refresh_token"}; + $hash->{HELPER}{EXPIRE_TOKEN} = time() + $body->{"expires_in"}; + + Log3 $name, 5, "$name - new acess_token:".$hash->{HELPER}{ACCESS_TOKEN}; + Log3 $name, 5, "$name - new refresh_token:".$hash->{HELPER}{REFRESH_TOKEN}; + + Log3 $name, 4, "$name - got new access token"; + } + } + else + { + # check if we need to login + Log3 $name, 4, "$name - check for need of login "; + $curlcmd = SMAEVCharger_getCurlcmd($hash, "easyget"); + + Log3 $name, 5, "$name - Curlaufruf für get: ".$curlcmd; + $response = `$curlcmd`; + ($head,$body) = split( m{\r?\n\r?\n}, $response,2 ); + ($code) = $head =~m{\A\S+ (\d+)}; + + Log3 $name, 5, "$name - Ergebnis easy_get: ".$response; + } + } + else + { + $code = 401; + } + + if ($code != 200) # we need to login + { + Log3 $name, 4, "$name - try login to $host with user $user and password $pass "; + + $curlcmd = SMAEVCharger_getCurlcmd($hash, "login", $data); + + Log3 $name, 5, "$name - Curlaufruf: ".$curlcmd; + + $response = `$curlcmd`; + ($head,$body) = split( m{\r?\n\r?\n}, $response,2 ); + ($code) = $head =~m{\A\S+ (\d+)}; + + Log3 $name, 5, "$name - Curl Response Header: ".$head; + Log3 $name, 5, "$name - Curl Response Body: ".$body; + Log3 $name, 5, "$name - Curl Response Code: ".$code; + + if (defined $head && defined $body) + { + if ($code == 200) # login ok + { + my ($cookies) = $head =~m{JSESSIONID= ?(.*);}; + my ($sessionid, $othercookies) = split(/;/, $cookies,2); + + Log3 $name, 5, "$name - Cookies:".$cookies; + Log3 $name, 5, "$name - SessionID:".$sessionid; + + $body = decode_json($body); + $hash->{HELPER}{ACCESS_TOKEN} = $body->{"access_token"}; + $hash->{HELPER}{REFRESH_TOKEN} = $body->{"refresh_token"}; + $hash->{HELPER}{EXPIRE_TOKEN} = time() + $body->{"expires_in"}; + + # remember all things for the actual session login + $hash->{HELPER}{SESSIONID} = $sessionid; + + Log3 $name, 4, "$name - login success"; + } + else + { + # todo err handling + Log3 $name, 3, "$name - Curl Response Error Code:".$code.":"; + + $hash->{HELPER}{SESSIONID} = ""; + $hash->{HELPER}{ACCESS_TOKEN} = ""; + $hash->{HELPER}{REFRESH_TOKEN} = ""; + $hash->{HELPER}{EXPIRE_TOKEN} = 0; + + return 0; + } + } + else + { + Log3 $name, 3, "$name - Curl no header or body"; + + $hash->{HELPER}{SESSIONID} = ""; + $hash->{HELPER}{ACCESS_TOKEN} = ""; + $hash->{HELPER}{REFRESH_TOKEN} = ""; + $hash->{HELPER}{EXPIRE_TOKEN} = 0; + + return 0; + } + } + + return 1; +} + + + +########################################################################## +# Logout +########################################################################## +sub SMAEVCharger_SMAlogout($$) +{ + # Parameters: host + my ($hash,$host) = @_; + my $name = $hash->{NAME}; + + #todo + + return 1; +} + + +1; + +=pod +=item summary Integration of SMA EVChargers over it's Speedwire (=Ethernet) Interface +=item summary_DE Integration von SMA Wallboxen über Speedwire (=Ethernet) Interface + +=begin html + + +

SMAEVCharger

+ +Module for the integration of a SMA EVCharger over it's Speedwire (=Ethernet) Interface.
+Tested on SMA EV Charger 22 +

+ + + +Requirements +

+This module requires: +
    +
  • Perl Module: Date::Time (apt-get install libdatetime-perl)
  • +
  • Perl Module: Time::HiRes
  • +
  • Perl Module: JSON
  • +
  • FHEM Module: Blocking.pm
  • +
+
+
+ + +Definition +
    +define <name> SMAEVCharger <hostname/ip> <user> <password>
    +
    +
  • hostname/ip: IP-Adress of the charger, should be without protocol (for now hostname not testet!).
  • +
  • Example: define myWallbox 192.168.xxx.xxx username userpassword
  • +
+ + +Operation method +
    +The module logs on to the SMA Wallbox and reads live data (monitoring measurement values) as well as available parameters (configuration parameters).
    +All values ​​that can be changed via the web interface can also be changed with the module. To reduce readings, the values ​​to be displayed and the values ​​that can be changed
    + can be adjusted with the 'detail-level' and 'setting-level' attributes. +
+ +Get +
+
    + +
  • get <name> data +

    + The request of the charger will be executed directly. Otherwise all seconds the charge will be called automated (look at attribute interval) +
    +
  • + +
    +
+ +Attributes +
    + +
  • disable [1|0]
    + Deactivate/activate the module. +
  • +
    + + +
  • interval
    + Request cycle in seconds. (default: 60) +
  • +
    + + +
  • detail-level
    + Set level for showing Live-Data Readings
    + 0: Basic
    + 1: Adanced
    + 2: Expert +
  • +
    + + +
  • setting-level
    + Set level for changing Parameters with fhem set-command. The module checks corresponding detail-level attribute.
    + 0: Basic
    + 1: Adanced
    + 2: Expert +
  • +
    + +
+ +Readings +
    +Following infos will show readings (livedata, parameter) and there corresponding detail-level and setting-level. + +There are additional readings which will be calculated from the values of the wallbox. + + +
  • Anzahl_Ladevorgaenge
    + Counts the charging starts since last connecting +
  • +
    + +
  • Startzeit_Verbindung
    + Last connecting time +
  • +
    +
+
+ +To start charging there are different options: +
    + +
  • Param_Betriebsart_Ladevorgang
    + Optimiertes Laden: default for using planning algorithm from wallbox
    + Laden mit Vorgabe: predefined charging. To set this option the params 'Param_Dauer_Ladevorgang' and 'Param_Energiemenge_Ladevorgang' must be filled.
    + If both values are set then this param will be set automatically and charging starts.
    + Ladestopp: stop charging +
  • +
    + +
  • Param_Dauer_Ladevorgang
    + Duration of the charging process. This values sets date/time till charging should be finished (Param_Ende_Ladevorgang) +
  • +
    + +
  • Param_Energiemenge_Ladevorgang
    + Set energy for charging in kWh. Value can be changed during charging process. +
  • +
    + +
  • Param_Minimaler_Ladestrom
    + Set minimum power for starting charging process. Minimum is 6A. Some vehicles need more power to start, so change this value. +
  • +
    +
+
+ + + +
    +
  • Name in Webinterface : Name in FHEM : comment
  • +
  • LIVEDATA
  • +
  • Measurement.ChaSess.WhIn :Energie_Ladevorgang : unit Wh (detail-level: 0)
  • +
  • Measurement.Chrg.ModSw :Schalterstellung Drehschalter : (detail-level: 0)
  • +
  • Measurement.GridMs.A.phsA : Netzstrom_Phase_L1 : (detail-level: 0)
  • +
  • Measurement.GridMs.A.phsB : Netzstrom_Phase_L2 : (detail-level: 0)
  • +
  • Measurement.GridMs.A.phsC : Netzstrom_Phase_L3 : (detail-level: 0)
  • +
  • Measurement.GridMs.PhV.phsA : Netzspannung_Phase_L1 : (detail-level: 0)
  • +
  • Measurement.GridMs.PhV.phsB : Netzspannung_Phase_L2 : (detail-level: 0)
  • +
  • Measurement.GridMs.PhV.phsC : Netzspannung_Phase_L3 : (detail-level: 0)
  • +
  • Measurement.Metering.GridMs.TotWIn : Leistung_Bezug : unit: W (detail-level: 0)
  • +
  • Measurement.Metering.GridMs.TotWIn.ChaSta : Leistung_Ladestation : unit W (detail-level: 0)
  • +
  • Measurement.Metering.GridMs.TotWhIn : Zaehlerstand_Bezugszaehler : unit Wh (detail-level: 0)
  • +
  • Measurement.Metering.GridMs.TotWhIn.ChaSta : Zaehlerstand_Ladestation : unit Wh (detail-level: 0)
  • +
  • Measurement.Operation.EVeh.ChaStt : Status_Ladevorgang: (detail-level: 0)
  • +
  • Measurement.Operation.EVeh.Health : Status_verbundenes_Fahrzeug: (detail-level: 0)
  • +
  • Measurement.Operation.Evt.Msg : Status_Meldung : (detail-level: 0)
  • +
  • Measurement.Operation.Health : Status_Zustand : (detail-level: 0)
  • +
  • Setpoint.PlantControl.Inverter.FstStop : Schnellabschaltung : (detail-level: 0)
  • +
  • Measurement.GridMs.Hz : Netzfrequenz : (detail-level: 1)
  • +
  • Measurement.GridMs.TotPF : Verschiebungsfaktor : (detail-level: 1)
  • +
  • Measurement.GridMs.TotVA : Scheinleistung : (detail-level: 1)
  • +
  • Measurement.GridMs.TotVAr : Blindleistung : (detail-level: 1)
  • +
  • Measurement.Wl.AcqStt : Status_WLAN_Scan : (detail-level: 1)
  • +
  • Measurement.Wl.ConnStt : Status_WLAN_Verbindung : (detail-level: 1)
  • +
  • Measurement.Wl.SigPwr : Signalstaerke_Netzwerk : (detail-level: 1)
  • +
  • Measurement.InOut.GI1 : digitaler_Gruppeneingang : (detail-level: 2)
  • +
  • Measurement.Operation.WMaxLimSrc : Digitaler_Eingang : (detail-level: 2)
  • +
  • Measurement.Wl.SoftAcsConnStt : Status_Soft_Access_Point : (detail-level: 2)
  • +
  • PARAMS:
  • +
  • Parameter.Chrg.ActChaMod : Param_Betriebsart_Ladevorgang: (detail-level: 0 / setting-level: 0)
  • +
  • Parameter.Chrg.AMinCha : Param_Minimaler_Ladestrom: (detail-level: 0 / setting-level: 0)
  • +
  • Parameter.Chrg.Plan.DurTmm : Param_Dauer_Ladevorgang : (detail-level: 0 / setting-level: 0)
  • +
  • Parameter.Chrg.Plan.En : Param_Energiemenge_Ladevorgang : (detail-level: 0 / setting-level: 0)
  • +
  • Parameter.Chrg.Plan.StopTm : Param_Ende_Ladevorgang: (detail-level: 0)
  • +
  • Parameter.Chrg.StpWhenFl : Param_Trennung_nach_Vollladung: (detail-level: 0 / setting-level: 1)
  • +
  • Parameter.Chrg.StpWhenFlTm : Param_Ladebereitschaft_bis_Trennung: (detail-level: 0 / setting-level: 1)
  • +
  • Parameter.GridGuard.Cntry.VRtg : Param_Netz_Nennspannung: (detail-level: 0)
  • +
  • Parameter.PCC.ARtg : Param_Nennstrom_Netzanschluss: (detail-level: 0 / setting-level: 1)
  • +
  • Parameter.PCC.FlbInv.WMax : Param_Fallback_Wirkleistungsbegrenzung: (detail-level: 0 / setting-level: 1)
  • +
  • Parameter.Chrg.UseEnergyMeter : Param_Betrieb_mit_Netzanschlusspunktzaehler: (detail-level: 1 / setting-level: 1)
  • +
  • Parameter.Chrg.MinSwTms : Param_Minimale_Schaltdauer_Relais : (detail-level: 1 / setting-level: 1)
  • +
  • Parameter.Inverter.WMax : Param_Nennwirkleistung_WMaxOut: (detail-level: 1 / setting-level: 1)
  • +
  • Parameter.Inverter.WMaxIn : Param_Nennwirkleistung_WMaxIn: (detail-level: 1 / setting-level: 1)
  • +
  • Parameter.Inverter.WMaxInRtg : Param_Bemessungswirkleistung_WMaxInRtg: (detail-level: 1)
  • +
  • Parameter.Nameplate.ARtg : Param_Nennstrom_alle_Phasen: (detail-level: 1)
  • +
  • Parameter.Nameplate.Location : Param_Geraetename : (detail-level: 1)
  • +
  • Parameter.PCC.WMaxAsym : Param_Maximale_Schieflast: (detail-level: 1 / setting-level: 1)
  • +
  • Parameter.Nameplate.ChrgCtrl.ChrgTypTxt :Param_Typ_Ladecontroller : (detail-level: 2)
  • +
  • Parameter.Nameplate.ChrgCtrl.SerNumTxt :Param_Seriennummer_Ladecontrollers : (detail-level: 2)
  • +
  • Parameter.Nameplate.ChrgCtrl.SusyId :Param_SusyID_Ladecontrollers : (detail-level: 2)
  • +
  • Parameter.Nameplate.ChrgCtrl.SwRevTxt :Param_SWVersion_Ladecontroller : (detail-level: 2)
  • +
  • Parameter.Nameplate.CmpMain.HwRev :Param_HWVersion_Hauptprozessor : (detail-level: 2)
  • +
  • Parameter.Nameplate.CmpMain.Rev :Param_Umbaustand_Hauptprozessor : (detail-level: 2)
  • +
  • Parameter.Nameplate.CmpMain.SerNum :Param_Seriennummer_Hauptprozessor : (detail-level: 2)
  • +
  • Parameter.Nameplate.CmpMain.SusyId :Param_SUSyID_Hauptprozessor : (detail-level: 2)
  • +
  • Parameter.Nameplate.CmpOS.SwRev :Param_Firmware_Version_Betriebssystem : (detail-level: 2)
  • +
  • Parameter.Nameplate.MacId :Param_MAC-Adresse : (detail-level: 2)
  • +
  • Parameter.Nameplate.MainModel :Param_Geraeteklasse : (detail-level: 2)
  • +
  • Parameter.Nameplate.Model :Param_Geraetetyp : (detail-level: 2)
  • +
  • Parameter.Nameplate.ModelStr :Param_Typenbezeichnung : (detail-level: 2)
  • +
  • Parameter.Nameplate.PkgRev :Param_Softwarepaket : (detail-level: 2)
  • +
  • Parameter.Nameplate.SerNum :Param_Seriennummer : (detail-level: 2)
  • +
  • Parameter.Nameplate.Vendor :Param_Hersteller : (detail-level: 2)
  • +
  • Parameter.Nameplate.WlMacId :Param_WLAN_MAC : (detail-level: 2)
  • +
  • Parameter.DevUpd.IsOn : Param_Geraete_Update_ein : (detail-level: 2)
  • +
  • Parameter.Inverter.OutPhs : Param_Phasenzuordnung : (detail-level: 2)
  • +
  • Parameter.Operation.ComTmOut : Param_Timeout_nach_Kommunikationsverlust: (detail-level: 2)
  • +
  • Parameter.Spdwr.IgmpQryTms : Param_IGMP_Query_Intervall: (detail-level: 2)
  • +
  • Parameter.Spdwr.IgmpQryTx : Param_IGMP_Anfragen_senden: (detail-level: 2)
  • +
  • Parameter.Spdwr.ActlDnsSrvIp :Param_Akt_Speedwire_Serveradresse : (detail-level: 2)
  • +
  • Parameter.Spdwr.ActlGwIp :Param_Akt_Speedwire_Gateway : (detail-level: 2)
  • +
  • Parameter.Spdwr.ActlIp :Param_Akt_Speedwire_IP : (detail-level: 2)
  • +
  • Parameter.Spdwr.ActlSnetMsk :Param_Akt_Speedwire_Subnetzmaske : (detail-level: 2)
  • +
  • Parameter.Spdwr.AutoCfgIsOn :Automatische_Speedwire-Konfig_an : (detail-level: 2)
  • +
  • Parameter.Sys.DevRstr : Param_Geraeteneustart_ausloesen: (detail-level: 2)
  • +
  • Parameter.SwCmp.CmpEnnexOS.Frwk.SwRev :Param_ennexOS_Framework_Version : (detail-level: 2)
  • +
  • Parameter.Upd.AutoUpdIsOn : Param_Auto_Update_an: (detail-level: 2)
  • +
  • Parameter.Upd.AvalChkIstl :Param_Auto_Speedwire_Konfig_an : (detail-level: 2)
  • +
  • Parameter.Wl.ActlGwIp :Param_IP_Gateway_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.ActlDnsSrvIp :Aktuelle_Speedwire-DNS-Serveradresse : (detail-level: 2)
  • +
  • Parameter.Wl.ActlIp :Param_IP_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.ActlSnetMsk :Param_IP_Subnetz_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.DoAcq :Param_WLAN_suchen : (detail-level: 2)
  • +
  • Parameter.Wl.DoWPS :Param_WPS_aktivieren : (detail-level: 2)
  • +
  • Parameter.Wl.ExsNetw[] :Param_Gefundenes_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.Sec.Cry :Param_Verschluesselung_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.Sec.Psk :Param_WLAN-Passwort : (detail-level: 2)
  • +
  • Parameter.Wl.Sec.Ssid :Param_SSID_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.AutoCfgIsOn : Param_Auto_Update_an: (detail-level: 2)
  • +
  • Parameter.Wl.IsOn : Param_WLAN_eingeschaltet: (detail-level: 2)
  • +
  • Parameter.Wl.SoftAcsIsOn : Param_Soft_Access_Point_an: (detail-level: 2)
  • +
+

+ + +=end html + + +=begin html_DE + + +

SMAEVCharger

+ +Modul zur Integration eines SMA EVCharger über Speedwire (=Ethernet) Schnittstelle.
+Getestet mit SMA EV Charger 22 +

+ + + +Notwendige Module +

+Diese Modul benötigt: +
    +
  • Perl Module: Date::Time (apt-get install libdatetime-perl)
  • +
  • Perl Module: Time::HiRes
  • +
  • Perl Module: JSON
  • +
  • FHEM Module: Blocking.pm
  • +
+
+
+ + +Definition +
    +define <name> SMAEVCharger <hostname/ip> <user> <password>
    +
    +
  • hostname/ip: IP-Adress des Charger, sollte zunächst ohne Protokoll angegeben werden (mit hostname noch nicht getestet!).
  • +
  • Beispiel: define myWallbox 192.168.xxx.xxx username userpassword
  • +
+ + +Operation method +
    +Das Modul meldet sich bei der SMA Wallbox an und liest Live-Daten (Momentanwerte) sowie verfügbare Parameter (Konfigurationsparameter).
    +Alle Werte, die über die Weboberfläche geändert werden können, können auch mit dem Modul geändert werden. Um die Readings zu reduzieren,
    +können die anzuzeigenden Werte und die Werte, die geändert werden können, mit den Attributen "detail-level" und "setting-level" angepasst werden. +
+ +Get +
+
    + +
  • get <name> data +

    + Die Daten des Chargers werden direkt abgerufen. Ansonsten findet alle Sekunden ein automatisierter Abruf statt (siehe auch das Attribut interval) +
    +
  • + +
    +
+ +Attribute +
    + +
  • disable [1|0]
    + Deaktivieren/Aktivieren des Moduls. +
  • +
    + + +
  • interval
    + Abfragezyklus in Sekunden. (default: 60) +
  • +
    + + +
  • detail-level
    + Einstellung der Sichtbarkeit von Parametern.
    + 0: Basisinformationen
    + 1: erweiterte Informationen
    + 2: Infos auf Expertenlevel +
  • +
    + + +
  • setting-level
    + Einstellung für die Parameter, die über den set-Befehl änderbar sind. Bei der Eingabe wird geprüft, dass diese auch mittels "detail-level" sichtbar sind
    + 0: Basisinformationen
    + 1: erweiterte Änderungsparameter
    + 2: Änderung von Parametern auf Expertenlevel +
  • +
    +
+ +Readings + +Nachfolgende Readings dienen der Darstellung zusätzlicher Werte, die aus den Werten der Wallbox ermittelt wurden. +
    + +
  • Anzahl_Ladevorgaenge
    + Zähler zur Ermittlung aller gestarteten Ladungen, seit dem der Stecker das letzte Mal eingesteckt wurde +
  • +
    + +
  • Startzeit_Verbindung
    + Zeitpunkt, zu dem der Stecker das letzte Mal angesteckt wurde +
  • +
    +
+
+ +Zum Starten des Ladeprozess gibt es verschiedene Einstellmöglichkeiten: +
    + +
  • Param_Betriebsart_Ladevorgang
    + Optimiertes Laden: Standardeinstellung für die Ladesteuerung der Wallbox
    + Laden mit Vorgabe: Laden mit vordefinierten Werten. Dieser Wert kann nur eingestellt werden, wenn die Parameter 'Param_Dauer_Ladevorgang' und 'Param_Energiemenge_Ladevorgang' gefüllt sind.
    + Sind beide Werte gesetzt, wird automatisch in diesen Lademodus geschaltet und die Ladung beginnt entsprechend
    + Ladestopp: Ladevorgang stoppen +
  • +
    + +
  • Param_Dauer_Ladevorgang
    + Dauer des Ladevorgangs in Minuten. Hiermit wird dann auch der Parameter 'Param_Ende_Ladevorgang' gesetzt, der Datum/Uhrzeit des geplanten Ladeende anzeigt +
  • +
    + +
  • Param_Energiemenge_Ladevorgang
    + Energiemenge in kWh, die in der angegebenen Zeit geladen werden soll +
  • +
    + +
  • Param_Minimaler_Ladestrom
    + Minimaler Strom, mit dem eine Ladung gestartet wird. Minimum ist 6A. Einige E-Autos benötigen einen höheren Wert, der hiermit eingestellt werden kann. +
  • +
    +
+
+ + +Nachfolgend sind alle Readings aufgelistet: + +
+
    +
  • Name im Webinterface : Name in FHEM : Kommentar
  • +
  • LIVEDATA
  • +
  • Measurement.ChaSess.WhIn :Energie_Ladevorgang : unit Wh (detail-level: 0)
  • +
  • Measurement.Chrg.ModSw :Schalterstellung Drehschalter : (detail-level: 0)
  • +
  • Measurement.GridMs.A.phsA : Netzstrom_Phase_L1 : (detail-level: 0)
  • +
  • Measurement.GridMs.A.phsB : Netzstrom_Phase_L2 : (detail-level: 0)
  • +
  • Measurement.GridMs.A.phsC : Netzstrom_Phase_L3 : (detail-level: 0)
  • +
  • Measurement.GridMs.PhV.phsA : Netzspannung_Phase_L1 : (detail-level: 0)
  • +
  • Measurement.GridMs.PhV.phsB : Netzspannung_Phase_L2 : (detail-level: 0)
  • +
  • Measurement.GridMs.PhV.phsC : Netzspannung_Phase_L3 : (detail-level: 0)
  • +
  • Measurement.Metering.GridMs.TotWIn : Leistung_Bezug : unit: W (detail-level: 0)
  • +
  • Measurement.Metering.GridMs.TotWIn.ChaSta : Leistung_Ladestation : unit W (detail-level: 0)
  • +
  • Measurement.Metering.GridMs.TotWhIn : Zaehlerstand_Bezugszaehler : unit Wh (detail-level: 0)
  • +
  • Measurement.Metering.GridMs.TotWhIn.ChaSta : Zaehlerstand_Ladestation : unit Wh (detail-level: 0)
  • +
  • Measurement.Operation.EVeh.ChaStt : Status_Ladevorgang: (detail-level: 0)
  • +
  • Measurement.Operation.EVeh.Health : Status_verbundenes_Fahrzeug: (detail-level: 0)
  • +
  • Measurement.Operation.Evt.Msg : Status_Meldung : (detail-level: 0)
  • +
  • Measurement.Operation.Health : Status_Zustand : (detail-level: 0)
  • +
  • Setpoint.PlantControl.Inverter.FstStop : Schnellabschaltung : (detail-level: 0)
  • +
  • Measurement.GridMs.Hz : Netzfrequenz : (detail-level: 1)
  • +
  • Measurement.GridMs.TotPF : Verschiebungsfaktor : (detail-level: 1)
  • +
  • Measurement.GridMs.TotVA : Scheinleistung : (detail-level: 1)
  • +
  • Measurement.GridMs.TotVAr : Blindleistung : (detail-level: 1)
  • +
  • Measurement.Wl.AcqStt : Status_WLAN_Scan : (detail-level: 1)
  • +
  • Measurement.Wl.ConnStt : Status_WLAN_Verbindung : (detail-level: 1)
  • +
  • Measurement.Wl.SigPwr : Signalstaerke_Netzwerk : (detail-level: 1)
  • +
  • Measurement.InOut.GI1 : digitaler_Gruppeneingang : (detail-level: 2)
  • +
  • Measurement.Operation.WMaxLimSrc : Digitaler_Eingang : (detail-level: 2)
  • +
  • Measurement.Wl.SoftAcsConnStt : Status_Soft_Access_Point : (detail-level: 2)
  • +
  • PARAMS:
  • +
  • Parameter.Chrg.ActChaMod : Param_Betriebsart_Ladevorgang: (detail-level: 0 / setting-level: 0)
  • +
  • Parameter.Chrg.AMinCha : Param_Minimaler_Ladestrom: (detail-level: 0 / setting-level: 0)
  • +
  • Parameter.Chrg.Plan.DurTmm : Param_Dauer_Ladevorgang : (detail-level: 0 / setting-level: 0)
  • +
  • Parameter.Chrg.Plan.En : Param_Energiemenge_Ladevorgang : (detail-level: 0 / setting-level: 0)
  • +
  • Parameter.Chrg.Plan.StopTm : Param_Ende_Ladevorgang: (detail-level: 0)
  • +
  • Parameter.Chrg.StpWhenFl : Param_Trennung_nach_Vollladung: (detail-level: 0 / setting-level: 1)
  • +
  • Parameter.Chrg.StpWhenFlTm : Param_Ladebereitschaft_bis_Trennung: (detail-level: 0 / setting-level: 1)
  • +
  • Parameter.GridGuard.Cntry.VRtg : Param_Netz_Nennspannung: (detail-level: 0)
  • +
  • Parameter.PCC.ARtg : Param_Nennstrom_Netzanschluss: (detail-level: 0 / setting-level: 1)
  • +
  • Parameter.PCC.FlbInv.WMax : Param_Fallback_Wirkleistungsbegrenzung: (detail-level: 0 / setting-level: 1)
  • +
  • Parameter.Chrg.UseEnergyMeter : Param_Betrieb_mit_Netzanschlusspunktzaehler: (detail-level: 1 / setting-level: 1)
  • +
  • Parameter.Chrg.MinSwTms : Param_Minimale_Schaltdauer_Relais : (detail-level: 1 / setting-level: 1)
  • +
  • Parameter.Inverter.WMax : Param_Nennwirkleistung_WMaxOut: (detail-level: 1 / setting-level: 1)
  • +
  • Parameter.Inverter.WMaxIn : Param_Nennwirkleistung_WMaxIn: (detail-level: 1 / setting-level: 1)
  • +
  • Parameter.Inverter.WMaxInRtg : Param_Bemessungswirkleistung_WMaxInRtg: (detail-level: 1)
  • +
  • Parameter.Nameplate.ARtg : Param_Nennstrom_alle_Phasen: (detail-level: 1)
  • +
  • Parameter.Nameplate.Location : Param_Geraetename : (detail-level: 1)
  • +
  • Parameter.PCC.WMaxAsym : Param_Maximale_Schieflast: (detail-level: 1 / setting-level: 1)
  • +
  • Parameter.Nameplate.ChrgCtrl.ChrgTypTxt :Param_Typ_Ladecontroller : (detail-level: 2)
  • +
  • Parameter.Nameplate.ChrgCtrl.SerNumTxt :Param_Seriennummer_Ladecontrollers : (detail-level: 2)
  • +
  • Parameter.Nameplate.ChrgCtrl.SusyId :Param_SusyID_Ladecontrollers : (detail-level: 2)
  • +
  • Parameter.Nameplate.ChrgCtrl.SwRevTxt :Param_SWVersion_Ladecontroller : (detail-level: 2)
  • +
  • Parameter.Nameplate.CmpMain.HwRev :Param_HWVersion_Hauptprozessor : (detail-level: 2)
  • +
  • Parameter.Nameplate.CmpMain.Rev :Param_Umbaustand_Hauptprozessor : (detail-level: 2)
  • +
  • Parameter.Nameplate.CmpMain.SerNum :Param_Seriennummer_Hauptprozessor : (detail-level: 2)
  • +
  • Parameter.Nameplate.CmpMain.SusyId :Param_SUSyID_Hauptprozessor : (detail-level: 2)
  • +
  • Parameter.Nameplate.CmpOS.SwRev :Param_Firmware_Version_Betriebssystem : (detail-level: 2)
  • +
  • Parameter.Nameplate.MacId :Param_MAC-Adresse : (detail-level: 2)
  • +
  • Parameter.Nameplate.MainModel :Param_Geraeteklasse : (detail-level: 2)
  • +
  • Parameter.Nameplate.Model :Param_Geraetetyp : (detail-level: 2)
  • +
  • Parameter.Nameplate.ModelStr :Param_Typenbezeichnung : (detail-level: 2)
  • +
  • Parameter.Nameplate.PkgRev :Param_Softwarepaket : (detail-level: 2)
  • +
  • Parameter.Nameplate.SerNum :Param_Seriennummer : (detail-level: 2)
  • +
  • Parameter.Nameplate.Vendor :Param_Hersteller : (detail-level: 2)
  • +
  • Parameter.Nameplate.WlMacId :Param_WLAN_MAC : (detail-level: 2)
  • +
  • Parameter.DevUpd.IsOn : Param_Geraete_Update_ein : (detail-level: 2)
  • +
  • Parameter.Inverter.OutPhs : Param_Phasenzuordnung : (detail-level: 2)
  • +
  • Parameter.Operation.ComTmOut : Param_Timeout_nach_Kommunikationsverlust: (detail-level: 2)
  • +
  • Parameter.Spdwr.IgmpQryTms : Param_IGMP_Query_Intervall: (detail-level: 2)
  • +
  • Parameter.Spdwr.IgmpQryTx : Param_IGMP_Anfragen_senden: (detail-level: 2)
  • +
  • Parameter.Spdwr.ActlDnsSrvIp :Param_Akt_Speedwire_Serveradresse : (detail-level: 2)
  • +
  • Parameter.Spdwr.ActlGwIp :Param_Akt_Speedwire_Gateway : (detail-level: 2)
  • +
  • Parameter.Spdwr.ActlIp :Param_Akt_Speedwire_IP : (detail-level: 2)
  • +
  • Parameter.Spdwr.ActlSnetMsk :Param_Akt_Speedwire_Subnetzmaske : (detail-level: 2)
  • +
  • Parameter.Spdwr.AutoCfgIsOn :Automatische_Speedwire-Konfig_an : (detail-level: 2)
  • +
  • Parameter.Sys.DevRstr : Param_Geraeteneustart_ausloesen: (detail-level: 2)
  • +
  • Parameter.SwCmp.CmpEnnexOS.Frwk.SwRev :Param_ennexOS_Framework_Version : (detail-level: 2)
  • +
  • Parameter.Upd.AutoUpdIsOn : Param_Auto_Update_an: (detail-level: 2)
  • +
  • Parameter.Upd.AvalChkIstl :Param_Auto_Speedwire_Konfig_an : (detail-level: 2)
  • +
  • Parameter.Wl.ActlGwIp :Param_IP_Gateway_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.ActlDnsSrvIp :Aktuelle_Speedwire-DNS-Serveradresse : (detail-level: 2)
  • +
  • Parameter.Wl.ActlIp :Param_IP_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.ActlSnetMsk :Param_IP_Subnetz_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.DoAcq :Param_WLAN_suchen : (detail-level: 2)
  • +
  • Parameter.Wl.DoWPS :Param_WPS_aktivieren : (detail-level: 2)
  • +
  • Parameter.Wl.ExsNetw[] :Param_Gefundenes_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.Sec.Cry :Param_Verschluesselung_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.Sec.Psk :Param_WLAN-Passwort : (detail-level: 2)
  • +
  • Parameter.Wl.Sec.Ssid :Param_SSID_WLAN : (detail-level: 2)
  • +
  • Parameter.Wl.AutoCfgIsOn : Param_Auto_Update_an: (detail-level: 2)
  • +
  • Parameter.Wl.IsOn : Param_WLAN_eingeschaltet: (detail-level: 2)
  • +
  • Parameter.Wl.SoftAcsIsOn : Param_Soft_Access_Point_an: (detail-level: 2)
  • +
+ +

+ +=end html_DE + +=cut