Nissan Leaf dashboard with charge limiter

Hi All,

Very new here but I wanted to share something that I’ve been working on the last few days. Those with a Nissan Leaf 2015 or later know that Nissan removed the old 80% charge option, so on any recent Leaf there is no officially supported way to charge to less than 100% other than manually keeping an eye on the charge level and unplugging it!

While the Nissan API allows a charge to be started remotely (if deferred by the charge timer) you can’t stop a charge via the API either, so extra hardware is needed to implement any sort of automated charge limiter. Very annoying.

Added to the mix I use the built in charge timer to charge my Leaf 30 in the early hours of the morning, which means I have the charge timer enabled in the car. I’ll shortly be switching to a cheaper night rate between 2am and 6am so charging needs to be within this time window.

I also use the timed climate control from 7:10 to 7:40 weekdays and this needs the charge point to be ON otherwise no climate control…

My charge point is an old 2017 Rolec “dumb EVSE” with no smart connectivity however some time ago I modified it using a Shelly One WiFi switch. I won’t go into too much detail about that modification here as it’s very specific to the model of EVSE, but for anyone curious you can read about it on speakev.com.

At the time I was mainly just using the schedule feature in the Shelly One and remote control by app, however I did implement one forward looking feature that has paid off with Home Assistant - the relay that switches the SW input of the Shelly.

This relay is only powered up when the main contactors close when the car actively requests power from the EVSE. The Shelly is configured with this switch input as a “detached switch” which only feeds state back but doesn’t control the relay in any way.

From a Home Assistant point of view the Shelly switch in this mode looks like a “switch” device (Car Charger Enabled, below) that you can turn on or off which enables and disables the EVSE, and a “binary_sensor” (Car Charger Active, below) which feeds back the state of whether the car is actually charging or not.

This ability to know instantly when the car has started or stopped charging without having to poll the Nissan API frequently to find out is key to the way I’ve designed my charge limiter and dashboard.

Here’s what my UI currently looks like - plain but functional:

By adjusting the Charge Limit slider I can choose whatever charge limit I want. I can also press a button to force an immediate refresh through the Nissan API, press a button to override the car’s charge timer, toggle the Climate control toggle to start or stop remote climate control and also manually toggle on/off the EVSE if I want to manually turn power off or on.

As well as providing the charge limit setting it duplicates pretty much all of functionality of the Nissan app apart from the driving statistics stuff… since I’ve had this UI up and running I’ve basically stopped using the Nissan app.

On the right you can see a graph of last nights charge which started at 2am and finished almost bang on the requested 85%. The timeline looks like this:

  1. The car’s built in timer starts charging at 2am - the EVSE is also scheduled to come on at 2am, although it’s usually already on from the previous day so this is just in case I turned it off manually for some reason and forgot to turn it back on.

  2. As soon as Car Charger Active changes to the on state (which happens instantly - the Shelly integration seems to work directly to the Shelly device across the network and is instantaneous) and other criteria are met the API is polled for the current SoC to get an initial figure and the Leaf integration then starts polling every 10 minutes to monitor the charging process.

  3. When the limit is reached an automation turns off the EVSE stopping the charge, or if the car was still charging at 6am the car stops charging by itself.

  4. At 6:10 the EVSE is scheduled (using the built in schedule of the Shelly One) to turn back on again, however because this is after the cars own charge window of 2am to 6am the car does not resume charging. (It charges for a few seconds only to “test” the power available from the EVSE)

  5. At around 7:10 the cars climate control timer starts plugged in climate control without charging the car to 100%. (Although in practice it can rise by up to 2%)

That’ll do for this post, in the next post I’ll discuss the automations that are working behind the scenes.

2 Likes

At the moment I have three automations to implement all this, one of them is optional. The first automation monitors the state of the binary sensor on the Shelly one to detect when the car starts and stops charging:

id: '1639094488633'
alias: Refresh Leaf Status start/end of charge
description: Refresh Status of Leaf when charge point turns on
trigger:
  - platform: state
    entity_id: binary_sensor.car_charger_input
condition: []
action:
  - delay:
      hours: 0
      minutes: 0
      seconds: 30
      milliseconds: 0
  - service: nissan_leaf.update
    data:
      vin: MY_VIN
  - delay:
      hours: 0
      minutes: 2
      seconds: 0
      milliseconds: 0
  - service: nissan_leaf.update
    data:
      vin: MY_VIN
mode: single

When it detects a state change on the binary sensor from the Shelly it waits 30 seconds, requests an API refresh from Nissan to update the SoC, waits 2 minutes and requests a second refresh.

I’ve found that sometimes the car provides stale data if that initial 30 second wait is not there, (although in theory that shouldn’t happen) so it polls again to make double sure that we receive updated state that includes both SoC and the Charging Status as the latter is needed later.

After these two initial API polls the Leaf Integration starts a regular 10 minute poll during the charging session to keep the SoC up to date.

When I arrive home and plug the car in the car’s charge timer prevents the car from charging until 2am, however the 3 second “test” charge that it does is enough to trigger this automation and force a refresh of the API, so within a couple of minutes of getting home and plugging the car in this information will be up to date.

This automation also triggers when the car stops charging (or running climate control) so that up to date data is available when everything is finished.

The automation that monitors the charging process itself looks like this:

id: '1639151966497'
alias: Simple Charge Limiter
description: Stop Charging Leaf when set state of charge is reached
trigger:
  - platform: state
    entity_id: sensor.leaf1sbyr_charge
  - platform: state
    entity_id: binary_sensor.leaf1sbyr_charging_status
    from: 'off'
    to: 'on'
  - platform: state
    entity_id: binary_sensor.car_charger_input
    from: 'off'
    to: 'on'
  - platform: state
    entity_id: switch.leaf1sbyr_climate_control
    from: 'on'
    to: 'off'
  - platform: state
    entity_id: input_number.leaf_charge_limit
condition:
  - condition: numeric_state
    entity_id: sensor.leaf1sbyr_charge
    above: input_number.leaf_charge_limit
    value_template: '{{ float(state.state) + 1 }}'
  - condition: state
    entity_id: binary_sensor.leaf1sbyr_charging_status
    state: 'on'
  - condition: state
    entity_id: binary_sensor.car_charger_input
    state: 'on'
  - condition: state
    entity_id: switch.leaf1sbyr_climate_control
    state: 'off'
  - condition: numeric_state
    entity_id: input_number.leaf_charge_limit
    below: '100'
  - condition: not
    conditions:
      - condition: time
        after: '06:00'
        before: '08:00'
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
action:
  - type: turn_off
    device_id: 21a8f0b2d6ad1130384cbc8ae93789c0
    entity_id: switch.car_charger
    domain: switch
mode: single
max: 10

This has a number of triggers that will fire it including change in SoC, Charging status (reported by the API) going from off to on, Car charger input (from the Shelly One) going from off to on, and climate control (from the car) going from on to off, or the charge limit slider in the UI being adjusted.

The conditions that have to be met for stopping the charge include SoC above charge limit, charging status reported by the car is on (this prevents the charge being stopped when only climate control is active!) car charger on (reported by the Shelly) as we don’t want to stop charging when the car is charging at a public charger away from home…and the charge limit has to be below 100%. (don’t try to stop charging under any circumstances if set to 100%, which doubles as a hard disable)

I’ve also thrown in a time restriction where it will NOT stop charging between 6am and 8am Monday to Friday - the period when climate control may be running.

This is to work around a couple of quirks in the Leaf.

  1. I check the climate control active status from the Leaf API to make sure climate control is not active but timed climate control does not show active climate control in the API! (only remote climate control)

  2. If you override the charge timer of the car remotely or by pressing the button on the dashboard, from that point onwards once a charge has started the override applies forever until the car is physically unplugged, turning of the EVSE is not enough.

This would cause the car to start charging again at 6:10am and attempt to charge to 100%, causing the automation to stop charging again, this would prevent timed climate control. In this scenario where I used manual charge override the day before and forgot to disconnect and reconnect the car I’d rather that it just charged to 100% and gave me climate control than stayed at 80% with no climate control!

When all the conditions are met the shelly switch is turned off and the car stops charging. At that point it will remain off until the next scheduled turn on point - either 6:10am for normal night time charging, or if I charged during the day, 2am.

Finally to improve the accuracy of hitting the target, a 3rd automation will increase the polling frequency to 5 minutes for the last 10% before reaching the charge limit:

id: '1639352576618'
alias: Refresh Leaf Status final 10%
description: Refresh charge every 5 minutes if charge is within 10% of target
trigger:
  - platform: state
    entity_id: sensor.leaf1sbyr_charge
condition:
  - condition: numeric_state
    entity_id: sensor.leaf1sbyr_charge
    above: input_number.leaf_charge_limit
    value_template: '{{ float(state.state) + 11 }}'
  - condition: state
    entity_id: binary_sensor.leaf1sbyr_charging_status
    state: 'on'
  - condition: state
    entity_id: binary_sensor.car_charger_input
    state: 'on'
  - condition: state
    entity_id: switch.leaf1sbyr_climate_control
    state: 'off'
  - condition: numeric_state
    entity_id: input_number.leaf_charge_limit
    below: '100'
  - condition: not
    conditions:
      - condition: numeric_state
        entity_id: sensor.leaf1sbyr_charge
        value_template: '{{ float(state.state) + 1 }}'
        above: input_number.leaf_charge_limit
action:
  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - service: nissan_leaf.update
    data:
      vin: MY_VIN
mode: single

The only trigger it has is changes in SoC.

It has several conditions however - SoC + 11 > charge limit, (this condition is met when SoC is 10% below the target) charging status on, car charger input on, climate control off, (although that doesn’t work for timed climate control as above) charge limit is below 100%, and also SoC is not equal to or greater than the charge limit.

If these conditions are met it waits 5 minutes and requests an API refresh. As this is triggered by a change in SoC from a previous API refresh this has the result of refreshing every 5 minutes and causing the default 10 minute refresh to be continually pushed forward.

Without this 5 minute refresh the SoC can overshoot up to 4-5% past the target, with the faster refresh at the end its usually within 2% or so.

A few final thoughts in the next post.

One thing that I wanted to implement from the beginning, but which I don’t have enough Home Assistant knowledge to do yet, is do predictive switching off of the charging session in between polling sessions.

Rather than increase polling frequency to 5 minutes when the target is near like I do now, the idea would be to take two or more recent measurements that include SoC and timestamps, calculate the rate of rise of SoC per 10 minutes and then work out if the target is going to be met before then next 10 minute polling period.

If it is, calculate how long to wait, sleep for that period of time in an automation or script then simply turn the charger off at the calculated time without polling the API again.

This should be pretty accurate and greatly reduce the amount of API polling, and also have the advantage that if the Nissan API stopped responding half way through the charge you could still extrapolate a reasonable charge end time as the charge rate is very linear right up to about 95%.

In other words at each polling time compare current and past SoC and timestamps, extrapolate when the charge should end, then use a script to sleep that amount of time before stopping the charge, however if that stopping time is beyond the next polling period the next time the API is polled and an updated estimate of charge end time is calculated the original script can be stopped and restarted with the new data.

So effectively you have a running estimated end time which keeps getting refined as you get closer to the end, however if the API dies part way through the charging session that last calculated stop time will be used. So even a full outage of the API once charging was underway would probably still give a fairly accurate end time to stop charging at.

However there are a couple of problems with implementing this:

  1. I don’t know enough about Home Assistant automations, scripts and especially performing math functions yet to know how to do this or how complex this might be - I get the feeling I may have to use the python integration or similar to break out the logic into some actual real scripting, so that may be what I end up doing as I’m reasonably OK with normal python coding.

  2. While the Leaf integration exposes a “last update” time - I believe this is only the last time the API is polled, not necessarily always the last time the data was fresh from the car, and if that’s the case you can’t rely on extrapolating if the data could be cached.

So I need to read the integration code a bit more or discuss that with the Leaf integration developers to see how the last update time is actually calculated and whether there is some way to properly expose the last update time from the API itself.

Apart from the above, future ideas I have for this UI are to have separate charge limit sliders for different days of the week, (I want at least weekday and weekend sliders) but I need to work out the best way to handle that first with input_numeric types (what’s the best way to choose a different input_number in a condition based on the day of the week ??) and also to add scheduled remote climate control.

I use the timed climate control in the mornings but when leaving work I use remote climate control - if I remember to turn it on that is… and the scheduler built into the Nissan app only allows to to schedule a single turn on time at once which is not very useful.

So having my own remote climate weekly schedule would be quite nice and relatively easy to implement!

Here’s the code for the UI, (an entities card) pretty simple, nothing fancy:

type: entities
entities:
  - type: attribute
    entity: sensor.leaf1sbyr_charge
    name: Last update from car
    icon: mdi:car
    attribute: updated_on
  - type: attribute
    entity: sensor.leaf1sbyr_charge
    name: Next update at
    icon: mdi:car
    attribute: next_update
  - type: button
    icon: mdi:reload
    name: Refresh Data
    action_name: Force Refresh
    tap_action:
      action: call-service
      service: nissan_leaf.update
      service_data:
        vin: MY_VIN
  - type: button
    icon: mdi:timer
    name: Charge Timer Override
    action_name: Start Charging
    tap_action:
      action: call-service
      service: nissan_leaf.start_charge
      service_data:
        vin: MY_VIN
  - entity: input_number.leaf_charge_limit
    icon: mdi:battery-charging-80
  - type: divider
  - entity: sensor.leaf1sbyr_charge
    secondary_info: last-updated
    name: State of Charge
  - entity: sensor.leaf1sbyr_range_ac
    secondary_info: last-updated
    name: Range (AC)
  - entity: sensor.leaf1sbyr_range
    secondary_info: last-updated
    name: Range
  - entity: binary_sensor.leaf1sbyr_plug_status
    secondary_info: last-updated
    name: Plug Status
  - entity: binary_sensor.leaf1sbyr_charging_status
    secondary_info: last-updated
    name: Charging Status
  - entity: switch.leaf1sbyr_climate_control
    secondary_info: last-updated
    name: Climate Control
  - type: divider
  - entity: switch.car_charger
    secondary_info: last-updated
  - entity: binary_sensor.car_charger_input
    secondary_info: last-updated
show_header_toggle: false
state_color: true

And the graphs:

type: history-graph
entities:
  - entity: switch.car_charger
    name: Charger Enabled
  - entity: binary_sensor.car_charger_input
    name: Charger Active
  - entity: binary_sensor.leaf1sbyr_charging_status
    name: Charging Status
  - entity: switch.leaf1sbyr_climate_control
    name: Climate Control
  - entity: sensor.leaf1sbyr_charge
    name: State of Charge
  - entity: input_number.leaf_charge_limit
hours_to_show: 12
refresh_interval: 0
1 Like

Oh, you’ll have so much fun with templates :slight_smile:

For time calculation, I do something similar with my VR headset:
Calculate how long to charge based on known rate of charge. 1 hour charges 50%, so I have an equation to calculate time need to charge based on current SoC.

charge_questvr:
  alias: charge questVR
  sequence:
    - service: switch.turn_on
      entity_id: switch.2132603268c63ae3a456
    - data:
        duration: "{{ 120 * (states.input_number.questvr_charge_percent.state|int(0)) / 100 * 60 }}"
        entity_id: timer.questvr_charge
      service: timer.start
  mode: restart

Implementing remote climate control timer is very easy. This is my scheduled charging automation:

- alias: Leaf - start charging timer
  id: '1556262896827'
  trigger:
  - platform: template
    value_template: '{{ states(''sensor.time'') == (state_attr(''input_datetime.leaf_start_charge'',
      ''timestamp'') | int(0) | timestamp_custom(''%H:%M'', False, now())) }}'
  condition: []
  action:
  - service: script.turn_on
    target:
      entity_id: script.leaf_start_charging
  - data:
      entity_id: automation.leaf_start_charging_timer
    service: automation.turn_off
  mode: single

Also, here’s my plug-in reminder:

- alias: Leaf - plug-in reminder
  id: '1560628547234'
  trigger:
  - at: '21:35'
    platform: time
  condition:
  - condition: state
    entity_id: binary_sensor.redleaf_plug_status
    state: 'off'
  - below: '52'
    condition: numeric_state
    entity_id: sensor.redleaf_charge
  action:
  - service: script.force_leaf_update
  - delay: 00:00:30
  - continue_on_timeout: true
    timeout: 00:15:00
    wait_template: '{{ states.binary_sensor.redleaf_plug_status.attributes.update_in_progress==
      false }}'
  - condition: state
    entity_id: binary_sensor.redleaf_plug_status
    state: 'off'
  - data:
      message: 'Reminder:  Plug in the car !! '
    service: notify.WYX_IPHONE_GRP

I’m not sure about fun - you’ll see I used Templates for a couple of trivial tasks like offsetting the state_numeric comparisons, but it felt more like an exercise in batting my head against a wall because despite there being quite a bit of documentation it’s just vague enough in the right places that I had a hell of a time getting the syntax “right”, (or at least a working syntax) as a lot of the examples given in the forum here didn’t actually work…

At 6kW my Leaf charges about 6% per 10 minutes, however I don’t want to hard code that. I want to record the last one or two SoC’s and time stamps and together with the current values calculate the actual slope based on that and use that to extrapolate. And each time a new SoC update comes in, recalculate it again to home into the final result.

Something seemingly simple like storing the SoC and last update datetime into variable storage for use by a future run of an automation is eluding me at the moment, and I’m sure I’d have to use a Template to do the actual calculation.

Quite a bit more reading and feeling my way around the functionality provided by HA will be neccessary before the solution appears to me.

Thanks - that gives me a starting point. I haven’t used datetime objects yet - can they be used in a mode where they’re only time and day of the week rather than calendar (numeric) dates ?

And where are you inputting the value for input_datetime.leaf_start_charge ? Do you have a widget in your UI for that so you can easily adjust it, like I have for my charge limit variable ?

Ideally I’d like to be able to specify zero, one or two timed climate control start times per day, for each day of the week, with the ability to click a check box or similar to turn off the ones I don’t need.

Still feeling my way around what the UI can accomodate at the moment to figure out how to handle a table of date/time UI elements.

I also want to have a separate charge limit slider for each day of the week - easy enough create them in the UI but I then need some way to pick the correct one for the day in the triggers and conditions, I presume something based on your value_template above might be able to look up the day of the week then somehow select the correct input_numeric to use for that day ? (Also that should probably only happen at the start of the charging session or charging sessions that cross a midnight boundary could get confusing!)

No need for that for me - the one built into the Nissan app works well for me. :slight_smile:

Yeah, I found it to involve a LOT of experiments in the Developer Tools → Template page. It’s mainly the datetime object that gives me the most trouble.

For storing values, use input_* helpers as they are called now. You’ll probably want to look at input_number.set_value service and use template in the data field.

Yes to both. See below for first, and use entities card for second :slight_smile:
If you are not going for super sleek UI with pictures, entities card is your best friend.

input_datetime:
  leaf_start_charge:
    name: Leaf start charge
    has_date: false
    has_time: true
    icon: mdi:car-electric

Check out schedule card? I’ve not used this myself, but might help with what you want to achieve.

There’s one built in to the app? I can’t find it… may be it’s not available for early CarWings.
Don’t worry about this, it’s off topic and HA method works well for me.

Yes I use the Developer Tools, Template page a lot but it’s still been hard wrapping my head around the syntax at first, especially when you have both yaml and jinja2 layered together, just figuring out where one starts and the other ends has taken a bit.

One simple thing that was tripping me up is quoting of single line yaml expressions. All the examples in documentation and forum posts show the raw yaml and say that you have to quote single line expressions but for some reason I hadn’t noticed that when I paste the same expression into the Web UI it is already quoting the line for me behind the scenes… whoops. It wasn’t until I switched to yaml mode that I saw it was being quoted twice, so I now always switch to the Yaml view to see what gets generated even when I’m using the Web UI to compose something.

Damn, what a find, thank you for that. :slight_smile: It took me all of 15 minutes to install that integration and a card and I now have a timer card where I have set up my 16:55 Monday-Friday climate control start and it works perfectly. The UI on that scheduler card is really good and it’s very quick and easy to add more time periods.

I also like that I can toggle individual schedules on and off with a click and also add conditions. For example I added a condition for my 16:55 leaving work climate timer so it doesn’t fire if the last known state of the car is plugged in. If I’m at home on a work day the car is generally plugged in (but timing deferred by the cars own timer) so it automatically detects the car is plugged in and doesn’t try to turn the climate control on if I forgot to adjust the schedule for that day… :slight_smile:

Using that schedule card has however reminded me that the switch on/off method for climate control always returns a failure after 3 seconds even though it does actually work. I need to dig into the integration code to find out what’s happening there as that seems like a bug perhaps due to changes in the Nissan API behaviour.

It’s built into the Nissan Connect EV head unit not the app - you can set a location aware unplugged reminder and a delay before it sends it. I have it set to 15 minutes and my home location as the only location where it reminds me. In the head unit it says “email alert” but it actually comes through as a push notification on the Nissan app.

1 Like

I’ve also been working on the weekly charge limit idea - I have an entities card with 7 Monday to Sunday sliders named input_number.leaf_charge_limit_0 through input_number.leaf_charge_limit_6.

The question is how to get each one to apply on the right day of the week. One way would be to use a Value template in the condition checks in the automation which checks the day of the week using now().weekday() this returns a numeric day of the week, however I don’t see an obvious way of using this number as an index to help build a variable name, (basically indirect addressing) and there are also multiple places where I need to check the charge limit so this complicates the automations significantly if they all need value templates.

Option two is to keep the existing slider as the one that all the conditions test against and copy the value from the appropriate week day input_number to the master input_number value (a) at midnight, (b) when the slider for today is adjusted it should be copied immediately.

One advantage of this approach is that if I want to temporarily change the charge limit for a daytime charging session I can directly adjust this slider without messing with the weekly values, knowing that the next weekly value will overwrite it automatically at midnight.

However to do this it’s going to need conditional jinja2 code by the looks of it, and I see the same issue where I don’t know how to take the numeric output of now().weekday() and tack it on the end of input_number.leaf_charge_limit_ and then index that variable. Is the language even capable of that kind of indirect indexing of variables ? If not that’s a big wad of if/else conditions or a case statement if it has one…at least there’s only 7 days in a week. :stuck_out_tongue:

Ok, I’m not proud of this brute force code, but it works… :joy:

alias: Weekly Charge Limit Schedule
description: >-
  Automation to handle copying daily charge limits to active charge limit at
  midnight
trigger:
  - platform: state
    entity_id: input_number.leaf_charge_limit_0
    id: '0'
  - platform: state
    entity_id: input_number.leaf_charge_limit_1
    id: '1'
  - platform: state
    entity_id: input_number.leaf_charge_limit_2
    id: '2'
  - platform: state
    entity_id: input_number.leaf_charge_limit_3
    id: '3'
  - platform: state
    entity_id: input_number.leaf_charge_limit_4
    id: '4'
  - platform: state
    entity_id: input_number.leaf_charge_limit_5
    id: '5'
  - platform: state
    entity_id: input_number.leaf_charge_limit_6
    id: '6'
  - platform: time
    at: '00:00'
    id: time
condition:
  - condition: state
    entity_id: input_boolean.charge_limit_schedule
    state: 'on'
action:
  - service: input_number.set_value
    target:
      entity_id: input_number.leaf_charge_limit
    data:
      value: >-
        {% set day = (now() + timedelta(minutes = 1)).weekday() %}
		{% if not trigger.id == 'time' and not trigger.id | int == day | int %}
		{{ states.input_number.leaf_charge_limit.state | float}}
		{% elif day == 0 %} {{ states.input_number.leaf_charge_limit_0.state | float }}
		{% elif day == 1 %} {{ states.input_number.leaf_charge_limit_1.state | float }}
        {% elif day == 2 %} {{ states.input_number.leaf_charge_limit_2.state | float }}
		{% elif day == 3 %} {{ states.input_number.leaf_charge_limit_3.state | float }}
		{% elif day == 4 %} {{ states.input_number.leaf_charge_limit_4.state | float }}
		{% elif day == 5 %} {{ states.input_number.leaf_charge_limit_5.state | float }}
        {% elif day == 6 %} {{ states.input_number.leaf_charge_limit_6.state | float }}
		{% endif %}
mode: single

If anyone knows a more elegant way of doing this than this if/elif/endif spaghetti code please let me know. :slight_smile:

The logic behind it is to find the current day of the week, then copy the appropriate input_number value to the target, however this only happens if the trigger is the time trigger at midnight, or if the user drags the weekly slider for today - in that case it updates the actual charge limit immediately. If not it leaves it alone. (by resetting the current value, as I wasn’t sure how to cancel a value set in a template without causing an error)

So my Leaf control dashboard is functionally complete now:

I don’t actually use the Nissan app anymore (apart from to receive notifications, which it continues to do even when Home Assistant’s use of the API has logged the Nissan app out…) as this dashboard replicates all the functionality of the app aside from the driving statistics which I seldom use, and is actually faster and more reliable…

3 Likes