DurgNomis-drol / mytoyota

Python client for Toyota Connected Services API
MIT License
72 stars 28 forks source link

Runtime Error, with intial execution #10

Closed CM000n closed 3 years ago

CM000n commented 3 years ago

Describe the bug Hi, when I try to run your code I get a runtimer error: OS: Windows 10 Python Version: 3.8.7 64-bit

RuntimeError                              Traceback (most recent call last)
<ipython-input-3-c06ef9828b3b> in <module>
     22 
     23 loop = asyncio.get_event_loop()
---> 24 loop.run_until_complete(get_cars())
     25 loop.close()

~\AppData\Local\Programs\Python\Python38\lib\asyncio\base_events.py in run_until_complete(self, future)
    590         """
    591         self._check_closed()
--> 592         self._check_running()
    593 
    594         new_task = not futures.isfuture(future)

~\AppData\Local\Programs\Python\Python38\lib\asyncio\base_events.py in _check_running(self)
    550     def _check_running(self):
    551         if self.is_running():
--> 552             raise RuntimeError('This event loop is already running')
    553         if events._get_running_loop() is not None:
    554             raise RuntimeError(

To Reproduce

  1. Install mytoyota via pip install git+https://github.com/DurgNomis-drol/mytoyota.git
  2. Run
    
    import aiohttp
    import asyncio
    from mytoyota.client import MyT

username = "MYUSER" password = "MYPW" locale = "de-de" session = aiohttp.ClientSession()

client = MyT(locale=locale, session=session)

print("Performing login...") client.perform_login(username=username, password=password)

async def get_cars(): print("Retrieving cars...") valid, cars = client.get_cars()

if valid:
    print(cars)
    return

loop = asyncio.get_event_loop() loop.run_until_complete(get_cars()) loop.close()


3. See error

**Expected behavior**
Get a list with valid cars
DurgNomis-drol commented 3 years ago

Thanks for trying 😊

I am gonna rewrite how this works, as other problems have risen anyway. I will ping you here in a couple of days when i have something for you to try again.

CM000n commented 3 years ago

Thank for your feedback. It looks like it would work if I left out the asyncio section

Then this one:

import aiohttp
import asyncio
from mytoyota.client import MyT

username = "MYUSER"
password = "MYPW"
locale = "de-de"
session = aiohttp.ClientSession()

client = MyT(locale=locale, session=session)

print("Performing login...")
client.perform_login(username=username, password=password)

valid, cars = await client.get_cars()
print(valid)
print(cars)

results in this:

connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x0000019A06946B20>, 1992.875)]']
connector: <aiohttp.connector.TCPConnector object at 0x0000019A084C6DC0>
Performing login...
True
[{'id': 1958079, 'vin': 'MYVIN', 'isNC': False, 'alias': 'Corolla', 'owner': False, 'vehicleAddedOn': '2020-11-19T17:36:19.469Z', 'isEntitled': True, 'entitledBy': 'CUSTOMER', 'entitledOn': '2020-11-20T17:28:23.074Z', 'ownerFlag': False, 'source': 'NMSC', 'horsePower': 98, 'hybrid': True, 'fuel': 'PETROL', 'engine': 'Hybrid: 1,8-l-VVT-i: Benzinmotor 72 kW (98PS), Elektromotor, 53 kW (72PS), Systemleistung 90 kW (122 PS)', 'transmissionType': 'CVT', 'transmission': 'Stufenloses Automatikgetriebe', 'fullKatashiki': 'ZWE211L-DWXNBW', 'grade': 'Mid', 'modelName': 'Corolla', 'modelCode': 'CR', 'interiorColour': '20', 'exteriorColour': '3U5 ', 'imageUrl': 'https://dj3z27z47basa.cloudfront.net/274b5a7a-5c46-4155-a275-f5e05b056e7a', 'modelDocumentId': '12345', 'productionYear': '2020', 'licensePlate': 'MYLICENSEPLATE', 'modelDescription': 'Corolla'}]

but when I then try this:

vin = 'MYVIN'

print("Retrieving latest parking information...")
parking = await client.get_parking(vin=vin)
print(parking)

I get the invalid character in header Message from HA again:

Retrieving latest parking information...
---------------------------------------------------------------------------
BadHttpMessage                            Traceback (most recent call last)
~\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\client_reqrep.py in start(self, connection)
    889                 try:
--> 890                     message, payload = await self._protocol.read()  # type: ignore
    891                 except http.HttpProcessingError as exc:

~\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\streams.py in read(self)
    603             try:
--> 604                 await self._waiter
    605             except (asyncio.CancelledError, asyncio.TimeoutError):

~\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\client_proto.py in data_received(self, data)
    212                 try:
--> 213                     messages, upgraded, tail = self._parser.feed_data(data)
    214                 except BaseException as exc:

~\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\_http_parser.pyx in aiohttp._http_parser.HttpParser.feed_data()

BadHttpMessage: 400, message='invalid character in header'

The above exception was the direct cause of the following exception:

ClientResponseError                       Traceback (most recent call last)
<ipython-input-13-c5f3650c5d37> in <module>
      2 
      3 print("Retrieving latest parking information...")
----> 4 parking = await client.get_parking(vin=vin)
      5 print(parking)

~\AppData\Local\Programs\Python\Python38\lib\site-packages\mytoyota\client.py in get_parking(self, vin)
    170         endpoint = f"{BASE_URL}/users/{self._uuid}/vehicle/location"
    171 
--> 172         retry, parking = await self._request(endpoint, headers=headers)
    173 
    174         if retry:

~\AppData\Local\Programs\Python\Python38\lib\site-packages\mytoyota\client.py in _request(self, endpoint, headers)
     68 
     69         resp = None
---> 70         async with self.session.get(
     71             endpoint, headers=headers, timeout=TIMEOUT
     72         ) as response:

~\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\client.py in __aenter__(self)
   1115 
   1116     async def __aenter__(self) -> _RetType:
-> 1117         self._resp = await self._coro
   1118         return self._resp
   1119 

~\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\client.py in _request(self, method, str_or_url, params, data, json, cookies, headers, skip_auto_headers, auth, allow_redirects, max_redirects, compress, chunked, expect100, raise_for_status, read_until_eof, proxy, proxy_auth, timeout, verify_ssl, fingerprint, ssl_context, ssl, proxy_headers, trace_request_ctx, read_bufsize)
    542                             resp = await req.send(conn)
    543                             try:
--> 544                                 await resp.start(conn)
    545                             except BaseException:
    546                                 resp.close()

~\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\client_reqrep.py in start(self, connection)
    890                     message, payload = await self._protocol.read()  # type: ignore
    891                 except http.HttpProcessingError as exc:
--> 892                     raise ClientResponseError(
    893                         self.request_info,
    894                         self.history,

ClientResponseError: 400, message='invalid character in header', url=URL('https://myt-agg.toyota-europe.com/cma/api/users/4c5c95ff-c92e-4e13-a8b4-99424edefc7d/vehicle/location')
DurgNomis-drol commented 3 years ago

All this information helps me a lot.

I think I know what the problem is now, it seems to be that Toyotas API does not play well with aiohttp, i will fix this later to day

DurgNomis-drol commented 3 years ago

@CM000n

EDIT: I take it back, have found some other things i m gonna try. SCRIPT have been updated.

Can i get you to test if my latest changes have worked.

Please create a test script in the MyT folder. And add this

import asyncio
from mytoyota.client import MyT

username = "mail"
password = "password"
locale = "da-dk"

client = MyT(locale=locale)

print("Performing login...")
client.perform_login(username=username, password=password)

async def get_information():
    print("Retrieving cars...")
    valid, cars = await client.get_cars()

    if valid:
        for car in cars:
            vin = car['vin']
            print(car)
            print(await client.get_information_for_given_car(vin))
    else:
        print("Invalid data received!")

loop = asyncio.get_event_loop()
loop.run_until_complete(get_information())
loop.close()

It speeds things up a lot if you could test this as these endpoints don't return anything for me (yet), so i cannot reproduce your problem.

Also don't install it with pip install as there is no setup.py yet. Just clone it and run script.

CM000n commented 3 years ago

Unfortunately, this again leads to a runtime error

Performing login...
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-1-d615b7cce775> in <module>
     24 
     25 loop = asyncio.get_event_loop()
---> 26 loop.run_until_complete(get_information())
     27 loop.close()

~\AppData\Local\Programs\Python\Python38\lib\asyncio\base_events.py in run_until_complete(self, future)
    590         """
    591         self._check_closed()
--> 592         self._check_running()
    593 
    594         new_task = not futures.isfuture(future)

~\AppData\Local\Programs\Python\Python38\lib\asyncio\base_events.py in _check_running(self)
    550     def _check_running(self):
    551         if self.is_running():
--> 552             raise RuntimeError('This event loop is already running')
    553         if events._get_running_loop() is not None:
    554             raise RuntimeError(

RuntimeError: This event loop is already running
DurgNomis-drol commented 3 years ago

It complains that the task is already running. How are you to execute this? This should be put into a file and the executed like this: python3 test.py where test.py is the name of the file.

I cannot replicate this error on Windows, for me it works. Both Windows CMD and wsl2.

CM000n commented 3 years ago

Ou man, silly me Γ”o. I had created a Jupyter Notebook and have it running within this. If I create a separate .py file and call it, it works :-)

Interestingly, this leads to another problem for "get_information_for_given_car" and "_get_odometer_endpoint" in client.py 35676576576547nt

DurgNomis-drol commented 3 years ago

No problem! πŸ˜„

Awesome πŸŽ‰ I have created a dev branch to make it easier to develop a function version. Please use that instead. And that error should be fixed in the dev branch. This will help me a lot to decipher what Toyota returns from there API's.

CM000n commented 3 years ago

Cool :-) In the dev Branch it suddenly complains that the username is an unexpected keyword: 45645654654nt

DurgNomis-drol commented 3 years ago

Sorry, i had change something and forgot to give you the updated code to test with:

import asyncio
from mytoyota.client import MyT

username = "email"
password = "password"
locale = "da-dk"

client = MyT(username=username, password=password, locale=locale)

print("Performing login...")
# This performs login and returns token and uuid. This should be saved somewhere safe and then reused when running
# this application again. Token lives about ~24 hours.
# token, uuid = client.perform_login()

client.perform_login()

async def get_information():
    print("Retrieving cars...")
    # Returns information about the cars registered to your account.
    cars = await client.get_cars()

    # Gets vehicle data from cars in the list.
    for car in cars:
        vin = car['vin']
        print(car)

        print(await client.get_information_for_given_car(vin))

loop = asyncio.get_event_loop()
loop.run_until_complete(get_information())
loop.close()
CM000n commented 3 years ago

Naaaaaice! ;-) 74567567864587746nt

DurgNomis-drol commented 3 years ago

YESS!! πŸŽ‰

But I can see that it is missing information from one endpoint. Where it says {'ReturnCode': '000000'} It should return more information about your HVAC and BATTERY, but this a least confirms that i'm on the right track. Can you tell if you have setup Toyota Connected Services through there website?

CM000n commented 3 years ago

I set it up through the Toyota Android MyT app at the time. https://play.google.com/store/apps/details?id=app.mytoyota.toyota.com.mytoyota&hl=de&gl=US To be honest, I think I've never been on the website πŸ˜ƒ

DurgNomis-drol commented 3 years ago

Haha, I only use the website to sniff out the API endpoints. πŸ˜„

When i get my car in the next couple of weeks, I will add more functions. In the mean time i will release this and the go back to work on the HA integration.

I just updated dev again to make it return things more neatly. Can you test this? πŸ˜„

CM000n commented 3 years ago

Ahh, I see it. The data is now grouped by Odometer, Parking & Status. Very nice πŸ‘ 65754674567nnt But the parking and status information is a bit redundant, isn't it?

{
    'odometer': [{
        'type': 'mileage',
        'value': 2064,
        'unit': 'km'
    }, {
        'type': 'Fuel',
        'value': 87.06
    }],
    'parking': {
        'event': {
            'lat': 'MYLAT',
            'lon': 'MYLON',
            'address': None,
            'timestamp': '1615741819000'
        },
        'tripStatus': '0',
        'energy': None
    },
    'status': {
        'event': {
            'lat': 'MYLAT',
            'lon': 'MYLON',
            'address': None,
            'timestamp': '1615741819000'
        },
        'tripStatus': '0',
        'energy': None
    }
}

I think this is a good approach, not to overload the first release too much with features, but to add them gradually. Have fun with the new car (what will it be?) and thanks for your work so far.

DurgNomis-drol commented 3 years ago

Thanks, i had a typo, that's why it is shown twice.

I have released a PyPi package, though still an alpha but it should work. You can install it by doing pip install mytoyota.

import asyncio
from mytoyota.client import MyT

username = "email"
password = "password"
locale = "da-dk"

client = MyT(username=username, password=password, locale=locale)

print("Performing login...")
# This performs login and returns token and uuid. This should be saved somewhere safe and then reused when running
# this application again. Token lives about ~24 hours.
# token, uuid = client.perform_login()

client.perform_login()

async def get_information():
    print("Retrieving cars...")
    # Returns information about the cars registered to your account.
    cars = await client.get_vehicles()

    # Gets vehicle data from cars in the list.
    for car in cars:
        vin = car['vin']
        print(car)

        print(await client.get_vehicle_status(vin))

loop = asyncio.get_event_loop()
loop.run_until_complete(get_information())
loop.close()

And to answer you last question. I just bought an Toyota Aygo (Micro Car) and to my surprise it comes with the ability to connect it to MyT. It also have Android Auto and Apple CarPlay πŸ˜„

DurgNomis-drol commented 3 years ago

@CM000n

Would you be willing to test somethings for me and post back the information, remember to remove private info? I have rewritten much of the underlying package here and have found a lot of new information in the API and i have added statistical endpoints. But I need some one to test it, because my car does not support everything that is possible. πŸ˜„

CM000n commented 3 years ago

Of course! I would be more than happy to support you at least by testing a little. Is there anything in particular I should look out for?

DurgNomis-drol commented 3 years ago

Can you run the below script and the paste the result here. Remember to desensitize it πŸ˜„

You will see that you now get statistical information from day, week and month. Right now i have some problems with year, but that will also come soon.

I have also changed a lot of things in the HA integration. I will release a new one very soon. Just have to fix some small things first in it.

Remember to update mytoyota. pip install mytoyota=0.2.1.

import asyncio
from mytoyota.client import MyT

username = "jane@doe.com"
password = "MyPassword"
locale = "da-dk"

client = MyT(username=username, password=password, locale=locale, region="europe")

async def get_information():
    print("Logging in...")
    await client.login()

    print("Retrieving cars...")
    # Returns information about the cars registered to your account
    cars = await client.get_vehicles()

    print(await client.gather_all_information_json())

    statistics = await client.get_driving_statistics_from_date_json(cars[0]['vin'])

    print(statistics)

    statistics = await client.get_driving_statistics_from_week_json(cars[0]['vin'])

    print(statistics)

    statistics = await client.get_driving_statistics_from_month_json(cars[0]['vin'])

    print(statistics)

loop = asyncio.get_event_loop()
loop.run_until_complete(get_information())
loop.close()
CM000n commented 3 years ago

Ok, I have updated via pip to version 0.2.1. But when I try to run your test script, I get the following error(s): 90092324r

DurgNomis-drol commented 3 years ago

Make sure you are running it under python 3 and not python 2. πŸ˜„

And can you paste the result in code-blocks next time. It is easier for me to just copy the part i need. πŸ˜„

DurgNomis-drol commented 3 years ago

UPDATE.

I found the error, was not because of you. Publishing a new package now.

EDIT: Please use mytoyota==0.2.2 πŸ˜„

CM000n commented 3 years ago

Seems to work now :-) This is the output I get for day, week, month so far:

[
   {
      "alias": "Corolla",
      "vin": "MYVIN",
      "details": {
         "engine": "Hybrid: 1,8-l-VVT-i: Benzinmotor 72 kW (98PS), Elektromotor, 53 kW (72PS), Systemleistung 90 kW (122 PS)",
         "entitledBy": "CUSTOMER",
         "entitledOn": "2020-11-20T17:28:23.074Z",
         "exteriorColour": "3U5 ",
         "fuel": "PETROL",
         "fullKatashiki": "ZWE211L-DWXNBW",
         "grade": "Mid",
         "horsePower": 98,
         "hybrid": true,
         "id": 1958079,
         "imageUrl": "https://dj3z27z47basa.cloudfront.net/9e45cf3a-684e-453e-859c-22cfde3272ae",
         "interiorColour": "20",
         "isEntitled": true,
         "isNC": false,
         "licensePlate": "MYLICENSEPLATE",
         "modelCode": "CR",
         "modelDescription": "Corolla",
         "modelDocumentId": "12345",
         "modelName": "Corolla",
         "owner": false,
         "ownerFlag": false,
         "productionYear": "2020",
         "source": "NMSC",
         "transmission": "Stufenloses Automatikgetriebe",
         "transmissionType": "CVT",
         "vehicleAddedOn": "2020-11-19T17:36:19.469Z"
      },
      "status": {
         "battery": null,
         "hvac": null,
         "odometer": {
            "mileage": 2381,
            "mileage_unit": "km",
            "Fuel": 29.02
         },
         "parking": {
            "event": {
               "lat": "MYLAT",
               "lon": "MYLON",
               "address": null,
               "timestamp": "1616853523000"
            },
            "tripStatus": "0",
            "energy": null,
            "protectionState": null
         }
      },
      "servicesEnabled": {
         "connectedServices": true
      }
   }
]
{
   "vin": "MYVIN",
   "from": "2021-03-27",
   "to": "2021-03-28",
   "uuid": "4c5c95ff-c92e-4e13-a8b4-99424edefc7d",
   "calendarInterval": "day",
   "summary": {
      "tripCount": 4,
      "totalDistanceInKm": 8.245,
      "totalDurationInSec": 750,
      "idleDurationInSec": 32,
      "highwayDistanceInKm": 0.0,
      "nightTripsCount": 0,
      "fuelSavedInL": 0.165,
      "averageDriverScore": 52.115585,
      "averageAccelerationDriverScore": 42.000727,
      "averageBrakingDriverScore": 42.079442,
      "averageConstantSpeedDriverScore": 84.210551,
      "evDurationInSec": 86,
      "evDistanceInKm": 0.811,
      "hardAccelerationCount": 1,
      "hardBrakingCount": 1,
      "coachingAdviceMostOccurrence": 5,
      "averageSpeedInKmph": 39.576063,
      "fuelSavedPercentage": 19.97578692493947,
      "evDurationPercentage": 11.466666666666667,
      "evDistancePercentage": 9.836264402668284,
      "co2Savings": 47.869011522134635,
      "totalFuelConsumedInL": 8.016979987871437,
      "maxSpeedInKmph": 99.0,
      "highwayDistancePercentage": 0.0
   },
   "histogram": [
      {
         "bucket": {
            "year": 2021,
            "dayOfYear": 86
         },
         "data": {
            "tripCount": 4,
            "totalDistanceInKm": 8.245,
            "totalDurationInSec": 750,
            "idleDurationInSec": 32,
            "highwayDistanceInKm": 0.0,
            "nightTripsCount": 0,
            "fuelSavedInL": 0.165,
            "averageDriverScore": 52.115585,
            "averageAccelerationDriverScore": 42.000727,
            "averageBrakingDriverScore": 42.079442,
            "averageConstantSpeedDriverScore": 84.210551,
            "evDurationInSec": 86,
            "evDistanceInKm": 0.811,
            "hardAccelerationCount": 1,
            "hardBrakingCount": 1,
            "coachingAdviceMostOccurrence": 5,
            "averageSpeedInKmph": 39.576063,
            "evDistancePercentage": 9.836264402668284,
            "evDurationPercentage": 11.466666666666667,
            "totalFuelConsumedInL": 8.016979987871437,
            "maxSpeedInKmph": 99.0,
            "highwayDistancePercentage": 0.0
         }
      }
   ]
}
{
   "vin": "MYVIN",
   "from": "2021-03-22",
   "to": "2021-03-28",
   "uuid": "4c5c95ff-c92e-4e13-a8b4-99424edefc7d",
   "calendarInterval": "week",
   "summary": {
      "tripCount": 14,
      "totalDistanceInKm": 113.484,
      "totalDurationInSec": 8067,
      "idleDurationInSec": 171,
      "highwayDistanceInKm": 34.851,
      "nightTripsCount": 0,
      "fuelSavedInL": 1.622,
      "averageDriverScore": 76.92702,
      "averageAccelerationDriverScore": 68.549513,
      "averageBrakingDriverScore": 88.453077,
      "averageConstantSpeedDriverScore": 78.9504,
      "evDurationInSec": 3101,
      "evDistanceInKm": 30.292,
      "hardAccelerationCount": 5,
      "hardBrakingCount": 9,
      "coachingAdviceMostOccurrence": 5,
      "averageSpeedInKmph": 50.643666,
      "fuelSavedPercentage": 20.994046078177583,
      "evDurationPercentage": 38.440560307425315,
      "evDistancePercentage": 26.69274963871559,
      "co2Savings": 34.18829086038561,
      "totalFuelConsumedInL": 5.37873180360227,
      "maxSpeedInKmph": 128.0,
      "highwayDistancePercentage": 30.710056043142647
   },
   "histogram": [
      {
         "bucket": {
            "year": 2021,
            "week": 13
         },
         "data": {
            "tripCount": 14,
            "totalDistanceInKm": 113.484,
            "totalDurationInSec": 8067,
            "idleDurationInSec": 171,
            "highwayDistanceInKm": 34.851,
            "nightTripsCount": 0,
            "fuelSavedInL": 1.622,
            "averageDriverScore": 76.92702,
            "averageAccelerationDriverScore": 68.549513,
            "averageBrakingDriverScore": 88.453077,
            "averageConstantSpeedDriverScore": 78.9504,
            "evDurationInSec": 3101,
            "evDistanceInKm": 30.292,
            "hardAccelerationCount": 5,
            "hardBrakingCount": 9,
            "coachingAdviceMostOccurrence": 5,
            "averageSpeedInKmph": 50.643666,
            "evDistancePercentage": 26.69274963871559,
            "evDurationPercentage": 38.440560307425315,
            "totalFuelConsumedInL": 5.37873180360227,
            "maxSpeedInKmph": 128.0,
            "highwayDistancePercentage": 30.710056043142647
         }
      }
   ]
}
{
   "vin": "MYVIN",
   "from": "2021-03-01",
   "to": "2021-03-28",
   "uuid": "4c5c95ff-c92e-4e13-a8b4-99424edefc7d",
   "calendarInterval": "month",
   "summary": {
      "tripCount": 81,
      "totalDistanceInKm": 516.324,
      "totalDurationInSec": 42076,
      "idleDurationInSec": 1853,
      "highwayDistanceInKm": 72.647,
      "nightTripsCount": 16,
      "fuelSavedInL": 9.019,
      "averageDriverScore": 73.547324,
      "averageAccelerationDriverScore": 67.956806,
      "averageBrakingDriverScore": 80.327442,
      "averageConstantSpeedDriverScore": 76.605964,
      "evDurationInSec": 17462,
      "evDistanceInKm": 159.045,
      "hardAccelerationCount": 32,
      "hardBrakingCount": 67,
      "coachingAdviceMostOccurrence": 5,
      "averageSpeedInKmph": 44.176407,
      "fuelSavedPercentage": 22.786277236903103,
      "evDurationPercentage": 42.1773489770193,
      "evDistancePercentage": 31.150997777481095,
      "co2Savings": 41.78277205785515,
      "totalFuelConsumedInL": 5.937744517008701,
      "maxSpeedInKmph": 128.0,
      "highwayDistancePercentage": 14.070041291901985
   },
   "histogram": [
      {
         "bucket": {
            "year": 2021,
            "month": 3
         },
         "data": {
            "tripCount": 81,
            "totalDistanceInKm": 516.324,
            "totalDurationInSec": 42076,
            "idleDurationInSec": 1853,
            "highwayDistanceInKm": 72.647,
            "nightTripsCount": 16,
            "fuelSavedInL": 9.019,
            "averageDriverScore": 73.547324,
            "averageAccelerationDriverScore": 67.956806,
            "averageBrakingDriverScore": 80.327442,
            "averageConstantSpeedDriverScore": 76.605964,
            "evDurationInSec": 17462,
            "evDistanceInKm": 159.045,
            "hardAccelerationCount": 32,
            "hardBrakingCount": 67,
            "coachingAdviceMostOccurrence": 5,
            "averageSpeedInKmph": 44.176407,
            "evDistancePercentage": 31.150997777481095,
            "evDurationPercentage": 42.1773489770193,
            "totalFuelConsumedInL": 5.937744517008701,
            "maxSpeedInKmph": 128.0,
            "highwayDistancePercentage": 14.070041291901985
         }
      }
   ]
}

Nice work πŸ‘

DurgNomis-drol commented 3 years ago

Thanks a lot. This will make it easier for me to implement unittest in the HA integration. The aim is to get it add to core at some point. πŸ˜„ Will ping you over at ha_toyota when a new release is ready for you to test. (Very very soon) πŸ˜„

CM000n commented 3 years ago

That sounds promising :-) What I noticed; Do the labels come from you, or directly from the API? The designation "totalFuelConsumedInL" is a bit misleading, because I'm pretty sure I've already consumed more than 5.9 L this month. ;-) That's probably more the average consumption per 100km, rather than total consumption

DurgNomis-drol commented 3 years ago

They come directly from the API. And i agree totalFuelConsumedInL is misleading. I think you are right, it is average consumptions per 100 km.