Nissan Leaf Component(s)/Platform

Probably great stuff @filcole … but what does any of that mean? :blush:

@RoadkillUK - the goal is to get a Nissan Leaf integration included part of the normal HomeAssistant releases so that people don’t have to install a custom component.

1 Like

I picked up a new Leaf earlier this week, so I’m happy to contribute with testing if needed.

I think our biggest issue is going to be that if Nissan keep messing around with their API it’s constantly going to break the component and it’s a lot harder to update it when it’s part of the main codebase.

Though I suppose you could wildcard the minor version number requirement for pycarwings2 and force through an update that way? As most fixed will be in there. Pretty sure we can do that right?

The big thing is going to be refactoring so that the response checking is not done as a blocking process really. Which basically means doing the checks once during the check interval.

Hi @BenWoodford.

In my pull request I’ve hopefully made the code async friendly so that it’s non-blocking. If the Nissan APIs keep changing we’ll have to stay on top of it, but this should be possible now that it’s published to PyPi. Also dartcarwings is doing a good job of keeping up to date, so I’m going to keep monitoring that codebase for changes/tips/enhancements.

Pull request https://github.com/home-assistant/home-assistant/pull/19786 has been updated.

  • Hass now starts more quickly, and updates the car status once a request to start charging has been posted.
  • It now passes HomeAssistant Travis CI test, so I’m going to write some docs.

It now detects if the traction battery goes below 2%, and if so limits the polling to every 12 hours. This might protect against the possibility of lots of updates flattening the 12V battery. The traction battery replenishes the 12V battery when so long the car is not plugged in. Additionally, the minimum polling frequency is limited to every two minutes.

To Help Test
Copy the following files into your local home assistant installation, in the same directory structure. I’m not using hass.io, so I’m afraid I can’t help here.

add the following settings into .homeassistant/configuration.yaml. The configuration options are pretty much as per the @BenWoodford’s original setup:

nissan_leaf:
    username: '<username/email>'
    password: '<password>'
    region: '<region>'                  (see first post for options)
    nissan_connect: [ true | false ]    (optional, defaults to true - see first post)
    update_interval:
        minutes: <minutes>    (default is 1 hour)
    update_interval_charging:
        minutes: <minutes>    (default is 15) 
    update_interval_climate:
        minutes: <minutes>    (default is 5)
    force_miles: true

TODO:

  • Get reviewed and committed to core homeassistant

DONE:

Potential improvements (likely to be left until the initial pull request is reviewed):

  • Service to trigger request to update car information without having to wait for automations
  • Consider allowing intervals of 0, to identify that polling shouldn’t be done - allowing the user to set the updates to be configured
  • Expose the last date the information was retrieved from the car in homeassistant (as an attribute?)
  • Pull the information from Nissan servers (rather than waiting for update from car) to show stale data on the sensors, and then refresh with new data from the car.
1 Like

I just took the files in to Hass.io and it doesn’t work.

It may be connected to me putting this in to the custom_components, but that’s where I had the files before and when it semi-worked. So I just replaced the files with the new ones.

Error loading custom_components.binary_sensor.nissan_leaf. Make sure all dependencies are installed

Traceback (most recent call last): File “/usr/local/lib/python3.6/site-packages/homeassistant/loader.py”, line 92, in get_component module = importlib.import_module(path) File “/usr/local/lib/python3.6/importlib/init.py”, line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File “<frozen importlib._bootstrap>”, line 994, in _gcd_import File “<frozen importlib._bootstrap>”, line 971, in _find_and_load File “<frozen importlib._bootstrap>”, line 955, in _find_and_load_unlocked File “<frozen importlib._bootstrap>”, line 665, in _load_unlocked File “<frozen importlib._bootstrap_external>”, line 678, in exec_module File “<frozen importlib._bootstrap>”, line 219, in _call_with_frames_removed File “/config/custom_components/binary_sensor/nissan_leaf.py”, line 9, in <module> from homeassistant.components.nissan_leaf import ( ModuleNotFoundError: No module named ‘homeassistant.components.nissan_leaf’

Unable to find component binary_sensor.nissan_leaf

Unable to prepare setup for platform binary_sensor.nissan_leaf: Platform not found.

Error loading custom_components.switch.nissan_leaf. Make sure all dependencies are installed

Traceback (most recent call last): File “/usr/local/lib/python3.6/site-packages/homeassistant/loader.py”, line 92, in get_component module = importlib.import_module(path) File “/usr/local/lib/python3.6/importlib/init.py”, line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File “<frozen importlib._bootstrap>”, line 994, in _gcd_import File “<frozen importlib._bootstrap>”, line 971, in _find_and_load File “<frozen importlib._bootstrap>”, line 955, in _find_and_load_unlocked File “<frozen importlib._bootstrap>”, line 665, in _load_unlocked File “<frozen importlib._bootstrap_external>”, line 678, in exec_module File “<frozen importlib._bootstrap>”, line 219, in _call_with_frames_removed File “/config/custom_components/switch/nissan_leaf.py”, line 8, in <module> from homeassistant.components.nissan_leaf import ( ModuleNotFoundError: No module named ‘homeassistant.components.nissan_leaf’

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File “/config/custom_components/nissan_leaf.py”, line 223, in async_update_data
await self.async_refresh_data(now)
File “/config/custom_components/nissan_leaf.py”, line 328, in async_refresh_data
climate_response = await self.async_get_climate()
File “/config/custom_components/nissan_leaf.py”, line 404, in async_get_climate
self.leaf.get_latest_hvac_status
File “/usr/local/lib/python3.6/concurrent/futures/thread.py”, line 56, in run
result = self.fn(*self.args, **self.kwargs)
File “/config/deps/lib/python3.6/site-packages/pycarwings2/pycarwings2.py”, line 395, in get_latest_hvac_status
return CarwingsLatestClimateControlStatusResponse(response)
File “/config/deps/lib/python3.6/site-packages/pycarwings2/responses.py”, line 312, in init
racr[“OperationResult”] and
TypeError: list indices must be integers or slices, not str

There were a few more errors, but those are the same as the above but for other components.

Hi @Abertil,
Thanks for trying to test. I’ve not been testing with custom_components, since I’ve been working on getting this installed as a full homeassistant component/platform. I put the files directly in and under the components folder of the installation, so in your case: /usr/local/lib/python3.6/site-packages/homeassistant/components/

I’m going to give custom_components a go, because it will also make testing easier. Also remember to enclose the login, password and region in quotes in the configuration.

Hi @filcole, firstly thanks for taking this on, we appreciate it.

I have my HA installed on windows and after a lot of searching for my HA installation, I can confirm that it’s working so far.

I did find this in the log after starting up HA…

2019-01-05 18:45:45 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "C:\Users\Lee\AppData\Local\Programs\Python\Python36-32\lib\site-packages\homeassistant\components\nissan_leaf.py", line 234, in async_update_data
    await self.async_refresh_data(now)
  File "C:\Users\Lee\AppData\Local\Programs\Python\Python36-32\lib\site-packages\homeassistant\components\nissan_leaf.py", line 339, in async_refresh_data
    climate_response = await self.async_get_climate()
  File "C:\Users\Lee\AppData\Local\Programs\Python\Python36-32\lib\site-packages\homeassistant\components\nissan_leaf.py", line 415, in async_get_climate
    self.leaf.get_latest_hvac_status
  File "C:\Users\Lee\AppData\Local\Programs\Python\Python36-32\lib\concurrent\futures\thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "C:\Users\Lee\AppData\Roaming\.homeassistant\deps\Python36\site-packages\pycarwings2\pycarwings2.py", line 395, in get_latest_hvac_status
    return CarwingsLatestClimateControlStatusResponse(response)
  File "C:\Users\Lee\AppData\Roaming\.homeassistant\deps\Python36\site-packages\pycarwings2\responses.py", line 312, in __init__
    racr["OperationResult"] and
TypeError: list indices must be integers or slices, not str

Oh wow you’ve been busy @filcole!

You shouldn’t be able to know when the battery is below 2% until it hits 0, we only get a battery level out of 12 bars so the lowest resolution you can get is increments 8.3%

The Nissan app is so bad that the component really should be a replacement for many, so getting stale values probably isn’t going to be that worthwhile as HASS would have up to date values anyway as it would have been the last one to ask for values from the car 95% of the time.

Perhaps make the battery level and increment configurable too? 12 hours is a hell of a long time and would be annoying if you then don’t get a battery level for half a day when you plug it in (after all, you’re going to want to monitor charge when it’s plugged in!)

None of this would be necessary if Nissan had actually implemented this properly and had the car push regular updates

Cool, I’ll wait for the next update. It was working earlier, so I think the config part should be ok.

Hi @BenWoodford, On later leafs (at least post 2016 30kWh) provide a SOC output, which shows the actual stage of charge/battery level as shown on the dashboard. I believe the 12V doesn’t get charged when the car is plugged in, but I can’t confirm that, so having your car plugged in actually a disadvantage for the 12V status!

I think it’s going to have to be made configurable, but I don’t want to add loads of configuration options which will get confusing.

This error

  File "C:\Users\Lee\AppData\Roaming\.homeassistant\deps\Python36\site-packages\pycarwings2\responses.py", line 312, in __init__
    racr["OperationResult"] and
TypeError: list indices must be integers or slices, not str

looks like a problem in pycarwings2 library. I’ve raised Issue 3 on the pycarwings2 library.

Can you restart home assistant with the following in configuration.yaml (at least the last two lines). Thanks

logger:
    default: critical
    logs:
        homeassistant.components.nissan_leaf: debug
        pycarwings2: debug

For the folks sat at home, I’ve emailed the log to @filcole and he’s on it.

1 Like

I’ve released version 2.3 of pycarwings2 that includes this fix, plus one other for a divide by zero glitch should the battery capacity be reported as zero. The homeassistant component has been updated to use this new library, so please download the files in comment 146 and try again. Thanks for reporting. :smile:

Ah, yes perhaps the NissanConnect models do. I have a CarWings model.

I would still suggest basing it on intervals of 8.3% though, as the CarWings models are the lowest common denominator and you won’t see those showing 2% until they hit 0% (though we should probably round down, I think the component rounds up to the nearest 8.3% right now)

I don’t think more configuration options is necessarily a bad thing, especially if they’re optional. This is HASS after all, you don’t really get anywhere with it without editing streams of YAML.

Are you actually getting battery and climate control states now? Because I’m still not, at least not on my older version of the component.

Is there anyone else using this, as I don’t think it’s updating. The only time it’s refreshed battery is when I restarted HA. Also, I use an automation to turn on the Climate Control, in HA even when the CC has been on but is no longer active, the binary switch still shows as on.

I ask if anyone else is using it as I’m in the process of updating my router as I’m having some issues with it sometimes, so it could be my end.

While I’m here, I’ve restarted my HA and the battery is showing 109% (it’s actually 96%) … I’m sure this is just a matter of maths as my battery has lost 1 bar :frowning:

Thanks for the info. I’m having difficulties logging into the official Nissan Connect EV app at the moment. Appears the website is down. If you’re getting duff data returned then I think it’s due to the pycarwings2 library again. Another log file would be great. 24kWh leafs return different data so difficult for me to test. I’m going to try to expose another sensor, or attribute of a sensor with the last datetime the data was updated and the next scheduled update time.

I’ll send it tomorrow, let it do it’s thing for a while.

Hello, i’ve tryed your code and i got this message:
(i’m not on HASS)

2019-01-09 19:56:33 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/config/custom_components/nissan_leaf.py", line 187, in async_update_data
await self.async_refresh_data(now)
  File "/config/custom_components/nissan_leaf.py", line 292, in async_refresh_data
climate_response = await self.async_get_climate()
  File "/config/custom_components/nissan_leaf.py", line 368, in async_get_climate
self.leaf.get_latest_hvac_status
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
result = self.fn(*self.args, **self.kwargs)
  File "/config/deps/lib/python3.6/site-packages/pycarwings2/pycarwings2.py", line 397, in get_latest_hvac_status
return CarwingsLatestClimateControlStatusResponse(response)
  File "/config/deps/lib/python3.6/site-packages/pycarwings2/responses.py", line 319, in __init__
racr.length > 0 and
AttributeError: 'list' object has no attribute 'length'