Modul für Tesla Model S / 3 / X

Begonnen von swhome, 17 Juli 2017, 12:53:25

Vorheriges Thema - Nächstes Thema

joker4791

Zitat von: Elektrolurch am 08 Oktober 2020, 15:04:23
Die gps - Koordinaten über Open Street Map umzusetzen, funktioniert super.
Hast Du da mal ein Beispiel für?

Elektrolurch

Hallo Joker,


sub TeslaCar_UpdateAddress($$$)
{
my ($hash,$la,$lo) = @_;
my $name  = $hash->{NAME};

# hier die eigene Mail-Adresse einsetzen
my $mailaddress = 'meineMail@web.de';

my $api_uri = "http://nominatim.openstreetmap.org/reverse?format=json&accept-language=de&lat=$la&lon=$lo&zoom=18&addressdetails=12&email=$mailadress";
# my $api_uri = "http://nominatim.openstreetmap.org/reverse";


#### Get status variables
  my $param = {
'url' => $api_uri,
'hash' => $hash,
'format' => 'json',

'header'  => 
{
'Accept' => "application/json"
},
# "Authorization" => "Bearer $token",
'timeout' => 10,
'callback' => \&TeslaCar_UpdateAddressCallback
}; # param

Log3 $name, 4, "TC_UpdateAddress: $name request: $param->{url}";

  HttpUtils_NonblockingGet($param);

  return undef;
} # end sub TeslaCar_UpdateAddress
##############################


Die 'TeslaCar_UpdateAddress($$$)' rufe ich von der 'TeslaCar_UpdateStatusCallback' auf, aber nur wenn
'is_user_present' und sich die Koordinaten geändert haben.
$hash ist der hash von Deinem Auto.


sub TeslaCar_UpdateAddressCallback($)
{
my ($param, $err, $data) = @_;
my $hash = $param->{hash};
my $name = $hash->{NAME};
my %readings = ();
my $JSON = JSON->new->utf8(0)->allow_nonref;

if($err ne "")
{
Log3 $name, 1, "TeslaCar_updateAddressCallback: error while requesting ".$param->{url}." - $err";
} # if error
elsif($data ne "")
{
Log3 $name, 5, "TeslaCar_UpdateAddressCallback: $name returned: \n$data";

my $parsed = eval {$JSON->decode ($data)};
if($@)
{
Log3($name,1,"TeslaCar_UpdateAddressCallback: $name - JSON error requesting data: $@");
} # json parse error
else
{
# readings

my $short = $parsed->{address};
my %unknown = map(
{($_  !~m/(building|office|industrial|shop|neighbourhood|man_made|railway|city|town|village|road|house_number|suburb|city_district|neighbourhood|postcode|country_code|country|state|county|junction)$/) ? ($_,$short->{$_}):()}
sort keys %$short);

Log3($name,1,"TC_updateaddresscb: unknown: \n".
join(' ',%unknown)) if(int( keys %unknown));

my $address = "$short->{road} $short->{house_number}";
my $city = "";
foreach my $c ('city','town','village')
{
if(exists($short->{$c}))
{
$city = $short->{$c};
last;
} # if exists
} # foreach $c

# $address .= $city;

my $extra = "";
foreach my $c ('building','office','shop','industrial',
'junction',
'suburb','city_district','man_made','address_county','address_country')
{
if(exists($short->{$c}))
{
$extra = $short->{$c};
last;
} # if exists
} # foreach $c


my $address_county = "";
$address_county = $short->{county} if(exists($short->{county}));
my $address_country = "";
$address_country = $short->{country} if(exists($short->{country}));
my $address_state = "";
$address_state = $short->{state} if(exists($short->{state}));

# readings aktualisieren

my $update = 0;
readingsBeginUpdate($hash);
if(readingsval($hash,'position_addr','') ne $address)
{
readingsBulkUpdate($hash,'position_addr',$address,1);
$hash->{end}{'position_addr'} = $address;
$update = 1;
} # adress has changed
if(readingsval($hash,'position_addr_city','') ne $city)
{
readingsBulkUpdate($hash,'position_addr_city',$city,1);
$hash->{end}{'position_addr_city'} = $city;
$update = 1;
} # city has changed
readingsBulkUpdate($hash,'position_addr_county',$address_county,1);
readingsBulkUpdate($hash,'position_addr_country',$address_country,1);
readingsBulkUpdate($hash,'position_addr_state',$address_state,1);
if(readingsval($hash,'position_addr_extra','') ne $extra)
{
readingsBulkUpdate($hash,'position_addr_extra',$extra,1);
$update = 1;
} # extra has changed

readingsEndUpdate($hash,1);
# in start wird der Anfang einer Reise gespeichert
# in end die aktuelle Position
# kann aber weg gelassen werden, da für die Trip-Aufzeichnung verwendet wird

if($hash->{start}{time} == 0)
{
$hash->{start}{'position_addr'} = $address;
$hash->{start}{'position_addr_city'} = $city;
} # start

# kann auch auskommentiert werden, da die einzelnen Punkte des Trips im Abstand von 2 min aufgezeichnet werden

TeslaCar_Trace($hash)
   if($update && AttrVal($name,'trace',0));
} # no parse error
} # there is data
} # end sub TeslaCar_UpdateAddressCallback
##############################


OSM hat sehr viele zusätzliche Infos, die ich (gewichtet und nach ihrem Auftreten) in $extra bzw. im Reading position_addr_extra speichere.
$city wird generiert aus city - town - village (je nach dem wer vorhanden ist).

Der untere Teil ist spezifisch für die Aufzeichnung einer Reise, die ich noch eingebaut habe.
Da werden dann so Werte wie Verbrauch je 100 km, Reisezeit, Reise-Distanz, Start- und Zieladresse für ein Fahrtenbuch) usw. erzeugt.
Bin gerade beim Testen...

Elektrolurch
(
configDB und Windows befreite Zone!

roadghost

Hallo zusammen,

ich habe heute versucht, mein M3 in FHEM einzubinden.

Nach dem Login ist das Modul connected, aber ich sehe weder ein Fahrzeug, noch kommen readings.

ein set teslaconn scanCars bringt FHEM zum Absturz.

Im Log ist trotz verb5 nichts zu finden.

Was mache ich falsch ?
NUC/Ubuntu 22.04 m. FHEM, div. Tasmota-Steckdosen, HMCFGUSB-2 für 12x HM-CC-RT-DN + 8x HM-TC-IT-WW
Rademacher DuoFern für 12 Jalousien, JeeLink für LaCrosse Temp.Sensor, WLAN-smart-Plugs, 
NUKI smartlock, 2xIP-CAM, Pylontech Speicher + Sungrow WR, Unifi-AP´s + Controller auf weiterem NUC

TimoD

#138
Ich brauche mal Hilfe der Programmier Profis:

War heute bei Tesla, sie haben wohl bei den neuen MCUs das Verhalten geändert. Und zwar wacht das Fahrzeug jede Stunde einmal kurz auf um sich mit den Tesla Servern zu verbinden (Es wacht aber nur die MCU und nicht das gesamte Fahrzeug auf. Wenn aber FHEM verbunden ist, wird das Fahrzeug als Online gesehen und es passiert:

# always read all data and update all values after coming online
          if ($car->{state} eq "online") {
            $requestFullStatus = 1;
            $hash->{updateAllValues} = 1;
          }
        } else {
          $hash->{updateAllValues} = 0;
        }


Woraufhin, dann das ganze Fahrzeug aufwacht und auch nicht direkt wieder einschläft.

Jetzt würde ich gerne in dem Fall, dass das Fahrzeug in den Status Online geht abwarten, ob es 3 Minuten später auch noch Online ist und erst dann die komplette Abfrage starten. (Um zu schauen, ob das Auto nicht schon wieder eingeschlafen ist. Bekomme es aber nicht hin, bzw. mir fehlt einfach Programmiererfahrung in der Sprache (Was ist perl?)

Ich versteh es wie folgt:

1. Abfrage ob FullStatus


  my $requestFullStatus = (
    ReadingsVal($name,"state",undef) eq "online" &&          # request full status at this poll when online and
      (
      $hash->{skipFull} >= $updateTimer ||                   # at least all $updateTimer seconds
        (
        #$odometerChangeAge < (18*$pollingTimer) ||                  # or if speed has changed between the last three polls
        $stateChangeAge < (3*$pollingTimer) ||                    # or if state has changed between the last three polls
$ParkingAge < (3*$updateTimer) ||                    # or if car has been parked the last 30 minutes
        ReadingsVal($name,"charging_state","none") eq "Charging" ||  # or if car is charging
ReadingsVal($name,"shift_state","none") ne "P" ||  # or if car is not in P
ReadingsVal($name,"sentry_mode","none") == 1 # or if car is in sentry mode
        )
      )
    );


2. Aufruf Funktion mit Übergabe ob FullStatus:


    if ($hash->{skipStatus}>=$pollingTimer) {
       TeslaCar_UpdateStatus($hash, 1);
       $hash->{skipStatus}=0;                                                       #HILFE was machen diese Zeilen?
       $hash->{skipFull}=0;                  #HILFE was machen diese Zeilen?


3. Abfragen ob Wert frisch auf Online gewechselt hat

if (ReadingsVal($hash->{NAME},"state",undef) ne $car->{state}) {
          readingsBeginUpdate($hash);
          readingsBulkUpdate($hash, "state", $car->{state});
          readingsEndUpdate($hash, 1);
          # always read all data and update all values after coming online
          if ($car->{state} eq "online") {
            $requestFullStatus = 1;
            $hash->{updateAllValues} = 1;
          }
        } else {
          $hash->{updateAllValues} = 0;
        }

und in diesem Fall requestFullStatus "händisch auf 1"

4. Abruf der Daten wenn FullRequest

if ($car->{state} eq "online" && $requestFullStatus) {
          my @names = ();
          push @names, "vehicle_data"                if (index($dataRequest, "data")>-1);
          push @names, "data_request/vehicle_state"  if (index($dataRequest, "vehicle")>-1);
          push @names, "data_request/charge_state"   if (index($dataRequest, "charge")>-1);
          push @names, "data_request/drive_state"    if (index($dataRequest, "drive")>-1);
          push @names, "data_request/climate_state"  if (index($dataRequest, "climate")>-1);
          push @names, "data_request/gui_settings"   if (index($dataRequest, "gui")>-1);
          push @names, "data_request/vehicle_config" if (index($dataRequest, "config")>-1);
          $hash->{topics} = [@names];
          TeslaCar_UpdateVehicleStatus($hash);
        }


Was ich auch noch nicht gefunden habe, ist wo der eigentlich "kleine" Abruf von nur Status stattfindet!?

swhome

#139
Wow was hier alles los ist  ;D

@Elektrolurch, sehr interessant, genau dieser Punkt ist in der Tat mit den meisten Unsicherheiten verbunden. Bin gespannt welche Erfahrungen Du machst und werde Deinen Code auch mal mit meinem Oldtimer ausprobieren.

Ich finde es auch schade dass das zeitnahe Erkennen des Fahrtantritts ohne vorherigen Schlaf des Computers nicht möglich ist. Die Idee, nach dem Laden nicht direkt auf lange Aktualisierungspausen zu schalten finde ich super!

@roadghost, gibts vor dem Absturz noch irgendeine Meldung im fhem.log?

@TimoD, wow echt Du hast bei Tesla jemand gefunden mit dem Du über das API sprechen konntest? Das ist ja fast unglaublich. Lebst Du in Kalifornien? Deine Info mit dem kurzen Aufwachen ist sehr wichtig und führt natürlich wie Du schon beobachtest hast zu einem vollen Request aller Daten. Zunächst aber mal eine Bitte: Dein Code ist nicht aktuell, bitte führe ein update des Moduls durch.

Nachdem Elektrolurch auch gerade mit der Steuerung der Abfrage experimentiert, kann er das 3-Minuten-Delay vielleicht mit einbauen. Ich nehme an dass er auch ein Auto mit neuer MCU hat. Ich überlege schon ob ich ein Upgrade machen lasse, wollte damit aber noch warten bis das Radio auch upgegradet werden kann.


Im Einsatz: FHEM auf Raspberry Pi mit 350 devices, hauptsächlich Homematic Wired und HM-Heizungsregler, dazu diverse Eigenbauten für Fussbodenheizung und LED Beleuchtung. Und jetzt mit Alexa!

TimoD

#140
Zitat von: swhome am 12 Oktober 2020, 23:38:51
Wow was hier alles los ist  ;D

@Elektrolurch, sehr interessant, genau dieser Punkt ist in der Tat mit den meisten Unsicherheiten verbunden. Bin gespannt welche Erfahrungen Du machst und werde Deinen Code auch mal mit meinem Oldtimer ausprobieren.

Ich finde es auch schade dass das zeitnahe Erkennen des Fahrtantritts ohne vorherigen Schlaf des Computers nicht möglich ist. Die Idee, nach dem Laden nicht direkt auf lange Aktualisierungspausen zu schalten finde ich super!

@roadghost, gibts vor dem Absturz noch irgendeine Meldung im fhem.log?

@TimoD, wow echt Du hast bei Tesla jemand gefunden mit dem Du über das API sprechen konntest? Das ist ja fast unglaublich. Lebst Du in Kalifornien? Deine Info mit dem kurzen Aufwachen ist sehr wichtig und führt natürlich wie Du schon beobachtest hast zu einem vollen Request aller Daten. Zunächst aber mal eine Bitte: Dein Code ist nicht aktuell, bitte führe ein update des Moduls durch.

Nachdem Elektrolurch auch gerade mit der Steuerung der Abfrage experimentiert, kann er das 3-Minuten-Delay vielleicht mit einbauen. Ich nehme an dass er auch ein Auto mit neuer MCU hat. Ich überlege schon ob ich ein Upgrade machen lasse, wollte damit aber noch warten bis das Radio auch upgegradet werden kann.

@swhome: Nein, wohne nähe Stuttgart, habe mich aber wahrscheinlich derart beschwert, dass er Kollege meinte, er zeigt mir die Rohdaten vom Fahrzeug (CAN, BMS etc.). Habe jetzt als quick BugFix mal das $requestFullStatus für updateTimer und "after coming online deaktiviert" und die Daten über Nacht mit geloggt. Es deckt sich exakt mit den Ausführungen von Tesla:

2020-10-13_00:19:44 5YJ19HF176512 state: online
2020-10-13_00:22:38 5YJ19HF176512 state: offline
2020-10-13_01:21:25 5YJ19HF176512 state: online
2020-10-13_01:24:08 5YJ19HF176512 state: offline
2020-10-13_02:22:47 5YJ19HF176512 state: online
2020-10-13_02:25:30 5YJ19HF176512 state: offline
2020-10-13_03:24:16 5YJ19HF176512 state: online
2020-10-13_03:27:11 5YJ19HF176512 state: offline
2020-10-13_04:25:50 5YJ19HF176512 state: online
2020-10-13_04:28:33 5YJ19HF176512 state: offline
2020-10-13_05:27:20 5YJ19HF176512 state: online
2020-10-13_05:30:03 5YJ19HF176512 state: offline
2020-10-13_06:28:52 5YJ19HF176512 state: online
2020-10-13_06:31:36 5YJ19HF176512 state: offline
2020-10-13_07:30:18 5YJ19HF176512 state: online
2020-10-13_07:33:14 5YJ19HF176512 state: offline


Fahrzeug wacht exakt nach einer Stunde für ca. 3 Minuten auf und schläft danach wieder ein. Meine zusätzliche Lösung ist, dass ich über FTUI im Fahrzeug eine Tesla Darstellung habe und darüber den $requestFullStatus auslösen kann, siehe Anhang.

@Elektrolurch: Deine Änderungen hören sich klasse an! (u.a. Durchschnittsverbrauch und Co. (Habe dies derzeit per userReadings umgesetzt) Eine Implementierung des "Verzögerungstimers nach Online für 3 Minuten oder für Variable-Minute wäre klasse. Gerne zu Begin auch erstmal als Hinweis wie du es umsetzten würdest.

Ansonsten werde ich heute zusätzlich noch das Update durchführen.

Grüße Timo

Habs jetzt wie folgt versucht:


  my $stateChangeAge    = gettimeofday() - time_str2num(ReadingsTimestamp($name,"state",gettimeofday()));

my $requestFullStatus = (
    ReadingsVal($name,"state",undef) eq "online" &&          # request full status at this poll when online and
      (
        $stateChangeAge > (24*$pollingTimer) ||                    # or if state has changed between the last three polls
        ReadingsVal($name,"charging_state","none") eq "Charging" ||  # or if car is charging
ReadingsVal($name,"sentry_mode","none") == 1 # or if car is in sentry mode
      )
    );


pollingTimer habe ich auf 10 Sekunden, was bedeuten würde, wenn Online und Alter 4 Minuten, dann FullRequest. Müsste doch passen,... gerade schläft das Fahrzeug :-)

Elektrolurch

Hallo,

Zitat:
Nachdem Elektrolurch auch gerade mit der Steuerung der Abfrage experimentiert, kann er das 3-Minuten-Delay vielleicht mit einbauen. Ich nehme an dass er auch ein Auto mit neuer MCU hat. Ich überlege schon ob ich ein Upgrade machen lasse, wollte damit aber noch warten bis das Radio auch upgegradet werden kann.

Eigentlich habe ich auf meinem neuen M3 die neuste Software aufgespielt, kann aber das o.g. Verhalten nicht bestätigen.
Allerdings steht bei mir der pollingTimer auch auf 120, vielleicht fällt das kurze 'online' daher aus dem Zeitraster.

Ich werde es weiter beobachten.
OSM-Adressenumsetzung funktioniert, Fahrtenbuch auch (nach 30 Minuten Pause wird der aktuelle Trip als Eintrag in eine Datei eingetragen), das Aufladen wird auch abgespeichert, so dass man auch über längere Zeit die Verbrauchswerte ermitteln kann.
Habe dem Modul für die einzelnen Bereiche auch noch einen eigenen html-Output verpasst.

Aktion, Batterie, Einstellungen, Fahren, Fahrtenbuch, Klima, Status, Strecke

Schönes Spielzeug. Wenn alles funktioniert und Interesse an einer Integration besteht, benötige ich allerdings etwas Unterstützung.

Elektrolurch
configDB und Windows befreite Zone!

roadghost

Zitat von: swhome am 12 Oktober 2020, 23:38:51
Wow was hier alles los ist  ;D

@roadghost, gibts vor dem Absturz noch irgendeine Meldung im fhem.log?

Hi. Folgenden Eintrag habe ich im Log gefunden:

2020.10.11 21:28:22.617 1: PERL WARNING: Use of uninitialized value $token in concatenation (.) or string at ./FHEM/49_TeslaConnection.pm line 370.
malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "(end of string)") at ./FHEM/49_TeslaConnection.pm line 313.

NUC/Ubuntu 22.04 m. FHEM, div. Tasmota-Steckdosen, HMCFGUSB-2 für 12x HM-CC-RT-DN + 8x HM-TC-IT-WW
Rademacher DuoFern für 12 Jalousien, JeeLink für LaCrosse Temp.Sensor, WLAN-smart-Plugs, 
NUKI smartlock, 2xIP-CAM, Pylontech Speicher + Sungrow WR, Unifi-AP´s + Controller auf weiterem NUC

swhome

Und danach stürzt das ganze FHEM ab? Ich schau's mir an.

Übrigens kommt noch weitere Arbeit auf uns zu, Tesla hat eine multifaktor authentication eingeführt. Ich nehme an dass das Modul nach dem Aktivieren der mfa nicht mehr funktioniert.
Im Einsatz: FHEM auf Raspberry Pi mit 350 devices, hauptsächlich Homematic Wired und HM-Heizungsregler, dazu diverse Eigenbauten für Fussbodenheizung und LED Beleuchtung. Und jetzt mit Alexa!

Black7king

Zitat von: swhome am 16 Oktober 2020, 23:21:47
Übrigens kommt noch weitere Arbeit auf uns zu, Tesla hat eine multifaktor authentication eingeführt. Ich nehme an dass das Modul nach dem Aktivieren der mfa nicht mehr funktioniert.

Jup so siehts aus geht leider nicht mehr mit der MFA

Elektrolurch

#145
Seit 31.10. 13:00 Uhr geht es bei mir auch nicht. "teslaconn" sagt login neccessary, aber der login geht nicht mehr?
Merkwürdigerweise gab es aber kein Update der Tesla - App auf dem iPhone.
Ist es jetzt die MFA oder ein anderes Problem?
Hat noch jemand Probleme mit dem login?

set teslacoon scancars führt zu

2020.11.02 12:10:17 4: teslaconn request: https://owner-api.teslamotors.com/api/1/vehicles
2020.11.02 12:10:17 4: teslaconn: no token to be refreshed
2020.11.02 12:10:17 1: PERL WARNING: Use of uninitialized value $token in concatenation (.) or string at ./FHEM/49_TeslaConnection.pm line 370.
2020.11.02 12:10:18 4: teslaconn response:
malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "(end of string)") at ./FHEM/49_TeslaConnection.pm line 313.
2020.11.02 12:11:49 1: Including fhem.cfg


Elektrolurch
configDB und Windows befreite Zone!

swhome

Sieht aus wie nicht eingeloggt. Ich hab mich bisher noch nicht neu anmelden müssen... aber irgendwann wird's passieren  :-\
Im Einsatz: FHEM auf Raspberry Pi mit 350 devices, hauptsächlich Homematic Wired und HM-Heizungsregler, dazu diverse Eigenbauten für Fussbodenheizung und LED Beleuchtung. Und jetzt mit Alexa!

Faber38

erstmal DANKE  ;D für das Modul...
Funktioniert für meine belange einwandfrei .

Mal sehen was man damit alles anfangen kann  8)

LR66

#148
Bei meinem M3 läuft es nach Erstinstallation im Frühjahr tadellos vor sich hin, selbst wenn die Handy-App mal tot ist, kriegt es beim Laden neue Daten. Überhöhter Schlafverbrauch ist mir nicht aufgefallen. Jetzt werde ich mal forschen, was die Log's so sagen...
Danke, dass ihr ein Auge drauf habt und da ggf. was macht!
PS: Im November schlief das M3 bei mir im Schnitt über Phasen von 6-10h (Firmware aktuell 2020.44.10.1).

Faber38

Zitat von: Elektrolurch am 02 November 2020, 12:14:47
Seit 31.10. 13:00 Uhr geht es bei mir auch nicht. "teslaconn" sagt login neccessary, aber der login geht nicht mehr?
Merkwürdigerweise gab es aber kein Update der Tesla - App auf dem iPhone.
Ist es jetzt die MFA oder ein anderes Problem?
Hat noch jemand Probleme mit dem login?



Elektrolurch

Hallo,
bei mir geht der login nur in der Befehls-Zeile mit
set teslaconn login xxx@xxx.de passwort