wez3 / volkswagen-carnet-client

A Python client to use Volkswagen CarNet
40 stars 21 forks source link

carnet-app.py, my solution... #9

Open TMD-Burger opened 6 years ago

TMD-Burger commented 6 years ago

Hello!

As a hobbyist, I'm always happy when someone somewhere in the world has already done something in a certain direction and that's why I wanted to give something to the community. Here are my "research" with the "app interface", which in my opinion is much faster. I'm sure one or the other may need something. This is the python3-code, which has read-only access for my purposes (so far): (Since we only have a vw car with carnet, I have decided (for speed reasons) to simply omit the vehicle search function and program the VIN firmly.)

#!/usr/bin/env python

import sys
import requests
import json
import pprint

# Login information for the VW CarNet app
CARNET_USERNAME = ' '       #login (email)
CARNET_PASSWORD = ' '               #password
VIN = " "                   #put in here your vehicle ID "WVWZZZ......"

# Fake the VW CarNet mobile app headers
HEADERS = { 'Accept': 'application/json',
            'X-App-Name': 'eRemote',
            'X-App-Version': '1.0.0',
            'User-Agent': 'okhttp/2.3.0' }

#JSON prettyprint
def pp_json(json_thing, sort=True, indents=4):
    if type(json_thing) is str:
        print(json.dumps(json.loads(json_thing), sort_keys=sort, indent=indents))
    else:
        print(json.dumps(json_thing, sort_keys=sort, indent=indents))
    return None

#carNet Login
def carNetLogon():
    r = requests.post('https://msg.volkswagen.de/fs-car/core/auth/v1/VW/DE/token', data = {'grant_type':'password',
                                                                                            'username':CARNET_USERNAME,
                                                                                            'password':CARNET_PASSWORD}, headers=HEADERS)
    responseData = json.loads(r.content)
    token = responseData.get("access_token")
    HEADERS["Authorization"] = "AudiAuth 1 " + token
    return token

#edit to find endpoints
def getTest():
    #honk and flash (incomplete)
    #r = requests.post('https://msg.volkswagen.de/fs-car/bs/rhf/v1/VW/DE/vehicles/' + VIN + '/honkAndFlash', headers=HEADERS)

    #car status
    #r = requests.get('https://msg.volkswagen.de/fs-car/bs/vsr/v1/VW/DE/vehicles/' + VIN + '/status', headers=HEADERS)

    #car battery charger
    r = requests.get('https://msg.volkswagen.de/fs-car/bs/batterycharge/v1/VW/DE/vehicles/' + VIN + '/charger', headers=HEADERS)

    #car details
    #r = requests.get('https://msg.volkswagen.de/fs-car/promoter/portfolio/v1/VW/DE/vehicle/' + VIN + '/carportdata', headers=HEADERS)

    responseData = json.loads(r.content)
    pp_json(responseData)

if __name__ == "__main__":
    token = carNetLogon()
    getTest()

Looking for the endpoints of the vw-server, I went the way on "android-studio" and found some variables. maybe valuable for someone: (What is missing here is the last expression of url)

#list of services

# "mbbServiceList": {
# "honkAndFlashService": "/bs/rhf/v1/VW/DE/",
# "geofenceService": "/bs/geofencing/v1/VW/DE/",
# "userPromoterService": "/promoter/portfolio/v1/VW/DE/",
# "tripStatisticService": "/bs/tripstatistics/v1/VW/DE/",
# "rolesAndRights": "/rolesrights/operationlist/v1/VW/DE/",
# "batteryChargingService": "/bs/batterycharge/v1/VW/DE/",
# "authService": "/core/auth/v1/VW/DE/",
# "preTripClimatisationService": "/bs/climatisation/v1/VW/DE/",
# "vehicleDataService": "/vehicleMgmt/vehicledata/v2/VW/DE/",
# "carFinderService": "/bs/cf/v1/VW/DE/",
# "poiService": "/destinationfeedservice/mydestinations/v1/VW/DE/",
# "operationListV2": "/rolesrights/operationlist/v2/VW/DE/",
# "vhrService": "/vehiclehealthreport/myreports/v1/VW/DE/",
# "registerPushService": "/pns/client/v1/VW/DE/",
# "doorLockUnlockService": "/bs/rlu/v1/VW/DE/",
# "userVehiclesService": "/usermanagement/users/v1/VW/DE/",
# "speedAlertService": "/bs/speedalert/v1/VW/DE/",
# "vehicleStatusService": "/bs/vsr/v1/VW/DE/",
# "rdtService": "/bs/departuretimer/v1/VW/DE/"

Since my origin plan was to make a "homekit to carnet bridge", which i rejected because of insufficient fexibility on the part of homekit. To become the ability of access those information as fast as possible, here is a php script, which practically does the same: (The return-values are in german, but its easy to change, requirements are to install composer, then requests. Google knows how to do that.)

<?php
setlocale (LC_ALL, 'de_DE');

require __DIR__ . '/vendor/autoload.php';

$username = ' ';        
$password = ' ';                
$vin = 'WVWZZ...';                  

$url = 'https://msg.volkswagen.de/fs-car/core/auth/v1/VW/DE/token'; 
$headers = array('Accept' => 'application/json', 'X-App-Name' => 'eRemote', 'X-App-Version' => '1.0.0', 'User-Agent' => 'okhttp/2.3.0');
$options = array('grant_type' => 'password', 'username' => $username, 'password' => $password);
$response = Requests::post($url, $headers, $options);
$body = json_decode($response->body);
$token = $body->access_token;
$headers = array('Accept' => 'application/json', 'X-App-Name' => 'eRemote', 'X-App-Version' => '1.0.0', 'User-Agent' => 'okhttp/2.3.0','Authorization' => 'AudiAuth 1 '.$token);

$request = Requests::get('https://msg.volkswagen.de/fs-car/bs/batterycharge/v1/VW/DE/vehicles/'.$vin.'/charger', $headers);
$charger = json_decode($request->body, TRUE);

$request = Requests::get('https://msg.volkswagen.de/fs-car/bs/vsr/v1/VW/DE/vehicles/'.$vin.'/status', $headers);
$status = json_decode($request->body, TRUE);

$stat = strtotime($status['StoredVehicleDataResponse']['vehicleData']['data'][0]['field'][0]['tsCarSent']);
$kmStand = $status['StoredVehicleDataResponse']['vehicleData']['data'][0]['field'][0]['milCarSent'];
$kmService = $status['StoredVehicleDataResponse']['vehicleData']['data'][2]['field'][2]['value'];
$timeService = $status['StoredVehicleDataResponse']['vehicleData']['data'][2]['field'][3]['value'];
$aussenTempK = $status['StoredVehicleDataResponse']['vehicleData']['data'][4]['field'][1]['value'];
$aussenTemp = round(($aussenTempK/10 - 273.15));
$handbremse = $status['StoredVehicleDataResponse']['vehicleData']['data'][4]['field'][2]['value'];
if ($handbremse == 1){
    $handbremse = 'gelöst';
} else {
    $handbremse = 'angezogen';
}
$akkuStand = $status['StoredVehicleDataResponse']['vehicleData']['data'][4]['field'][3]['value'];
$reichweite = $status['StoredVehicleDataResponse']['vehicleData']['data'][4]['field'][6]['value'];
$chargeCurrent = $charger['charger']['status']['batteryStatusData']['stateOfCharge']['content'];
$chargeTimeRemain = $charger['charger']['status']['batteryStatusData']['remainingChargingTime']['content'];
$chargeState = $charger['charger']['status']['chargingStatusData']['chargingState']['content'];
if ($chargeState == 'charging') {
    $chargeState = 'ladet mit '.$chargeCurrent.'A, und endet in '.date('g:i', mktime(0, $chargeTimeRemain));
} else {
    $chargeState = 'ladet nicht';
}
$chargePlugLock = $charger['charger']['status']['plugStatusData']['lockState']['content'];
if ($chargePlugLock == 'locked') {
    $chargePlugLock = 'verriegelt';
} else {
    $chargePlugLock = 'nicht verriegelt';
}
$chargePlugConn = $charger['charger']['status']['plugStatusData']['plugState']['content'];
if ($chargePlugConn == 'connected'){
    $chargePlugConn = 'angeschlossen, '.$chargePlugLock;
} else {
    $chargePlugConn = 'nicht angeschlossen';
}

?>

(Here are a screenshot of my "fast" info-website", to get the informations as fast as possible: bildschirmfoto 2018-03-03 um 06 54 56

Have fun with it! Stefan ;-)

wez3 commented 6 years ago

Great work :) Thanks for sharing

Reimai73 commented 5 years ago

I would be Interested If this could be Installed on a raspberry pie with loxberry Image. I have a e golf at home and would like to see some Information like battery status on my loxone smart Home.

Best regards from Austria Reinhard

birgersp commented 5 years ago

Nice work, but shouldn't you create a repo for this? Or create a fork, update this project and submit a PR?

ottopaulsen commented 5 years ago

Hi, is this still working, after name-change to We Connect? I cannot get the token-url to work, or to be precise, I am getting unsupported_grant_type exception.

mikaelho commented 5 years ago

@ottopaulsen, see issue https://github.com/wez3/volkswagen-carnet-client/issues/16