BMW connected drive in IPS?

Hallo zusammen.

Ich würde gerne wissen, ob schon jemand sein BMW i3 oder Hybrid im IPS als Status mit den verschiedenen zur Verfügung stehenden Werten darstellen konnte?
Es gibt da einige API Dokumentationen, welche einem dies erlauben ohne die App verwenden zu müssen.

Danny

Wow, das wäre mal was :wink:

Hatte vor einem dreivirtel Jahr mal versucht Infos darüber zu bekommen, aber habe dann aufgegeben :frowning:

Abend!

Man findet einiges dazu im Internet. Sieht eigentlich einfach aus >> GitHub - edent/BMW-i-Remote: A reverse engineered interface for the BMW i3 Electric Car

Hätte ich sicher Spaß dran, aber leider fehlt mir das passende Auto … kann mir aber gerne jemand eins sponsoren :wink: :smiley:

Grüße,
Chris

Ja, das mit Github hab ich auch gefunden, das Auto auch. :slight_smile:
Spannend zu wissen, ob es auch jemand von diesem Forum schon realisiert hat und wie gut sich das im IPS Webfrontend denn abbilden lässt

Vielleicht reicht Dir ja iRemote von den Funktionen aus, das kannst Du einfach mit IP-Symcon benutzten.

Ich hätte was für dich:

Bei mir schaut das so aus:

Fahrten.JPGStatusmeldungen.JPG

Infos aus folgenden Foren zusammengesucht und noch etwas erweitert:
https://okedv.dyndns.org/wbb/blog/index.php?entry/51-connecteddrive-webapp-fuer-i3-und-plugins/http://
https://shkspr.mobi/blog/2015/11/reverse-engineering-the-bmw-i3-api/
https://github.com/edent/BMW-i-Remote#servers
https://github.com/sergejmueller/battery.ebiene.de

Probleme:

  1. Es gibt keinen ‚Push-Service‘. Die Webschnittstelle muss regelmässig abgefragt werden und dennoch kann es passieren, dass Informationen verloren gehen. Ausserdem wird es für BMW einfach sein festzustellen, dass da jemand sehr regelmässig abfragen tätigt, welche so wohl kaum von der App oder der offiziellen Website stammen. Ob es BMW stört?
  2. Aufgrund des reverse engineering Ansatzes kann es jederzeit aufhören zu funktionieren, wenn BMW etwas am Systen ändert. Für BMW wäre es sehr einfach die Tokens so zu gestalten, dass es nicht mehr oder nur mit erheblichem Aufwand funktioniert.

Bis es so ist, freue ich mich über den Komfort und die Möglichkeit einen Verlauf (z.B. der Fahrten) darzustellen. Und über den Touchscreen im Haus das Auto vorzuheizen ist schon nett :slight_smile:

LG, kjb

Hi kjb,

hättest Du da ein paar code snipsel?

Danke
Attain

Hätte auch Interesse an Code Schnipsel!

Eine klasse Sache wäre ein Modul, das die Variablen zum lesen und schreiben (für remote Funktionen) zur Verfügung stellt.
Dann könnte man auch ohne Programmierkenntnisse die Werte visualisieren und Remote Funktionen auslösen.

Bei IO Broker gibt es bereits einen Adapter, der die Datenpunkte bereitstellt.

Und was benötigst Du da an einzelnen Datenpunkten? Das meiste wären ja doch eher eine HTMLBox aufgrund der Fülle an Daten. Da müsste man ja dann auch differenzieren um was für ein Modell es sich handelt ein 5er braucht ja z.B. andere Datenpunkte als ein i3.

eine HTML Box wäre auch schon hilfreich - ist aber dann eine starre Lösung und nur passiv Nutzbar.

Wenn ein Modul aber zumindest die wichtigen Parameter als Variable zur Verfügung stellt, dann kann darauf aufbauend mit IPS Boardmitteln jeder die Parameter in seine Visualisierung individuell einbauen - inc. Logging und Ereignistriggern.

Für die Remote Funktionen wären Befehle wie „Door Lock“, „Standheizung ein“, „Standheizungstimer setzen“, „Lichthupe ein“ sinnvoll. Die könnten dann wieder in Scripten und Ereignissen aufgerufen werden.

Anwendungsbeispiel 1: man könnte den Start der Standheizung aus IPS automatisch starten im Rahmen von Szenarien, die am Morgen ablaufen (Starte die Standheizung, wenn Wochentag und 30 min nach Kaffeemaschine ein etc.).

Anwendugnsbeispiel 2: Erinnerungsfunktion in IPS wenn Fahrzeug vor dem Haus nicht abgesperrt oder. Warnung wenn Cabrio offen vor dem Haus steht und es beginnt zu regnen

Bei Batteriefahrzeugen sind diverse Anwendungen mit intelligentem Laden bei Integration des Fahrzeuges in IPS denkbar.

Vielleicht findet sich ein BMW Fan in der Community, der so ein Modul bauen kann.

Den Vorschlag finde ich top.

Mir ist eigentlich auch nur wichtig am Abend vor dem Bettgehen zu wissen das alles abgeschlossen ist - inkl. Auto :wink:

Das ist an sich ja kein Hexenwerk so was ist an zwei Tagen erledigt. Das Problem ist eher das ich zwar mal eine 5er mit BMW Connect gefahren habe, aber jetzt 4 Ringe fahre. Wenn man so was dann testen will braucht man dann auch schon reale Daten für. Falls sich einer der BMW Fahrer bereit erklärt die Zugangsdaten per PM für einen Test zu teilen kann man das mal machen.

Auf Euren Wunsch poste ich hier mal meine Gehversuche. Das ist bisher alles zusammengeschustert und nicht die feine Art zu coden. Hat noch einige Debugging Funktionen drin und man kann das (wenn dann die Zeit mal da ist) sicher viel schöner und kompakter lösen. Ich wollte primär mal sehen ob es geht und das tut es.

Wie gesagt, es sind lediglich Kopien der Leistungen von Menschen aus den anderen Foren mit kleinen Erweiterungen.
Das Grundkonzept erkläre ich nicht, auch das steht alles in den oben genannten Links.

Hiermit wird das Token angefordert:

<?

$username = "";
$password = "";

$auth_api = 'https://customer.bmwgroup.com/gcdm/oauth/authenticate';

// Init cURL
$ch = curl_init();

// Set cURL options
curl_setopt($ch, CURLOPT_URL, $auth_api);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/x-www-form-urlencoded'));
//die Daten in der nächsten Zeile (unterbrochen mit ....) müssen gemäss den im Post genannten Links und Foren selbst herauslesen und vollständig eingetragen werden 
curl_setopt($ch, CURLOPT_POSTFIELDS, 'username=' . urlencode( $username) . '&password=' . urlencode( $password) . '&client_id=dbf...dlIn0&locale=DE-de');
//curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false);
		
// Exec curl request
$response = curl_exec($ch);
$curl_error = curl_error($ch);

// Close connection
curl_close( $ch );


if(empty($response) || $response === false || !empty($curl_error)) 
	{
	$error_log = "Empty answer from Bearerinterface: ".$curl_error."
";
	
	SetValue(34450 /*[BMW\Token fehlerfrei]*/, false);
	return;
	}     
    

// Extract token
preg_match( '/access_token=([\w\d]+).*token_type=(\w+).*expires_in=(\d+)/', $response, $matches );


// Check token type
if ( empty( $matches[2] ) OR $matches[2] !== 'Bearer' ) 
	{
	$error_log = $error_log."No remote token received - username or password might be wrong: ".$response."
";

	SetValue(34450 /*[BMW\Token fehlerfrei]*/, false);
	return;
	}


SetValue(34450 /*[BMW\Token fehlerfrei]*/, true);
SetValue(13653 /*[BMW\Token]*/, $matches[1]);
SetValue(11459 /*[BMW\Token Expiration]*/, time() + $matches[3]);

?>

Hier werden die verschiedenen Daten angefordert:

<?

// Hier muss die vollständige Fahrgestellnummer des Fahrzeugs eingetragen werden (nicht nur die letzten 7 Stellen)
$vehicle = "";
// Die Adresse ist für die Schweiz. Vermutlich .de anstatt .ch für Deutschland?
$api = 'https://www.bmw-connecteddrive.ch/api';


//Token neu anfordern, wenn nicht mehr gültig
if (time() > GetValue(11459 /*[BMW\Token Expiration]*/)) IPS_RunScriptWait(21000 /*[BMW\Token anfordern]*/);
$token = GetValue(13653 /*[BMW\Token]*/);


//Fahrzeugdaten anfordern
$resp_array_1a=null;
$resp_array_1b=null;
$resp_array_2=null;
$resp_array_3=null;
$resp_array_4=null;
$resp_array_5=null;
$resp_array_6=null;
// Init cURL
$ch_1 = curl_init();
$ch_2 = curl_init();
$ch_3 = curl_init();
$ch_4 = curl_init();
$ch_5 = curl_init();
$ch_6 = curl_init();

// Set cURL options
curl_setopt( $ch_1, CURLOPT_URL, $api . '/vehicle/dynamic/v1/' . $vehicle . '?offset=-60' );
curl_setopt( $ch_1, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json' , 'Authorization: Bearer ' . $token) );
curl_setopt( $ch_1, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch_1, CURLOPT_FOLLOWLOCATION, true );
//curl_setopt( $ch_1, CURLOPT_SSL_VERIFYPEER, false);
        
curl_setopt( $ch_2, CURLOPT_URL, $api . '/vehicle/navigation/v1/' . $vehicle );
curl_setopt( $ch_2, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json' , 'Authorization: Bearer ' . $token ) );
curl_setopt( $ch_2, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch_2, CURLOPT_FOLLOWLOCATION, true );
//curl_setopt( $ch_2, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt( $ch_3, CURLOPT_URL, $api . '/vehicle/efficiency/v1/' . $vehicle );
curl_setopt( $ch_3, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json' , 'Authorization: Bearer ' . $token ) );
curl_setopt( $ch_3, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch_3, CURLOPT_FOLLOWLOCATION, true );
//curl_setopt( $ch_3, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt( $ch_4, CURLOPT_URL, $api . '/vehicle/remoteservices/chargingprofile/v1/' . $vehicle );
curl_setopt( $ch_4, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json' , 'Authorization: Bearer ' . $token ) );
curl_setopt( $ch_4, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch_4, CURLOPT_FOLLOWLOCATION, true );
//curl_setopt( $ch_4, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt( $ch_5, CURLOPT_URL, $api . '/me/service/mapupdate/download/v1/' . $vehicle );
curl_setopt( $ch_5, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json' , 'Authorization: Bearer ' . $token ) );
curl_setopt( $ch_5, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch_5, CURLOPT_FOLLOWLOCATION, true );
//curl_setopt( $ch_5, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt( $ch_6, CURLOPT_URL, $api . '/vehicle/remoteservices/v1/' . $vehicle . '/history' );
curl_setopt( $ch_6, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json' , 'Authorization: Bearer ' . $token) );
curl_setopt( $ch_6, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch_6, CURLOPT_FOLLOWLOCATION, true );
//curl_setopt( $ch_6, CURLOPT_SSL_VERIFYPEER, false);

        
// Build the multi-curl handle
$mh = curl_multi_init();
curl_multi_add_handle( $mh, $ch_1 );
curl_multi_add_handle( $mh, $ch_2 );
curl_multi_add_handle( $mh, $ch_3 );
curl_multi_add_handle( $mh, $ch_4 );
curl_multi_add_handle( $mh, $ch_5 );
curl_multi_add_handle( $mh, $ch_6 );

// Execute all queries simultaneously
$running = null;
do 
	{
	curl_multi_exec( $mh, $running );
    }
while ( $running );

// Close the handles
curl_multi_remove_handle( $mh, $ch_1 );
curl_multi_remove_handle( $mh, $ch_2 );
curl_multi_remove_handle( $mh, $ch_3 );
curl_multi_remove_handle( $mh, $ch_4 );
curl_multi_remove_handle( $mh, $ch_5 );
curl_multi_remove_handle( $mh, $ch_6 );
curl_multi_close( $mh );



// evaluate response of navigation interface
// -----------------------------------------------------------------------------------------------------------------------------------------------------------
$response_1 = curl_multi_getcontent( $ch_1 );
					
if(empty($response_1)) 
	{
	$error_log = ('Empty answer from navigation interface: '.curl_error($ch_1));
	} 
else 
	{
	// decode response 1a
	$resp_array_1a=json_decode( $response_1, true )['attributesMap'];
	$jsonerror=json_last_error();
	switch($jsonerror) 
		{
		case JSON_ERROR_NONE:
			break;
		case JSON_ERROR_DEPTH:
			$error_log_a = (' JSON1 - Maximale Stacktiefe überschritten'.">".$response_1."<");
			break;
		case JSON_ERROR_STATE_MISMATCH:
			$error_log_a = (' JSON1 - Unterlauf oder Nichtübereinstimmung der Modi'.">".$response_1."<");
			break;
		case JSON_ERROR_CTRL_CHAR:
			$error_log_a = (' JSON1 - Unerwartetes Steuerzeichen gefunden'.">".$response_1."<>".$ch_1."<");
			break;
		case JSON_ERROR_SYNTAX:
			$error_log_a = (' JSON1 - Syntaxfehler, ungültiges JSON'.">".$response_1."<");
			break;
		case JSON_ERROR_UTF8:
			$error_log_a = (' JSON1 - Missgestaltete UTF-8 Zeichen, möglicherweise fehlerhaft kodiert'.">".$response_1."<");
			break;
		default:
			$error_log_a = (' JSON1 - Unbekannter Fehler'.">".$response_1."<");
			break;
		}		

	// decode response 1b
	$resp_array_1b=json_decode( $response_1, true )['vehicleMessages']['cbsMessages'];
	$jsonerror=json_last_error();
	switch($jsonerror) 
		{
		case JSON_ERROR_NONE:
			break;
		case JSON_ERROR_DEPTH:
			$error_log_b = (' JSON1 - Maximale Stacktiefe überschritten'.">".$response_1."<");
			break;
		case JSON_ERROR_STATE_MISMATCH:
			$error_log_b = (' JSON1 - Unterlauf oder Nichtübereinstimmung der Modi'.">".$response_1."<");
			break;
		case JSON_ERROR_CTRL_CHAR:
			$error_log_b = (' JSON1 - Unerwartetes Steuerzeichen gefunden'.">".$response_1."<>".$ch_1."<");
			break;
		case JSON_ERROR_SYNTAX:
			$error_log_b = (' JSON1 - Syntaxfehler, ungültiges JSON'.">".$response_1."<");
			break;
		case JSON_ERROR_UTF8:
			$error_log_b = (' JSON1 - Missgestaltete UTF-8 Zeichen, möglicherweise fehlerhaft kodiert'.">".$response_1."<");
			break;
		default:
			$error_log_b = (' JSON1 - Unbekannter Fehler'.">".$response_1."<");
			break;
		}			
	}

// Fehler
if (!empty($error_log))
	{
	SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, false);
	return;
	}
if (!empty($error_log_a))
	{
	SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, false);
	return;
	}
if (!empty($error_log_b))
	{
	SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, false);
	return;
	}

// Keine Fehler
SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, true);

print_r($resp_array_1a, true);
print_r($resp_array_1b, true);
		
// evaluate response of application interface
// -----------------------------------------------------------------------------------------------------------------------------------------------------------
$response_2 = curl_multi_getcontent( $ch_2 );
		
if(empty($response_2)) 
	{
	$error_log = (' Empty answer from application interface: '.curl_error($ch_2));
	} 
else 
	{
	$resp_array_2=json_decode( $response_2, true);
	$jsonerror=json_last_error();
	switch($jsonerror) 
		{
		case JSON_ERROR_NONE:
			break;
		case JSON_ERROR_DEPTH:
			$error_log = (' JSON2 - Maximale Stacktiefe überschritten'.">".$response_2."<");
			break;
		case JSON_ERROR_STATE_MISMATCH:
			$error_log = (' JSON2 - Unterlauf oder Nichtübereinstimmung der Modi'.">".$response_2."<");
			break;
		case JSON_ERROR_CTRL_CHAR:
			$error_log = (' JSON2 - Unerwartetes Steuerzeichen gefunden'.">".$response_2."<>".$ch_2."<");
			break;
		case JSON_ERROR_SYNTAX:
			$error_log = (' JSON2 - Syntaxfehler, ungültiges JSON'.">".$response_2."<");
			break;
		case JSON_ERROR_UTF8:
			$error_log = (' JSON2 - Missgestaltete UTF-8 Zeichen, möglicherweise fehlerhaft kodiert'.">".$response_2."<");
			break;
		default:
			$error_log = (' JSON2 - Unbekannter Fehler'.">".$response_2."<");
			break;
		}			
	}

// Fehler
if (!empty($error_log))
	{
	SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, false);	
	return;
	}

// Keine Fehler
SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, true);

print_r($resp_array_2, true);


// evaluate response of efficiency interface
// -----------------------------------------------------------------------------------------------------------------------------------------------------------
$response_3 = curl_multi_getcontent( $ch_3 );
		
if(empty($response_3)) 
	{
	$error_log = (' Empty answer from application interface: '.curl_error($ch_3));
	} 
else 
	{
	$resp_array_3=json_decode( $response_3, true);
	$jsonerror=json_last_error();
	switch($jsonerror) 
		{
		case JSON_ERROR_NONE:
			break;
		case JSON_ERROR_DEPTH:
			$error_log = (' JSON2 - Maximale Stacktiefe überschritten'.">".$response_3."<");
			break;
		case JSON_ERROR_STATE_MISMATCH:
			$error_log = (' JSON2 - Unterlauf oder Nichtübereinstimmung der Modi'.">".$response_3."<");
			break;
		case JSON_ERROR_CTRL_CHAR:
			$error_log = (' JSON2 - Unerwartetes Steuerzeichen gefunden'.">".$response_3."<>".$ch_3."<");
			break;
		case JSON_ERROR_SYNTAX:
			$error_log = (' JSON2 - Syntaxfehler, ungültiges JSON'.">".$response_3."<");
			break;
		case JSON_ERROR_UTF8:
			$error_log = (' JSON2 - Missgestaltete UTF-8 Zeichen, möglicherweise fehlerhaft kodiert'.">".$response_3."<");
			break;
		default:
			$error_log = (' JSON2 - Unbekannter Fehler'.">".$response_3."<");
			break;
		}			
	}

// Fehler
if (!empty($error_log))
	{
	SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, false);		
	return;
	}

// Keine Fehler
SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, true);

print_r($resp_array_3, true);

// evaluate response of charging interface
// -----------------------------------------------------------------------------------------------------------------------------------------------------------
$response_4 = curl_multi_getcontent( $ch_4 );
		
if(empty($response_4)) 
	{
	$error_log = (' Empty answer from application interface: '.curl_error($ch_4));
	} 
else 
	{
	$resp_array_4=json_decode( $response_4, true);
	$jsonerror=json_last_error();
	switch($jsonerror) 
		{
		case JSON_ERROR_NONE:
			break;
		case JSON_ERROR_DEPTH:
			$error_log = (' JSON2 - Maximale Stacktiefe überschritten'.">".$response_4."<");
			break;
		case JSON_ERROR_STATE_MISMATCH:
			$error_log = (' JSON2 - Unterlauf oder Nichtübereinstimmung der Modi'.">".$response_4."<");
			break;
		case JSON_ERROR_CTRL_CHAR:
			$error_log = (' JSON2 - Unerwartetes Steuerzeichen gefunden'.">".$response_4."<>".$ch_4."<");
			break;
		case JSON_ERROR_SYNTAX:
			$error_log = (' JSON2 - Syntaxfehler, ungültiges JSON'.">".$response_4."<");
			break;
		case JSON_ERROR_UTF8:
			$error_log = (' JSON2 - Missgestaltete UTF-8 Zeichen, möglicherweise fehlerhaft kodiert'.">".$response_4."<");
			break;
		default:
			$error_log = (' JSON2 - Unbekannter Fehler'.">".$response_4."<");
			break;
		}			
	}

// Fehler loggen
if (!empty($error_log))
	{
	SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, false);	
	
	$filename = "C:\Hausleitsystem\Logs\BMW-CD-Data_".date("Y", time()).".txt";
	$file = fopen($filename, 'a');
	$data = date("d.m.Y H:i:s  -  ", time())."Response 4:   ";
	$data = $data.$error_log."

";
	$data = $data.$response_4."
";
	$data = $data."----------------------------------------------------------------------"."


";	
	fwrite($file, utf8_decode($data));
	fclose($file);
	
	return;
	}

// Keine Fehler
SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, true);

print_r($resp_array_4, true);


// evaluate response of map interface
// -----------------------------------------------------------------------------------------------------------------------------------------------------------
$response_5 = curl_multi_getcontent( $ch_5 );
		
if(empty($response_5)) 
	{
	$error_log = (' Empty answer from application interface: '.curl_error($ch_5));
	} 
else 
	{
	$resp_array_5=json_decode( $response_5, true);
	$jsonerror=json_last_error();
	switch($jsonerror) 
		{
		case JSON_ERROR_NONE:
			break;
		case JSON_ERROR_DEPTH:
			$error_log = (' JSON2 - Maximale Stacktiefe überschritten'.">".$response_5."<");
			break;
		case JSON_ERROR_STATE_MISMATCH:
			$error_log = (' JSON2 - Unterlauf oder Nichtübereinstimmung der Modi'.">".$response_5."<");
			break;
		case JSON_ERROR_CTRL_CHAR:
			$error_log = (' JSON2 - Unerwartetes Steuerzeichen gefunden'.">".$response_5."<>".$ch_5."<");
			break;
		case JSON_ERROR_SYNTAX:
			$error_log = (' JSON2 - Syntaxfehler, ungültiges JSON'.">".$response_5."<");
			break;
		case JSON_ERROR_UTF8:
			$error_log = (' JSON2 - Missgestaltete UTF-8 Zeichen, möglicherweise fehlerhaft kodiert'.">".$response_5."<");
			break;
		default:
			$error_log = (' JSON2 - Unbekannter Fehler'.">".$response_5."<");
			break;
		}			
	}

// Fehler loggen
if (!empty($error_log))
	{
	SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, false);	
	return;
	}

// Keine Fehler
SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, true);

print_r($resp_array_5, true);


// evaluate response of map interface
// -----------------------------------------------------------------------------------------------------------------------------------------------------------
$response_6 = curl_multi_getcontent( $ch_6 );
		
if(empty($response_6)) 
	{
	//$error_log = (' Empty answer from application interface: '.curl_error($ch_6));
	} 
else 
	{
	$resp_array_6=json_decode( $response_6, true);
	$jsonerror=json_last_error();
	switch($jsonerror) 
		{
		case JSON_ERROR_NONE:
			break;
		case JSON_ERROR_DEPTH:
			$error_log = (' JSON2 - Maximale Stacktiefe überschritten'.">".$response_6."<");
			break;
		case JSON_ERROR_STATE_MISMATCH:
			$error_log = (' JSON2 - Unterlauf oder Nichtübereinstimmung der Modi'.">".$response_6."<");
			break;
		case JSON_ERROR_CTRL_CHAR:
			$error_log = (' JSON2 - Unerwartetes Steuerzeichen gefunden'.">".$response_6."<>".$ch_6."<");
			break;
		case JSON_ERROR_SYNTAX:
			$error_log = (' JSON2 - Syntaxfehler, ungültiges JSON'.">".$response_6."<");
			break;
		case JSON_ERROR_UTF8:
			$error_log = (' JSON2 - Missgestaltete UTF-8 Zeichen, möglicherweise fehlerhaft kodiert'.">".$response_6."<");
			break;
		default:
			$error_log = (' JSON2 - Unbekannter Fehler'.">".$response_6."<");
			break;
		}			
	}

// Fehler loggen
if (!empty($error_log))
	{
	SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, false);	
	return;
	}

// Keine Fehler
SetValue(20030 /*[BMW\Fahrzeugdaten fehlerfrei]*/, true);
SetValue(23655 /*[BMW\Fahrzeugdaten fehlerfrei\Zeitpunkt letzter fehlerfreier Empfang]*/, time());

print_r($resp_array_6, true);


// Daten auswerten
include '59002 /*[BMW\Fahrzeugdaten auswerten]*/.ips.php';


?>

Hi danke für die Scripte

Bei der Tokenabfrage hängt es aber schon bei mir.

 Empty answer from Bearerinterface: SSL certificate problem: unable to get local issuer certificate

Die client_id ist doch der 100 byte lange string?

Moin,

das wäre schon recht cool …

Grüße
Thomas

N’abend zusammen.

Vielen herzlichen Dank! Läuft bei mir :wink:

Ich musste aber ein paar Dinge anpassen. Wundert mich das es bei Dir so läuft :confused:

Das Token Script wollte unbedingt „redirect_uri“ als Parameter für die Authentifizierung haben. Per G**gle habe ich eine komplette URL gefunden!

Da ich nur einen „normalen“ BMW habe :eek:- also nix mit Elektro - ist das Script immer bei dem Charging Profile ausgestiegen!

Das habe ich bei mir mit dem Abruf der Bilder vom Auto ersetzt:


curl_setopt( $ch_4, CURLOPT_URL, $api . '/vehicle/image/v1/' . $vehicle . '?startAngle=0&stepAngle=10&width=780' ); 

Sonst alles bestens - vielen Dank!

Nein, die client-id ist eine normal GUID! Findet man aber leicht im Internet!

Ciao

Mal eine Frage am Rande, kennt jemand vielleicht ähnliches für Audi Connect?