Skip to content

Nissan Leaf Integration (Carwings / NissanConnect EV) #19786

Merged
fabaff merged 82 commits into
home-assistant:devfrom
filcole:nissanleaf
Feb 15, 2019
Merged

Nissan Leaf Integration (Carwings / NissanConnect EV) #19786
fabaff merged 82 commits into
home-assistant:devfrom
filcole:nissanleaf

Conversation

@filcole
Copy link
Copy Markdown
Contributor

@filcole filcole commented Jan 5, 2019

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:

nissan_leaf:
  username: "username"
  password: "password"
  region: 'NE'     # Indicates Europe, must be changed for other regions
  nissan_connect: true  # Set to false for early Leafs 24kWh that don't report location
  update_interval: 
    hours: 1
  update_interval_charging: 
    minutes: 15
  update_interval_climate: 
    minutes: 5
  force_miles: true

Checklist:

  • The code change is tested and works locally.
  • Local tests pass with tox. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • New dependencies have been added to the REQUIREMENTS variable (example).
  • New dependencies are only imported inside functions that use them (example).
  • New or updated dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

If the code does not interact with devices:

  • Tests have been added to verify that the new code works.

home-assistant/home-assistant.io#8073

Ben Woodford and others added 21 commits February 1, 2018 14:33
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
Copy link
Copy Markdown
Contributor

@dgomes dgomes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave to other reviewers to have a second go :)

Comment thread homeassistant/components/nissan_leaf/__init__.py
@ghost ghost assigned fabaff Feb 15, 2019
@fabaff fabaff merged commit 656d39e into home-assistant:dev Feb 15, 2019
@ghost ghost removed the in progress label Feb 15, 2019
@fabaff fabaff modified the milestone: 0.88.0 Feb 15, 2019
@klaasnicolaas
Copy link
Copy Markdown
Member

Release 0.88 or 0.89?

@stbenjam
Copy link
Copy Markdown
Contributor

stbenjam commented Feb 15, 2019

Thank you so much @filcole and @BenWoodford!!!! And all the reviewers 👍 Can't wait for the next release of HA

@bachya
Copy link
Copy Markdown
Contributor

bachya commented Feb 15, 2019

@klaasnicolaas This has been marked for 0.88. 👇

@MartinHjelmare
Copy link
Copy Markdown
Member

No, this will go out in 0.89.

Copy link
Copy Markdown
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(
Copy link
Copy Markdown
Member

@MartinHjelmare MartinHjelmare Feb 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use the listener if we need to call the action now?

Comment thread homeassistant/components/nissan_leaf/__init__.py
Comment thread homeassistant/components/nissan_leaf/__init__.py
try:
# This might need to be made async (somehow) causes
# homeassistant to be slow to start
await hass.async_add_job(leaf_login)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread homeassistant/components/nissan_leaf/sensor.py
Comment thread homeassistant/components/nissan_leaf/switch.py
Comment thread homeassistant/components/nissan_leaf/switch.py
self.car.data[DATA_CLIMATE] = False

@property
def icon(self):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this.

I don't understand the change needed here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this if we don't support it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this shouldn't be a switch at all? Maybe a scene is better?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, switch is sub-optimal. Perhaps sensor and service - discuss in new pull request.

@filcole
Copy link
Copy Markdown
Contributor Author

filcole commented Feb 16, 2019

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.

@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.

@BenWoodford
Copy link
Copy Markdown

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.

@MartinHjelmare
Copy link
Copy Markdown
Member

MartinHjelmare commented Feb 16, 2019

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?

@MartinHjelmare
Copy link
Copy Markdown
Member

For more discussion I would prefer to have that in the new PR. It's ok to open that before it's completely ready.

@filcole filcole mentioned this pull request Feb 17, 2019
9 tasks
@balloob balloob mentioned this pull request Mar 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants