Nissan Leaf Integration (Carwings / NissanConnect EV) #19786
Conversation
Remove invalid FIXMEs and update TODOs Fixes for pylint and test for CarwingsError exception rather than Exception Flake8 fixes Add pycarwings2 to requirements_all.txt Add extra configuration documentation. Use pycarwings2 from pip. Check server dates between requests. Add sensor device class for battery. Async conversion fixes flake8 fixes and docstrings Non-async charging is OK Handle multiple cars in the configuration Convert to async. Better imports for platforms Fix scanning interval & prevent extra refreshes. async switchover Check discovery_info to prevent load of platforms Ensure update frequency is always above a minimum interval (1 min). Platforms don't have return values Use values() instead of items() when not using key Use snake_case (LeafCore becomes leaf_core) commit 418b6bb
dgomes
left a comment
There was a problem hiding this comment.
I'll leave to other reviewers to have a second go :)
|
Release 0.88 or 0.89? |
|
Thank you so much @filcole and @BenWoodford!!!! And all the reviewers 👍 Can't wait for the next release of HA |
|
@klaasnicolaas |
|
No, this will go out in 0.89. |
MartinHjelmare
left a comment
There was a problem hiding this comment.
Please open a new PR where we can address the comments.
Generally I think there is too much logging and the update logic seems complicated.
Consider use of async vs sync api. Don't do I/O in event loop.
I'm looking forward to the next PR.
|
|
||
| if vin in hass.data[DATA_LEAF]: | ||
| data_store = hass.data[DATA_LEAF][vin] | ||
| async_track_point_in_utc_time( |
There was a problem hiding this comment.
Why use the listener if we need to call the action now?
| try: | ||
| # This might need to be made async (somehow) causes | ||
| # homeassistant to be slow to start | ||
| await hass.async_add_job(leaf_login) |
There was a problem hiding this comment.
hass.async_add_job is legacy. Use hass.async_create_task for coroutines if we want to track the task and wait for completion before finishing setup phase. Otherwise use hass.loop.create_task if we don't want to wait for completion during setup phase.
| async def leaf_login(): | ||
| nonlocal leaf | ||
| sess = pycarwings2.Session(username, password, region) | ||
| leaf = sess.get_leaf() |
There was a problem hiding this comment.
We're not allowed to do I/O in event loop ie in coroutines. This needs to move to be scheduled on the executor thread pool. From async context that's done with hass.async_add_executor_job.
Any reason why we want to use the home assistant async api when the client library doesn't support asyncio? Usually it's easier to use our sync api if the library is sync.
| self.car.data[DATA_CLIMATE] = False | ||
|
|
||
| @property | ||
| def icon(self): |
There was a problem hiding this comment.
Remove this.
I don't understand the change needed here
There was a problem hiding this comment.
The switch entity already has frontend representation tailored to that entity. We usually don't overwrite this property for switches.
| if await self.car.async_start_charging(): | ||
| self.car.data[DATA_CHARGING] = True | ||
|
|
||
| def turn_off(self, **kwargs): |
There was a problem hiding this comment.
Remove this if we don't support it.
There was a problem hiding this comment.
Maybe this shouldn't be a switch at all? Maybe a scene is better?
There was a problem hiding this comment.
Yes, switch is sub-optimal. Perhaps sensor and service - discuss in new pull request.
@MartinHjelmare Thank you for the review, and also to @fabaff and @dgomes. I will submit another pull request when I've tried to address the issues raised. I hope you don't mind if I comment against the conversation points raised as I'm attempting to resolve them. |
|
When you say too much logging, do you mean logging using info or in general? Part of the reason for so much logging is that Nissan break their API on a semi-regular basis, and sometimes only for certain people (like how they only broke battery charge for older cars that report in bars). They have basically no sense of DevOps for API versioning/maintenance so the logging is needed at least on trace to debug issues that only occur for certain people. |
|
Both. Generally we don't want to log on info level in components. If it's not a warning or error, we should use debug. There are some more places where the debug logs only seem to be used to verify our own logic. That's not how we should use logging. If we need to verify our own logic, we should use tests. It's ok to log the result of an api but we should probably not log that we called the api, and definitely not log internal component variable changes. Sounds good? |
|
For more discussion I would prefer to have that in the new PR. It's ok to open that before it's completely ready. |
Description:
Adds support for monitoring and controlling the Nissan Leaf remote control platform.
Currently introduces two switches (climate control and charging, charging can only be turned on as per the API limitation), 3 sensors (battery charge and range with and without AC on), a binary sensor for if the car is currently plugged in, device tracker for the car location (if the car is capable).
I'm based in the UK with a 2016 30kWh leaf so assistance from others is very useful.
Example entry for configuration.yaml:
Checklist:
tox. Your PR cannot be merged unless tests passIf user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
REQUIREMENTSvariable (example).requirements_all.txtby runningscript/gen_requirements_all.py..coveragerc.If the code does not interact with devices:
home-assistant/home-assistant.io#8073