Ankündigung

Einklappen
Keine Ankündigung bisher.

Tesla & Edomi

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Tesla & Edomi

    Hallo zusammen,

    Mein Tesla Model 3 ist vor kurzem geliefert worden.
    Jetzt habe ich natürlich nach einem Baustein für Edomi geschaut, aber nichts gefunden. Nur einen Beitrag in den das Laden kurz erwähnt wird von Hartwig.
    Kurz Hartwig angeschrieben und siehe da er hat tatsächlichen einen beta Baustein den er jedoch nicht mehr pflegt und im Moment auch keine Zeit hat. Er hat ihn mir aber zur Verfügung gestellt und hat auch nichts dagegen das ich Ihn jetzt mit euch teile.
    Das Problem ist das einige Funktionen nicht / nicht mehr funktionieren

    Was mir aufgefallen ist:
    1. logging funktioniert nicht (wäre ja wichtig für die Fehlersuche)
    2. Aufwecken geht nicht
    3. Pollen geht nicht
    Getestet und funktioniert (wenn Auto nicht schläft)
    1. Türen auf und zu
    2. Laden stoppen und starten
    3. Setzen vom Ladelimit
    Basieren tut es auf der rekonstruierten API von Tesla
    https://www.teslaapi.io

    Wer hat Lust sich mit mir den Code etwas näher anzuschauen um die Fehler zu beseitigen und evtl. neue Funktionen hinzuzufügen, da ich nicht der PHP Expert bin und mich darin noch nicht so zurecht finde.
    Ich habe zwar auch ein paar. Bausteine online, aber die sind etwas einfacher „gestrickt“

    Wichtig für mich wäre das ich das Auto automatisch bei genügend PV Ertrag automatisch laden kann. Das funktioniert zwar schon, aber nur wenn das Auto nicht schläft.

    Hier der Code


    PHP-Code:

    ###[DEF]###
    [name = Tesla API]

    [e#1 = Autostart #init=1]
    [e#2 = Username-Tesla Account]
    [e#3 = Passwort-Tesla Account]


    [e#9 =---Kommandos-- ]
    [e#10 = wakeup]
    [e#11 = lock doors]
    [e#12 = unlock doors]
    [e#13 = Set Charge Limit %]
    [e#14 = Set Charge Limit to max]
    [e#15 = Set Charge Limit to standard]
    [e#16 = Start Charging]
    [e#17 = Stop Charging]
    [e#18 = Honk]
    [e#19 = Ladeklappe öffnen]
    [e#29 = read after write #init=1]
    [e#30 = debug]
    [e#31 = PollInterval in s #init=100]

    [a#1 = Aktiv]
    [a#2 = charge_limit_soc]
    [a#3 =charge_limit_soc_std]
    [a#4 =charge_limit_soc_min]
    [a#5 = charge_limit_soc_max]
    [a#6 =charge_limit_soc_std]
    [a#7 = charge_to_max_range]
    [a#8 = battery_range]
    [a#9 = est_battery_range]
    [a#10 = ideal_battery_range]
    [a#11 = battery_level]
    [a#12 = charger_voltage]
    [a#13 = time_to_full_charge]
    [a#14 = charge_port_door_open]
    [a#15 = charge_current_request]

    [a#18 = shift_state]
    [a#19 = speed]
    [a#20 = power]
    [a#21 = native_latitude]
    [a#22 = native_longitude]
    [a#23 = heading]

    [a#26 = autopark_state_v2]
    [a#27 = homelink_nearby]
    [a#28 = locked]
    [a#29 = odometer]
    [a#30 = vehicle_name]
    [a#33 = Vehicle_ID]
    [a#34 = Daemon Aktiv]
    [a#35 = Debug]

    [v#100 = 0.1 ]
    [v#101 = 19510010 ]
    [v#102 = 'Tesla ' ]
    [v#103 = 0 ]
    [v#104 = 0 ]
    [v#105 = 0 ]
    [v#106 = 0 ] Debug-Level wird über E30 gesetzt
    [v#107 = 0 ] wird zusammengesetzt
    [v#108 = 0 ] Array mit Loglevelnamen
    ###[/DEF]###


    ###[HELP]###
    Tesla Anbindung über Tesla Account

    E29 Read after write, wenn 1 wird direkt nach ausführen eines Kommandos nochmals abgefragt

    ###[/HELP]###


    ###[LBS]###

    <?
    function LB_LBSID($id) {

    if ($E=logic_getInputs($id)) {

    if (logic_getStateExec($id)==0){
    if ( $E[1]['value'] ){

    logic_setVar($id,106,$E[30]['value']); //loglevel
    $version = logic_getVar($id, 100);
    $lbsNo = logic_getVar($id, 101);
    $logName = logic_getVar($id, 102) . "-LBS$lbsNo";
    $logName = preg_replace('/ /', '_', $logName);
    logic_setVar($id,107,$logName); // V#107 mit Logname belegen
    $logLevelNames = array('none','Info','Info ausf.','Debug' );

    logic_setInputsQueued($id,$E);
    logic_callExec(LBSID,$id);
    }
    } else {
    logic_setInputsQueued($id,$E);
    }
    }
    }
    ?>



    ###[/LBS]###

    ###[EXEC]###
    <?
    require(dirname(__FILE__)."/../../../../main/include/php/incl_lbsexec.php");

    set_time_limit(0);

    restore_error_handler();
    error_reporting(0);

    sql_connect();

    //------------------------------------------------------------------------------------------------------------
    $cmdInterval=0.5; //Befehlsintervall in Sekunden
    $pollMaxInterval=100; //max. Abfrageintervall in Sekunden
    $pollInterval=$E[31]['value'];
    //------------------------------------------------------------------------------------------------------------

    $pollTimerOld=0;
    $cmdTimerOld=0;

    try {

    if ($E=logic_getInputs($id)) {
    $tesla = new Tesla();
    $tesla->setClientId("e4a9949fcfa04068f59abb5a658f2bac0a34 28e4652315490b659d5ab3f35a9e");
    $tesla->setClientSecret("c75f14bbadc8bee3a7594412c31416f8 300256d7668ea7e6e7f06727bfb9d220");
    $tesla->getAccessToken($E[2]['value'],$E[3]['value']);

    // if (!isset($token['access_token'])){
    // logic_setOutput($id,35,"token kann nicht ermittelt werden");
    // break;
    // }




    $vehicles=($tesla->vehicles());
    $vehicle_id= $vehicles['response'][0]['id_s']; //vehicle ID zuweisen

    logic_setOutput($id,33,$vehicle_id);

    $tesla->setVehicleId($vehicle_id);
    #$tesla->setVehicleId("45555003714663208");
    #echo "<pre>".htmlentities(print_r($tesla->vehicles()['response'], true))."</pre>";
    #echo "<pre>".htmlentities(print_r($tesla->allData(), true))."</pre>";$gui_settings=$tesla->guiSettings();

    $test=$tesla->access_test();
    if ($test==false){
    //keine Verbindung
    logic_setOutput($id,35,"HTTP 408 Timeout- starte wakeup");
    $tesla->wakeUp();
    return;
    }

    $gui_settings=$tesla->guiSettings();
    if ($gui_settings['gui_charge_rate_units']=='km/hr'){
    $faktor = 1.60934;
    } else {$faktor=1;}


    }

    logic_setOutput($id,34,1);

    while ( logic_getEdomiState()==1 && (!isEmpty($vehicle_id))) {

    $doPoll=false;
    $doCmd=false;
    if ((getMicrotime()-$pollTimerOld)>=$pollInterval) {
    $pollTimerOld=getMicrotime();
    $doPoll=true;
    }
    if ((getMicrotime()-$cmdTimerOld)>=$cmdInterval) {
    $cmdTimerOld=getMicrotime();
    $doCmd=true;
    }

    if ($doPoll || $doCmd) {
    if ($V=logic_getVars($id)) {

    //Status-Polling
    if ($doPoll) {


    $chargeState=$tesla->chargeState();
    logic_setOutput($id,1,$chargeState["charging_state"]);
    logic_setOutput($id,2,$chargeState["charge_limit_soc"]);
    logic_setOutput($id,3,$chargeState["charge_limit_soc_std"]);
    logic_setOutput($id,4,$chargeState["charge_limit_soc_min"]);
    logic_setOutput($id,5,$chargeState["charge_limit_soc_max"]);
    logic_setOutput($id,6,$chargeState["charge_limit_soc_std"]);
    logic_setOutput($id,7,$chargeState["charge_to_max_range"]);
    logic_setOutput($id,8,round($faktor *$chargeState["battery_range"]));
    logic_setOutput($id,9,round($faktor *$chargeState["est_battery_range"]));
    logic_setOutput($id,10,round($faktor *$chargeState["ideal_battery_range"]));
    logic_setOutput($id,11,$chargeState["battery_level"]);
    logic_setOutput($id,12,$chargeState["charger_voltage"]);
    logic_setOutput($id,13,$chargeState["time_to_full_charge"]);
    logic_setOutput($id,14,$chargeState["charge_port_door_open"]);
    logic_setOutput($id,15,$chargeState["charge_current_request"]);

    $drive_state = $tesla->driveState();
    logic_setOutput($id,18,intval($drive_state["shift_state"]));
    logic_setOutput($id,19,$drive_state["speed"]);
    logic_setOutput($id,20,$drive_state["power"]);
    logic_setOutput($id,21,$drive_state["native_latitude"]);
    logic_setOutput($id,22,$drive_state["native_longitude"]);
    logic_setOutput($id,23,$drive_state["heading"]);

    $vehicle_state= $tesla->vehicleState();
    logic_setOutput($id,26,$vehicle_state["autopark_state_v2"]);
    logic_setOutput($id,27,$vehicle_state["homelink_nearby"]);
    logic_setOutput($id,28,$vehicle_state["locked"]);
    logic_setOutput($id,29,round($faktor*$vehicle_stat e["odometer"]));
    logic_setOutput($id,30,$vehicle_state["vehicle_name"]);


    }

    //Befehl absetzen
    if ($doCmd) {
    if ($E=logic_getInputsQueued($id)) {
    if ($E[10]['refresh']&& $E[10]['value']==1){$tesla->wakeUp();}
    if ($E[11]['refresh']&& $E[11]['value']==1){$tesla->lockDoors() ;}
    if ($E[12]['refresh']&& $E[12]['value']==1){$tesla->unlockDoors();}
    if ($E[13]['refresh']){$tesla->setChargeLimit($E[13]['value']);}
    if ($E[14]['refresh']&& $E[14]['value']==1){$tesla->setChargeLimitToMaxRange();}
    if ($E[15]['refresh']&& $E[15]['value']==1){$tesla->setChargeLimitToStandard();}
    if ($E[16]['refresh']&& $E[16]['value']==1){$tesla->startCharging();}
    if ($E[17]['refresh']&& $E[17]['value']==1){$tesla->stopCharging();}
    if ($E[18]['refresh']&& $E[18]['value']==1){$tesla->honkHorn();}
    if ($E[19]['refresh']&& $E[19]['value']==1){$tesla->openChargePort();}

    if ($E[29]['value']==1){ //Anschliessend gleich wieder lesen
    //read after write
    $pollTimerOld=0;
    }

    }
    }
    if ($E[1]['value']==0) {break;}
    }
    logic_setOutput($id,34,0);
    }

    usleep(1000*100);
    }

    } catch (Exception $e) {
    echo 'Exception abgefangen: ', $e->getMessage(), "\n";
    }


    sql_disconnect();


    class TeslaException extends \Exception {}

    class Tesla
    {
    protected $apiBaseUrl = "https://owner-api.teslamotors.com/api/1";
    protected $tokenUrl = 'https://owner-api.teslamotors.com/oauth/token';
    protected $accessToken;
    protected $vehicleId = null;

    public function __construct(string $accessToken = null)
    {
    $this->accessToken = $accessToken;
    }



    public function setAccessToken(string $accessToken)
    {
    $this->accessToken = $accessToken;
    }


    public function access_test()
    {
    $d=$this->sendRequest('/data_request/charge_state');
    return $d['response'];
    }



    public function allData() #: array
    {
    $d=$this->sendRequest('/data');
    return $d['response'];
    }
    public function vehicles()
    {
    return $this->sendRequest('/vehicles');
    }

    public function setVehicleId($vehicleId)
    {
    $this->vehicleId = $vehicleId;
    }

    public function setClientId($clientId)
    {
    putenv('TESLA_CLIENT_ID=' . $clientId);
    }

    public function setClientSecret($clientSecret)
    {
    putenv('TESLA_CLIENT_SECRET=' . $clientSecret);
    }

    public function mobileEnabled() # : bool
    {
    $d=$this->sendRequest('/mobile_enabled');
    return $d['response'];
    }

    public function chargeState() # : array
    {
    $d=$this->sendRequest('/data_request/charge_state');
    return $d['response'];
    }

    public function climateState() # : array
    {
    $d=$this->sendRequest('/data_request/climate_state');
    return $d['response'];
    }

    public function driveState() # : array
    {
    $d=$this->sendRequest('/data_request/drive_state');
    return $d['response'];
    }

    public function guiSettings() # : array
    {
    $d=$this->sendRequest('/data_request/gui_settings');
    return $d['response'];
    }

    public function vehicleState() # : array
    {
    $d=$this->sendRequest('/data_request/vehicle_state');
    return $d['response'];
    }

    public function wakeUp() # : array
    {
    $d=$this->sendRequest('/wake_up', array(), 'POST');
    return $d['response'];
    }

    public function setValetMode($active = false, $pin = 0000) # : array
    {
    $params = array(
    'on' => $active,
    'pin' => $pin
    );
    $d=$this->sendRequest('/command/set_valet_mode', $params, 'POST');
    return $d['response'];
    }

    public function resetValetPin() # : array
    {
    $d=$this->sendRequest('/command/reset_valet_pin', array(), 'POST');
    return $d['response'];
    }

    public function openChargePort() # : array
    {
    $d=$this->sendRequest('/command/charge_port_door_open', array(), 'POST');
    return $d['response'];
    }

    public function setChargeLimitToStandard() # : array
    {
    $d=$this->sendRequest('/command/charge_standard', array(), 'POST');
    return $d['response'];
    }

    public function setChargeLimitToMaxRange() # : array
    {
    $d=$this->sendRequest('/command/charge_max_range', array(), 'POST');
    return $d['response'];
    }

    public function setChargeLimit($percent = 90) # : array
    {
    $params = array(
    'percent' => "$percent"
    );
    $d=$this->sendRequest('/command/set_charge_limit', $params, 'POST');
    return $d['response'];
    }


    public function startCharging() # : array
    {
    $d=$this->sendRequest('/command/charge_start', array(), 'POST');
    return $d['response'];
    }

    public function stopCharging() # : array
    {
    $d=$this->sendRequest('/command/charge_stop', array(), 'POST');
    return $d['response'];
    }

    public function flashLights() # : array
    {
    $d=$this->sendRequest('/command/flash_lights', array(), 'POST');
    return $d['response'];
    }

    public function honkHorn() # : array
    {
    $d=$this->sendRequest('/command/honk_horn', array(), 'POST');
    return $d['response'];
    }

    public function unlockDoors() # : array
    {
    $d=$this->sendRequest('/command/door_unlock', array(), 'POST');
    return $d['response'];
    }

    public function lockDoors() # : array
    {
    $d=$this->sendRequest('/command/door_lock', array(), 'POST');
    return $d['response'];
    }

    public function setTemperature($driverDegreesCelcius = 20.0, $passengerDegreesCelcius = 20.0)# : array
    {
    $d=$this->sendRequest('/command/set_temps?driver_temp=' . $driverDegreesCelcius . '&passenger_temp=' . $passengerDegreesCelcius, array(), 'POST');
    return $d['response'];
    }

    public function startHvac() # : array
    {
    $d=$this->sendRequest('/command/auto_conditioning_start', array(), 'POST');
    return $d['response'];
    }

    public function stopHvac() # : array
    {
    $d=$this->sendRequest('/command/auto_conditioning_stop', array(), 'POST');
    return $d['response'];
    }

    public function movePanoramicRoof($state = 'vent', $percent = 50) # : array
    {
    $d=$this->sendRequest('/command/sun_roof_control?state=' . $state . '&percent=' . $percent, array(), 'POST');
    return $d['response'];
    }

    public function remoteStart($password = '') # : array
    {
    $d=$this->sendRequest('/command/remote_start_drive?password=' . $password, array(), 'POST');
    return $d['response'];
    }

    public function openTrunk() # : array
    {
    $d=$this->sendRequest('/command/trunk_open?which_trunk=rear', array(), 'POST');
    return $d['response'];
    }


    public function getAccessToken($username, $password)
    {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $this->tokenUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Accept: application/json',
    'User-Agent: Mozilla/5.0 (Linux; Android 9.0.0; VS985 4G Build/LRX21Y; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.83 Mobile Safari/537.36',
    'X-Tesla-User-Agent: TeslaApp/3.4.4-350/fad4a582e/android/9.0.0',
    ));
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array(
    'grant_type' => 'password',
    'client_id' => getenv('TESLA_CLIENT_ID'),
    'client_secret' => getenv('TESLA_CLIENT_SECRET'),
    'email' => $username,
    'password' => $password,
    )));

    // JM-2018-09-16: added because we had problems with the SSL certificate verification
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    $apiResult = curl_exec($ch);
    print(curl_error($ch));
    $apiResultJson = json_decode($apiResult, true);

    curl_close($ch);

    $this->accessToken = $apiResultJson['access_token'];

    return $apiResultJson;
    }





    protected function sendRequest($endpoint, $params = array(''), $method = 'GET')
    {
    $ch = curl_init();

    if ($endpoint !== '/vehicles' && ! is_null($this->vehicleId)) {
    $endpoint = '/vehicles/' . $this->vehicleId . $endpoint;
    }

    curl_setopt($ch, CURLOPT_URL, $this->apiBaseUrl . $endpoint);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Accept: application/json',
    'User-Agent: Mozilla/5.0 (Linux; Android 9.0.0; VS985 4G Build/LRX21Y; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.83 Mobile Safari/537.36',
    'X-Tesla-User-Agent: TeslaApp/3.4.4-350/fad4a582e/android/9.0.0',
    'Authorization: Bearer ' . $this->accessToken,
    ));

    // JM-2018-09-16: added because we had problems with the SSL certificate verification
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    if ($method == 'POST' || $method == 'PUT' || $method == 'DELETE') {
    if ($method == 'POST') {
    curl_setopt($ch, CURLOPT_POST, true);
    }
    if (in_array($method, array('PUT', 'DELETE'))) {
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    }
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
    }

    $apiResult = curl_exec($ch);
    $headerInfo = curl_getinfo($ch);
    $apiResultJson = json_decode($apiResult, true);
    curl_close($ch);

    $result = array();
    if ($apiResult === false) {
    $result['errorcode'] = 0;
    $result['errormessage'] = curl_error($ch);

    throw new TeslaException($result['errormessage'], $result['errorcode']);
    }

    if (! in_array($headerInfo['http_code'], array('200', '201', '204'))) {
    //print_r($headerInfo);
    $result['errorcode'] = $headerInfo['http_code'];
    if (isset($apiresult)) {
    $result['errormessage'] = $apiresult;
    }

    if(array_key_exists('errormessage',$result)){
    throw new TeslaException($result['errormessage'], $result['errorcode']);
    }else{
    throw new TeslaException('Error occured', $result['errorcode']);
    //return false;
    }

    }

    if(isset($apiResultJson)){
    return $apiResultJson;
    }else{
    return $apiResult;
    }
    }
    }




    ?>
    ###[/EXEC]###

    Grüße Frank
Lädt...
X