################################################################################################################# # $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