Code Monkey home page Code Monkey logo

mytoyota's Introduction

GitHub Workflow Codecov Commit activity GitHub Release PyPI - Downloads

Toyota Connected Services Europe Python module

🚨 Breaking changes ahead 🚨

Version 1.0.0 only supports the new ctpa-oneapi API endpoints that were introduced with the new MyToyota app. Some functions are not yet implemented and must first be determined due to the lack of API documentation.

Users of the old MyT app should use a mytoyota python module version < 1.0.0.

⚠️ This is still in beta

⚠️ Only EU is supported, other regions are not possible so far. See this for North America

Description

Python 3 package to communicate with Toyota Connected Europe Services. This is an unofficial package and Toyota can change their API at any point without warning.

Installation

This package can be installed through pip.

pip install mytoyota

Usage

For a quick start on how to use the package take a look at the simple_client_example.py file contained in the report. You can also use and execute this file directly by using the following commands:

python -m venv mytoyota
source mytoyota/bin/activate
python -m pip install "mytoyota @ git+https://github.com/DurgNomis-drol/mytoyota@master"
curl -LO https://raw.githubusercontent.com/GitOldGrumpy/mytoyota/master/simple_client_example.py
# Create a credentials.json file with {"username":"[email protected]","password":"yourpassword"}
python simple_client_example.py

Known issues

  • Statistical endpoint will return None if no trip have been performed in the requested timeframe. This problem will often happen at the start of each week, month or year. Also daily stats will of course also be unavailable if no trip have been performed.
  • Currently, it is only possible to get various vehicle information. Functions for controlling and setting vehicle properties have not yet been implemented.

Docs

Coming soon...

Contributing

This python module uses poetry (>= 1.2.2) and pre-commit.

To start contributing, fork this repository and run poetry install. Then create a new branch. Before making a PR, please run pre-commit poetry run pre-commit run --all-files and make sure that all tests passes locally first by running pytest tests/.

Note

As I @DurgNomis-drol am not a professional programmer. I will try to maintain it as best as I can. If someone is interested in helping with this, they are more the welcome to message me to be a collaborator on this project.

Credits

A huge thanks go to @calmjm for making tojota.

mytoyota's People

Contributors

apmechev avatar cm000n avatar dependabot[bot] avatar durgnomis-drol avatar gitoldgrumpy avatar joro75 avatar tibor19 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

mytoyota's Issues

Fuel consumed

"Fuel consumed" values are incorrect for all day/week/month/year sensors. For example, I get 2lt fuel consumption for 256km travelled which is inconsistent with actual consumption provided by the myToyota app
Screenshot_20240109-233900_Home Assistant~2

Screenshot_20240109-234040_MyToyota~2

Connected services is falsely reported as not setup

Describe the bug
Connected services is falsely reported as not setup if we get None from toyota's servers. We should handle this problem better.

Additional context
Log message from Home Assistant, this is the one printed out by the logger function:

Your vehicle does not support Connected services (). You can find out if your vehicle is compatible by checking the manual that comes with your car.

Add tool for getting data and anonymize it

@DurgNomis-drol In the original description of this PR, you are referring to that more testing is needed to get all the different information values from the MyT endpoints, for all different car models.

I do observe that this will be a common problem, not only for HVAC but also for other sensors and engine types.
This may be off topic for this PR, but shouldn't we start thinking about a separate function (or tool) that just requests the data and then anonimizes the data (stripping vin, user and location data), and makes it possible for the user to share it with us?

Originally posted by @joro75 in #93 (comment)

Discord

I'm spinning up to contribute to the NA version of this project and realized there's not a great place to come together and chat in regards to reverse engineering and whatnot. To that end I'm setting up a discord server for both the NA and EU projects so we can collaborate and work together.

Feel free to join

discord.gg/mFHJYew658

Statistical driver information of today cannot be requested when specifying specific date

Describe the bug
In the get_driving_statistics function it is possible to retrieve the specify a 'day'-interval with the 'from_date' of today. In that case no statistics are returned but error_code 2 is being returned.

if however the same function is called with the same 'day'-interval, but with the default 'from_date' (None), the day statistics of today are being returned.

This seems to be related to the line 391 of client.py, where a check is done if the requested date is today, and then the actual retrieval is skipped.

To Reproduce

>>> print(asyncio.run(client.get_driving_statistics(car['vin'], 'day', from_date="2022-02-13")))
[{'error_mesg': 'No data available for this period. (day)', 'error_code': 2}]
>>> print(asyncio.run(cl.get_driving_statistics(car['vin'], 'day')))
[{'bucket': {'year': 2022, 'dayOfYear': 44, 'unit': 'metric', 'date': '2022-02-13'}, 'data': {'tripCount': 1, 'totalDistanceInKm': 14.937, 'totalDurationInSec': 1313, 'idleDurationInSec': 98, 'highwayDistanceInKm': 0.0, 'nightTripsCount': 0, 'hardAccelerationCount': 4, 'hardBrakingCount': 3, 'averageSpeedInKmph': 40.95448, 'totalFuelConsumedInL': 8.703220191470844, 'maxSpeedInKmph': 93.0, 'highwayDistancePercentage': 0.0}}]

Expected behavior
I would expect that even if a specific date for today is passed, the statistical information of that day is being returned.

Additional context
A very related problem is present when no specific date is specified for the 'week'-interval, and it is requested on a Sunday. In that case no data is being returned, even though statistical information is present on the Toyota servers. This problem is also causing problems with some unittests if they are being performed on a Sunday :-(

Add support for Asia

Hey,

Would love to be able to use this in Thailand!
Can anyone assist?

Best regards,
Kim

Use python tests

Describe the solution you'd like

Use python tests to make the module robust.

Help wanted as I'm still very new to write code.

'Internal Server Error'

Retrying setup: 500, message='Internal Server Error', url=URL('https://oneapi.telematicsct.com/v2/legacy/remote/status')

Sensors are unavailable
2022-09-08 18:11:47.686 ERROR (MainThread) [custom_components.toyota_na] Error fetching data
Traceback (most recent call last):
File "/config/custom_components/toyota_na/init.py", line 104, in update_vehicles_status
raw_vehicles = await get_vehicles(client)
File "/usr/local/lib/python3.10/site-packages/toyota_na/vehicle/vehicle.py", line 36, in get_vehicles
await vehicle.update()
File "/usr/local/lib/python3.10/site-packages/toyota_na/vehicle/vehicle_generations/seventeen_cy.py", line 86, in update
vehicle_status = await self._client.get_vehicle_status(
File "/usr/local/lib/python3.10/site-packages/toyota_na/client.py", line 65, in get_vehicle_status
return await self.get_vehicle_status_17cy(vin)
File "/usr/local/lib/python3.10/site-packages/toyota_na/client.py", line 75, in get_vehicle_status_17cy
return await self.api_get(
File "/usr/local/lib/python3.10/site-packages/toyota_na/client.py", line 41, in api_get
return await self.api_request("GET", endpoint, header_params)
File "/usr/local/lib/python3.10/site-packages/toyota_na/client.py", line 31, in api_request
resp.raise_for_status()
File "/usr/local/lib/python3.10/site-packages/aiohttp/client_reqrep.py", line 1004, in raise_for_status
raise ClientResponseError

Wrong formatting in has_connected_services_enabled()

Describe the bug
Server returned data is different than expected causing a crash.

To Reproduce
Steps to reproduce the behavior:

  • locale is "sk-sk"
  • have one car with services enabled
  • have one car that has no functionality (I have a 2007 RAV4 just for the sake of it in the app)
    • probably unnecessary to buy a vehicle just for testing

Expected behavior
It should work but it don't

** Possible Fix **

I had to modify the vehicle.py - has_connected_services_enabled() fully knowing that a general try-catch is the bodgiest of bodges to be like so:

def has_connected_services_enabled(self, json_dict) -> bool:
    """Checks if the user has enabled connected services."""
    try:
        if (
            "connectedService" in json_dict
            and json_dict["connectedService"]["devices"][0]["state"] == "ACTIVE"
        ):
            return True

        _LOGGER.error(
            "Please setup Connected Services if you want live data from the car. (%s)",
            self.vin,
        )
        return False
    except:
        return False

Apart from the big try-catch notice the json_dict lookup change.
Probably needs testing to see if this happens in more countries or it's just a nieche for Slovakia.
Unsure if there could be ["devices"][1] or more? I don't have the touch2go nav, did not registrer my head unit nor do I have a hybrid.

Catching Readtimeout exception and related errors.

Describe the bug
In my HA integration I need to do below to catch some exceptions thrown by Toyota's servers because it is to slow to respond when processing a request.

 except (
            asyncioexceptions.CancelledError,
            asyncioexceptions.TimeoutError,
            httpx.ReadTimeout,
        ) as ex:

            raise UpdateFailed(
                "Update canceled! Toyota's API was too slow to respond."
                " Will try again later..."
            ) from ex

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

I would love to move this to here instead, but I am unsure of what the best way to do it, and maybe even handle the error silently by doing the request again or something. What do you think @joro75 ?

Additional context
Add any other context about the problem here.

Check if UUID is a valid UUID4 and check if token is valid

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

my own fault -- simple_client_example.py => error | solved

Describe the bug

simple_client_example.py => error

To Reproduce


$ python simple_client_example.py 

Traceback (most recent call last):
  File "/usr/lib/python3.11/logging/config.py", line 573, in configure
    handler = self.configure_handler(handlers[name])
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/logging/config.py", line 758, in configure_handler
    result = factory(**kwargs)
             ^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/logging/__init__.py", line 1181, in __init__
    StreamHandler.__init__(self, self._open())
                                 ^^^^^^^^^^^^
  File "/usr/lib/python3.11/logging/__init__.py", line 1213, in _open
    return open_func(self.baseFilename, self.mode,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 13] Permission denied: '/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/.log'

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

Traceback (most recent call last):
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/simple_client_example.py", line 8, in <module>
    import mytoyota.utils.logging.logging_config  # noqa # pylint: disable=unused-import
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/mytoyota/__init__.py", line 4, in <module>
    from mytoyota.client import MyT  # noqa
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/mytoyota/client.py", line 14, in <module>
    import mytoyota.utils.logging.logging_config  # noqa # pylint: disable=unused-import
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/mytoyota/utils/logging/logging_config.py", line 13, in <module>
    logging.config.dictConfig(config_dict)
  File "/usr/lib/python3.11/logging/config.py", line 823, in dictConfig
    dictConfigClass(config).configure()
  File "/usr/lib/python3.11/logging/config.py", line 580, in configure
    raise ValueError('Unable to configure handler '
ValueError: Unable to configure handler 'file'

Error from toyota's servers

Describe the bug
This error comes from the Home Assistant integration, but the traceback shows that it occurs in the library.
It works, but should be handled better the in code. Happens when an error occurred at Toyota's servers.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
No error.

Additional context

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 187, in _async_refresh
    self.data = await self._async_update_data()
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 147, in _async_update_data
    return await self.update_method()
  File "/config/custom_components/toyota/__init__.py", line 105, in async_update_data
    data = await asyncio.gather(
  File "/usr/local/lib/python3.9/site-packages/mytoyota/client.py", line 419, in get_driving_statistics
    raw_statistics = await self.api.get_driving_statistics_endpoint(
  File "/usr/local/lib/python3.9/site-packages/mytoyota/api.py", line 96, in get_driving_statistics_endpoint
    return await self.controller.request(
  File "/usr/local/lib/python3.9/site-packages/mytoyota/controller.py", line 202, in request
    + response["code"]
KeyError: 'code'

Unlock/Lock Functions?

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Am I able to lock and unlock my compatible vehicles using this API.
In addition to start and stop functions?

Describe the solution you'd like
A clear and concise description of what you want to happen.
I want to be able to track my vehicles and unlock or lock the doors when necessary.

I also want to start and safely stop my vehicle using the API.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

NoneType object has no attribute `unit` in `self._electric.fuel_range.unit`

Describe the bug
Running simple_client_example.py leads to an error

To Reproduce

$ date
Mi 10. Jan 17:47:15 CET 2024

$ git pull                                                                                                                                                                          
remote: Enumerating objects: 6, done.                                                                                                                                                                                                         
remote: Counting objects: 100% (6/6), done.                                                                                                                                                                                                   
remote: Compressing objects: 100% (2/2), done.                                                                                                                                                                                                
remote: Total 6 (delta 4), reused 5 (delta 4), pack-reused 0                                                                                                                                                                                  
Entpacke Objekte: 100% (6/6), 1.96 KiB | 125.00 KiB/s, fertig.                                                                                                                                                                                
Von https://github.com/DurgNomis-drol/mytoyota                                                                                                                                                                                                
   66ad51e..6f648fb  master     -> origin/master                                                                                                                                                                                              
   737574e..32c6509  feature/add_current_day_week_month_year_statistics -> origin/feature/add_current_day_week_month_year_statistics                                                                                                          
Aktualisiere 66ad51e..6f648fb                                                                                                                                                                                                                 
Fast-forward                                                                                                                                                                                                                                  
 mytoyota/models/endpoints/telemetry.py | 4 ++--                                                                                                                                                                                              
 1 file changed, 2 insertions(+), 2 deletions(-)                      
$ git log                                                                                                                                                                           
commit 6f648fbedf888f48092e06578ee22d6a5f8edc08 (HEAD -> master, origin/master, origin/HEAD)                                                                                                                                                  
Author: Simon Hörrle <[email protected]>                                                                                                                                                                                
Date:   Wed Jan 10 16:43:21 2024 +0100                                                                                                                                                                                                        
                                                                                                                                                                                                                                              
    Fix: Make `fuel_level` optional (#289)                                                                                                                                                                                                    
                                                                                                                                                                                                                                              
    * Make fuel_level optional                                                                                                                                                                                                                
                                                                                                                                                                                                                                              
    * adjust docstring                                                                                                                                                                                                                        
                                                                                                                                                                                                                                              
commit 66ad51ed2db1094ae1b109913b74e8afbdde312f (tag: v1.1.3)                                                                                                                                                                                 
Author: GitOldGrumpy <[email protected]>                                                                                                                                                                                           
Date:   Tue Jan 9 20:50:07 2024 +0000                                   
…

python is linked to python3

$ python simple_client_example.py
Logging in...
Retrieving cars...
Traceback (most recent call last):
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/simple_client_example.py", line 83, in <module>
    loop.run_until_complete(get_information())
  File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/simple_client_example.py", line 52, in get_information
    pp.pprint(f"Dashboard: {car.dashboard}")
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/mytoyota/models/dashboard.py", line 37, in __repr__
    [
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/mytoyota/models/dashboard.py", line 38, in <listcomp>
    f"{k}={getattr(self, k)!s}"
           ^^^^^^^^^^^^^^^^
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/mytoyota/models/dashboard.py", line 90, in fuel_range
    self._electric.fuel_range.unit,
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'unit'

Expected behavior

The script should output

  • Dashboard Data
    
  • Location Data
    
  • Lock Status
    
  • Notifications
    
  • Summary
    
  • Trips
    

Unexpected value returned by Toyota

Testing the new api endpoint for the ha toyota integration

It happend after the setup flow is finished and the integration try to create entitites

Expected behavior
I should be able to see my vehicle sensors

Additional context
Car is a Toyota Corolla Touring 2021 Hyrbrid

payload -> 0 -> dcm
  none is not an allowed value (type=type_error.none.not_allowed)
payload -> 0 -> electricalPlatformCode
  none is not an allowed value (type=type_error.none.not_allowed)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 300, in _async_refresh
    self.data = await self._async_update_data()
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 256, in _async_update_data
    return await self.update_method()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/toyota/__init__.py", line 72, in async_get_vehicle_data
    vehicles = await asyncio.wait_for(client.get_vehicles(metric=use_metric_values), 15)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/tasks.py", line 489, in wait_for
    return fut.result()
           ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/mytoyota/client.py", line 63, in get_vehicles
    vehicles = await self._api.get_vehicles_endpoint()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/mytoyota/api.py", line 75, in get_vehicles_endpoint
    return await self._request_and_parse(VehiclesResponseModel, "GET", VEHICLE_GUID_ENDPOINT)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/mytoyota/api.py", line 49, in _request_and_parse
    return model(**response)
           ^^^^^^^^^^^^^^^^^
  File "pydantic/main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 2 validation errors for VehiclesResponseModel
payload -> 0 -> dcm
  none is not an allowed value (type=type_error.none.not_allowed)
payload -> 0 -> electricalPlatformCode
  none is not an allowed value (type=type_error.none.not_allowed)```

Performance problems with API

Hi
maybe I'm alone with this problem, but since November 29th I've started noticing strange problems. Toyota API often returns HTTP 429 answer on vehicleStatus endpoint. Problem didn't stopped even after implementing strong throttling, and it looks that API has performance problems. In the same time application works correctly, and I'm just wondering if Toyota hasn't changed its API endpoints to new ones with the application (while leaving old ones scaled down for older application instances). Last update for the application was on November 18th.
Do you have an option to verify traffic generated from the application? I have locked phone :(.

mytoyota 0.7.4 dependency requierement error

Describe the bug
I'm trying to use MyToyota Connected Services and it's requiere mytoyota 0.7.4, so I've tryed to install it:

I cannot install the package (either via pip and webinterface), get

mytoyota 0.7.4 requires httpx<0.19.0,>=0.18.1, but you have httpx 0.19.0 which is incompatible.

To Reproduce
upgrade python3.8 .11 (Debian version)

Expected behavior
working with latest httpx version (0.19.0)

Screenshots
N/A

Additional context

Maintainer Access...

Hi could someone grant me maintainer access so I can create branches with new work for review? Might be easier than me creating pull requests?

Thanks.

The 'year' information in the 'bucket' of the statistics is sometimes a string and sometimes an integer

Describe the bug
The 'year' information in the bucket of the statistical information is sometimes provided as a string in the dictionary, and in other situations it is provided as an integer in the dictionary. This is not consistent.

day, week and month return the 'year' as an int
isoweek and year return the 'year' as a string

To Reproduce
Retrieve the statistics for one of the mentioned intervals, and see that the data type of the 'year' key in the 'bucket' dictionary is having different types

Also see the unittests in commit #138, that proof this.

Expected behavior
That independent of the requested interval, the same type is used for the year.
I would like to suggest that 'int' is used as it also seems to be the type that is returned by default by the Toyota servers.

This could however be a breaking change, as some code using the library is assuming to have the year as a string.

X-TME-APP-VERSION not provided

Describe the bug
No information is retrieved anymore from the Toyota servers because of a 'X-TME-APP-VERSION not provided' error.
The ToyotaApiError exception is raised with the information:

ToyotaApiError':'HTTP: 400 - {"timestamp":1648387011009,"status":400,"error":"Bad Request","message":"X-TME-APP-VERSION not provided","errorCode":"CMA400"}

To Reproduce
Not checked yet, but I expect it will also be present when the example from README.md is used.

Expected behavior
That the mytoyota library provides an appropiate 'X-TME-APP-VERSION'.

Additional context
My Domoticz plugin which is using the mytoyota library, was working correctly on March 21st. However since March 22nd no information is being retrieved anymore. No configuration changes, software update or restart has been performed on my side. It seems that the Toyota Servers are suddenly requiring the additional headers.

`get_vehicle_status().dashboard.battery_level` is not returning fresh data

Describe the bug
When the car is charging, get_vehicle_status().dashboard.battery_level does not return fresh data, but the data that was fetched when MyT app has refreshed charging status from the Remote Charging menu by clicking the refresh button (screenshot attached):

Screenshot

Not exactly sure if this falls under a bug or feature request, putting it under bug since to me it sounds like the current behaviour is somewhat misleading.

To Reproduce
Steps to reproduce the behavior:

  • Plug the car (Toyota RAV4 PHEV 2022) to charge
  • Run mytoyota client with the (cropped) code below:
from mytoyota.client import MyT

client = MyT(username=username, password=password, brand=brand)
await client.login()
vehicle = await client.get_vehicle_status(car)
charging_status = vehicle.dashboard.charging_status # this correctly returns 'charging' status
battery = vehicle.dashboard.battery_level # this will always return the same value while the car is charging

As per comment, when battery level is updated using the client, it returns the same value throughout the time that the car is charging.
Currently the only way to get an up-to-date charge value is by opening MyT app, going into Remote Charging menu and refreshing the data, which is obviously a blocker for doing automation using the client.

Expected behavior
Calling await client.get_vehicle_status(car).dashboard.battery_level should return up-to-date value on every call.


I meant to intercept the http request that the MyT app is performing when the refresh button is clicked, however so far the apk that's rebuilt with client certificates allowed fails on login step. If there's info on what toyota-europe API endpoint is used to refresh the data, it would also be of great help.

Thanks!

South Africa

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Latest langcodes.Language.make() in doesn't accept da-dk locale anymore

Describe the bug
mytoyota currently depends on langcodes 3.1.0. That library is used in the utils.is_valid_locale function. In the 3.1.0 version of langcodes the following is valid: `Language.make('da-dk').is_valid()'. However in the latest version of langcodes (which is version 3.2.1 at this moment), passing the 'da-dk' is not valid anymore.

To Reproduce

from langcodes import Language
print(Language.make('da-dk').is_valid())

It is better to use the Language.get() function. That is also working as expected in the used 3.1.0 version of langcodes.

Missing odometer information

Describe the bug
A clear and concise description of what the bug is.

Using the API, I am missing the odometer information. This was available from the old endpoints.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Additional context
Add any other context about the problem here.

Contract_id: "**********52458"
IMEI: "*************34103"
Katashiki_code: KGB40L-AHMGKW
ASI_code: FC
Brand: T
Car_line_name: Aygo
Car_model_year: "2018"
Car_model_name: Aygo - MC '18
Color: Dark Grey Mica
Generation: 17CYPLUS
Manufactured_date: "2021-03-01"
Date_of_first_use: null
Transmission_type: M
Fuel_type: G
Electrical_platform_code: null
EV_vehicle: false
Features:
  crash_notification: true
  dealer_appointment: true
  drive_pulse: true
  emergency_assist: true
  last_parked: true
  privacy: true
  service_history: true
Extended_capabilities:
  battery_status: true
  bump_collisions: true
  drive_pulse: true
  emergency_assist: true
Remote_service_capabilities: {}
('Dashboard: odometer=None fuel_level=None battery_level=None fuel_range=None '
 'battery_range=None battery_range_with_ac=None range=None '
 'charging_status=None remaining_charge_time=None warning_lights=[]')
('Location: latitude=00.00000 longitude=0.00000 timestamp=2024-01-11 '
 '15:42:03+00:00 state=Last Parked')
'Lock Status: last_updated=None doors=None windows=None hood=None'
'Notifications: []'
("Summary: [[average_speed=52.53 countries=['DK'] duration=5:25:28 "
 'distance=284.928 ev_duration=None ev_distance=None from_date=2023-07-15 '
 'to_date=2023-07-31 fuel_consumed=0.0 average_fuel_consumed=0.0], '
 "[average_speed=49.05 countries=['DK'] duration=12:50:35 distance=629.954 "
 'ev_duration=None ev_distance=None from_date=2023-08-01 to_date=2023-08-31 '
 'fuel_consumed=0.0 average_fuel_consumed=0.0], [average_speed=57.26 '
 "countries=['DK'] duration=20:38:22 distance=1181.861 ev_duration=None "
 'ev_distance=None from_date=2023-09-01 to_date=2023-09-30 fuel_consumed=0.0 '
 "average_fuel_consumed=0.0], [average_speed=63.33 countries=['DK'] duration=1 "
 'day, 3:17:51 distance=1728.835 ev_duration=None ev_distance=None '
 'from_date=2023-10-01 to_date=2023-10-31 fuel_consumed=0.0 '
 "average_fuel_consumed=0.0], [average_speed=49.73 countries=['DK'] "
 'duration=20:07:04 distance=1000.43 ev_duration=None ev_distance=None '
 'from_date=2023-11-01 to_date=2023-11-30 fuel_consumed=0.0 '
 "average_fuel_consumed=0.0], [average_speed=53.63 countries=['DK'] duration=1 "
 'day, 3:19:18 distance=1465.188 ev_duration=None ev_distance=None '
 'from_date=2023-12-01 to_date=2023-12-31 fuel_consumed=0.0 '
 "average_fuel_consumed=0.0], [average_speed=36.97 countries=['DK'] "
 'duration=12:12:12 distance=451.131 ev_duration=None ev_distance=None '
 'from_date=2024-01-01 to_date=2024-01-11 fuel_consumed=0.0 '
 'average_fuel_consumed=0.0]]')

Add more debug logging

Important points to log.

  • Raw data
  • Formatted data
  • Login
    • Censor login information
    • Censor token

Example

Describe the bug
Example (README.md)

battery = vehicle.dashboard.batter_level

There is a misspelled, battery instead of batter

Additional context
Great work DurgNomis-drol

AttributeError: 'MyT' object has no attribute 'get_vehicle_status'

I obtain without problems the list of my cars registered in my Toyota account using await client.get_vehicles() However when I try to access more specific information about any vehicle using await client.get_vehicle_status(car) rises an error AttributeError: 'MyT' object has no attribute 'get_vehicle_status'

In local machine there is no problem,

Requirement already satisfied: mytoyota in ./.local/lib/python3.7/site-packages (0.2.2)
Requirement already satisfied: langcodes in ./.local/lib/python3.7/site-packages (from mytoyota) (3.1.0)
Requirement already satisfied: pendulum in ./.local/lib/python3.7/site-packages (from mytoyota) (2.1.2)
Requirement already satisfied: httpx in ./.local/lib/python3.7/site-packages (from mytoyota) (0.19.0)
Requirement already satisfied: httpcore<0.14.0,>=0.13.3 in ./.local/lib/python3.7/site-packages (from httpx->mytoyota) (0.13.6)
Requirement already satisfied: rfc3986[idna2008]<2,>=1.3 in ./.local/lib/python3.7/site-packages (from httpx->mytoyota) (1.5.0)
Requirement already satisfied: certifi in /usr/lib/python3/dist-packages (from httpx->mytoyota) (2018.8.24)
Requirement already satisfied: sniffio in ./.local/lib/python3.7/site-packages (from httpx->mytoyota) (1.2.0)
Requirement already satisfied: charset-normalizer in ./.local/lib/python3.7/site-packages (from httpx->mytoyota) (2.0.4)
Requirement already satisfied: anyio==3.* in ./.local/lib/python3.7/site-packages (from httpcore<0.14.0,>=0.13.3->httpx->mytoyota) (3.3.0)
Requirement already satisfied: h11<0.13,>=0.11 in ./.local/lib/python3.7/site-packages (from httpcore<0.14.0,>=0.13.3->httpx->mytoyota) (0.12.0)
Requirement already satisfied: idna>=2.8 in ./.local/lib/python3.7/site-packages (from anyio==3.*->httpcore<0.14.0,>=0.13.3->httpx->mytoyota) (3.2)
Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from anyio==3.*->httpcore<0.14.0,>=0.13.3->httpx->mytoyota) (3.10.0.0)
Requirement already satisfied: pytzdata>=2020.1 in ./.local/lib/python3.7/site-packages (from pendulum->mytoyota) (2020.1)
Requirement already satisfied: python-dateutil<3.0,>=2.6 in /usr/lib/python3/dist-packages (from pendulum->mytoyota) (2.7.3)
Django Version: 3.2.6
Python Version: 3.7.3
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.7/dist-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/api/geo/views.py", line 19, in get_toyota
    return HttpResponse(toyota.main())
  File "/opt/api/geo/auxiliar/toyota.py", line 45, in main
    loop.run_until_complete(get_information())
  File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "/opt/api/geo/auxiliar/toyota.py", line 36, in get_information
    vehicle = await client.get_vehicle_status(car)

Exception Type: AttributeError at /geo/get_toyota
Exception Value: 'MyT' object has no attribute 'get_vehicle_status'

Cache folder could not be set up.

Describe the bug
When trying to use the Home Assistant ha_toyota Custom Component with mytoyota v1.1.0, there is a problem with the creation of the cache directory, which is why the Custom Component cannot be set up:

Logger: custom_components.toyota.config_flow
Source: custom_components/toyota/config_flow.py:53
Integration: Toyota Connected Services ([documentation](https://github.com/DurgNomis-drol/ha_toyota), [issues](https://github.com/DurgNomis-drol/ha_toyota/issues))
First occurred: 21:45:28 (2 occurrences)
Last logged: 21:52:01

An unknown error occurred during login request: [Errno 2] No such file or directory: '/root/.cache/toyota_credentials_cache_contains_secrets'

To Reproduce
Steps to reproduce the behavior:

  1. Use the work in progress version of ha_toyota from the following MR and copy the files into your home assistatn custom_components directory: DurgNomis-drol/ha_toyota#198
  2. Restart your home assistant instance
  3. Add the "Toyota connected services" Integration in Home Assistant and insert E-Mail and Password
  4. See error

Expected behavior
The custom component should be able to be initialised correctly and without errors.

Additional context

Runtime Error, with intial execution

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()
  1. See error

Expected behavior
Get a list with valid cars

Key 'hood' not available

Describe the bug
Information about the status of the hood is not available for my car, this results in the following error:

Traceback (most recent call last):
  File "fetch.py", line 87, in <module>
    loop.run_until_complete(get_information())
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "fetch.py", line 26, in get_information
    vehicle = await client.get_vehicle_status(car)
  File "/usr/local/lib/python3.8/dist-packages/mytoyota/client.py", line 120, in get_vehicle_status
    car = Vehicle(
  File "/usr/local/lib/python3.8/dist-packages/mytoyota/vehicle.py", line 192, in __init__
    Status(status["protectionState"])
  File "/usr/local/lib/python3.8/dist-packages/mytoyota/vehicle.py", line 112, in __init__
    self.doors = Doors(status[HOOD], status[DOORS])
KeyError: 'hood'

To Reproduce
Steps to reproduce the behavior:
Execute the sample script of this repository.

Additional context
Response of the request:

{'overallStatus': 'OK', 'timestamp': '2021-09-17T18:12:40Z', 'doors': {'warning': False, 'driverSeatDoor': {'warning': False, 'closed': True, 'locked': True}, 'passengerSeatDoor': {'warning': False, 'closed': True, 'locked': True}, 'rearRightSeatDoor': {'warning': False, 'closed': True, 'locked': True}, 'rearLeftSeatDoor': {'warning': False, 'closed': True, 'locked': True}, 'backDoor': {'warning': False, 'closed': True, 'locked': True}}, 'lamps': {'warning': False, 'headLamp': {'warning': False, 'off': True}, 'tailLamp': {'warning': False, 'off': True}, 'hazardLamp': {'warning': False, 'off': True}}, 'windows': {'warning': False, 'driverSeatWindow': {'warning': False, 'state': 'close'}, 'passengerSeatWindow': {'warning': False, 'state': 'close'}, 'rearRightSeatWindow': {'warning': False, 'state': 'close'}, 'rearLeftSeatWindow': {'warning': False, 'state': 'close'}}, 'key': {'warning': False, 'inCar': False}, 'lock': {'lockState': 'locked', 'source': 'key', 'failedUnlockPreconditions': []}}

Car: Toyota Yaris model 2021

Inconsistency in statistics summaries

I am currently in the process of adapting the Home Assistant integration to the new mytoyota version.
I noticed that the statistics summaries are inconsistent.
According to the current date (08 January 2024), the monthly and annual statistics should be the same. However, for the same period from 01.01 to 08.01.2024 I get different values for month (e.g. 90km distance) and year (e.g. 179km distance).

Screenshot_20240108-172537

Authentication Failed. Unknown method.

Describe the bug
Authentication is not working.

Logging in...
Traceback (most recent call last):
  File "/mnt/wsl/docker-desktop-bind-mounts/Ubuntu/387e0f16919e6d7c21c3fbd983fea1ba949b10b954c00eef297e8363c9452535/new.py", line 85, in <module>
    loop.run_until_complete(get_information())
  File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/mnt/wsl/docker-desktop-bind-mounts/Ubuntu/387e0f16919e6d7c21c3fbd983fea1ba949b10b954c00eef297e8363c9452535/new.py", line 45, in get_information
    await client.login()
  File "/home/lasith/.local/lib/python3.10/site-packages/mytoyota/client.py", line 58, in login
    await self._api.controller.login()
  File "/home/lasith/.local/lib/python3.10/site-packages/mytoyota/controller.py", line 62, in login
    await self._update_token()
  File "/home/lasith/.local/lib/python3.10/site-packages/mytoyota/controller.py", line 74, in _update_token
    await self._authenticate()
  File "/home/lasith/.local/lib/python3.10/site-packages/mytoyota/controller.py", line 105, in _authenticate
    raise ToyotaLoginError("Authentication Failed. Unknown method.")
mytoyota.exceptions.ToyotaLoginError: Authentication Failed. Unknown method.

To Reproduce
Steps to reproduce the behavior:
python simple_client_example.py

Could you please add supprt for Australia?

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

running simple_client_example.py => E-Mail with verification code from toyota

Describe the bug
When running simple_client_example.py I get an Authentication Error
plus an e-mail from toyota with a verification code.

`Deine Anmeldung in der MyToyota App ist fast fertig, du musst nur noch deine E-Mail-Adresse bestätigen. Bitte gebe den Verifizeriungscode ein, wenn du dazu aufgefordert wirst.

Dies ist der sechsstellige Verifizierungscode: 080628 Dieser Code ist fünf Minuten lang gültig`

Where should I place/save this code?

To Reproduce
Steps to reproduce the behavior:

homeassistant@aberddi:~/.homeassistant/custom_components/mytoyota$ python simple_client_example.py 

Logging in...

Traceback (most recent call last):
  File "mytoyota/simple_client_example.py", line 83, in <module>
    loop.run_until_complete(get_information())
  File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^

  File "mytoyota/simple_client_example.py", line 43, in get_information
    await client.login()

  File "mytoyota/client.py", line 58, in login
    await self._api.controller.login()

  File "mytoyota/controller.py", line 62, in login
    await self._update_token()

  File "mytoyota/controller.py", line 74, in _update_token
    await self._authenticate()

  File "mytoyota/controller.py", line 105, in _authenticate
    raise ToyotaLoginError("Authentication Failed. Unknown method.")
mytoyota.exceptions.ToyotaLoginError: Authentication Failed. Unknown method.

Expected behavior
After saving the verification-code at ?? simple_client_example.py should run ;-)

PLZ requesting support for Puerto Rico

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Ability to determine the version of the mytoyota library in code

  • Is your feature request related to a problem? Please describe.
    In my domoticz plugin, the mytoyota library is used, however I am not sure if the end-user who is using the domoticz plugin also has installed the latest mytoyota library, because it is installed using 'pip', and the end-user can update the domoticz plugin without updating the pip libraries.

  • Describe the solution you'd like
    I thus would like to have a possibility that my python code (which is using the mytoyota library) is able to check the version of the actually used/installed mytoyota library. In case that it is too old, the python plugin can then take appropiate actions, like rasising a warning.
    Best implementation seems to follow PEP 396 which requires that a version attribute is included. This also seems to be used by a lot of other python libraries.

  • Describe alternatives you've considered
    Checking and performing pip3 queries from an embedded commandline is ofcourse possible, but more complicated, and too heavy.

  • Additional context
    I will continue to suggest a code change, and will provide a PR later.

`scores` fields can be `None` in `TripsResponseModel`

Describe the bug
Hello, I have been trying to use simple_client_example.py. I have been experiencing the same issues as reported in #284. After the update that close this issue, the error shown changed to the following:

Logging in...
Retrieving cars...
Traceback (most recent call last):
File "/home/jhidalgo/simple_client_example.py", line 73, in
loop.run_until_complete(get_information())
File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/home/jhidalgo/simple_client_example.py", line 49, in get_information
await car.update()
File "/home/jhidalgo/mytoyota/lib/python3.11/site-packages/mytoyota/models/vehicle.py", line 113, in update
for name, data in await responses:
^^^^^^^^^^^^^^^
File "/home/jhidalgo/mytoyota/lib/python3.11/site-packages/mytoyota/models/vehicle.py", line 107, in parallel_wrapper
r = await function()
^^^^^^^^^^^^^^^^
File "/home/jhidalgo/mytoyota/lib/python3.11/site-packages/mytoyota/api.py", line 220, in get_trips_endpoint
return await self._request_and_parse(TripsResponseModel, "GET", endpoint, vin=vin)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jhidalgo/mytoyota/lib/python3.11/site-packages/mytoyota/api.py", line 49, in _request_and_parse
return model(**response)
^^^^^^^^^^^^^^^^^
File "/home/jhidalgo/mytoyota/lib/python3.11/site-packages/pydantic/main.py", line 341, in init
raise validation_error
pydantic.error_wrappers.ValidationError: 3 validation errors for TripsResponseModel
payload -> trips -> 0 -> scores
field required (type=value_error.missing)
payload -> trips -> 1 -> scores
field required (type=value_error.missing)
payload -> summary -> 0 -> scores
field required (type=value_error.missing)

To Reproduce
Steps to reproduce the behavior:

  1. Fresh install of the software
  2. Created credentials.json file
  3. Run simple_client_example.py (my car is a petrol Toyota Aygo from 2021.

Expected behavior
I should be able to see my vehicle sensors

Additional context
Related to issue #284

TripEvent interval

Hi,

Are you aware what is the interval between the trip events?
They do not contain a timestamp and I could not figure out what the interval between them is, be it time or distance..
If anyone does know, please share.

Thank you!

SummaryType error if using simple_client_example.py

Describe the bug
Getting following error if using simple_client_example.py:

Traceback (most recent call last):
  File "/home/pi/toyota/simple_client_example.py", line 8, in <module>
    from mytoyota.models.summary import SummaryType
ModuleNotFoundError: No module named 'mytoyota.models.summary'

To Reproduce
Python 3.9.2

Run: python simple_client_example.py

Implement typing

Type check everything. Though not aiming for enabling strict typing yet.

running simple_client_example.py gives an error

Describe the bug

Running the script simple_client_example.py gives an error

To Reproduce

running: python simple_client_example.py

`Logging in...

Retrieving cars...

Traceback (most recent call last):
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/simple_client_example.py", line 83, in <module>
    loop.run_until_complete(get_information())
  File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/simple_client_example.py", line 49, in get_information
    await car.update()
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/mytoyota/models/vehicle.py", line 113, in update
    for name, data in await responses:
                      ^^^^^^^^^^^^^^^
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/mytoyota/models/vehicle.py", line 107, in parallel_wrapper
    r = await function()
        ^^^^^^^^^^^^^^^^
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/mytoyota/api.py", line 114, in get_remote_status_endpoint
    return await self._request_and_parse(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/oldroot/home/humbert/dokumente/photovoltaik-wallbox/mytoyota/mytoyota/api.py", line 49, in _request_and_parse
    return model(**response)
           ^^^^^^^^^^^^^^^^^
  File "pydantic/main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 4 validation errors for RemoteStatusResponseModel
payload -> telemetry -> fugage -> unit
  none is not an allowed value (type=type_error.none.not_allowed)
payload -> telemetry -> fugage -> value
  none is not an allowed value (type=type_error.none.not_allowed)
payload -> telemetry -> rage -> unit
  none is not an allowed value (type=type_error.none.not_allowed)
payload -> telemetry -> rage -> value
  none is not an allowed value (type=type_error.none.not_allowed)`

Expected behavior

The script should output

  • Dashboard Data
  • Location Data
  • Lock Status
  • Notifications
  • Summary
  • Trips

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.