PHP-Code:
<?
$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."\n";
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."\n";
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:
PHP-Code:
<?
// 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."\r\n\r\n";
$data = $data.$response_4."\r\n";
$data = $data."----------------------------------------------------------------------"."\r\n\r\n\r\n";
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';
?>