Goodday everyone,
is there some hardware that is used only to be an “accesspoint for bluetooth”, i mean something to bridge the bluetooth dongle with my wifi, without setting up a dedicated PC. Tnx
Yep, this:
Guys is there any way to monitor battery charging, or atleast battery level when I pull into the driveway, in some way to measure how much power I use to charge the car?
I am about to buy the bluetooth dongle, but I’d just as soon buy an Emporia whole home energy monitor if it’s not possible to monitor charging with a bluetooth OBD dongle
I have a gen2 leaf, and it will only respond to requests via the dongle when the car is switched on. If you turn the car on when it’s charging, it stays on at least, but not a tremendously reliable strategy.
I also use a Wallbox charger which reports charging power and energy added (but not SoC) over WiFi: much more reliable.
I just put a deposit on a second gen leaf (2019 SL) and was planning on ordering a wallbox “charger” and hoping to find a way to get the SOC from the leaf so that I can use home assistant to control how full I charge the leaf. This looks like it might do it if I order a Bluetooth odb adapter?
Hi @peter.vk, I do exactly this.
I have a 2021 62kWh Lean, and a Wallbox Pulsar, which reliably reports the amount of energy added.
Since the OBD dongle can only fetch state of charge (SoC) while the car is switched on, I use an input_number helper to ‘save’ the last known SoC.
I then have an automation that calculates the estimated amount of energy to add to get to 80% SoC. This result is stored in another input_number helper.
(excuse the decimal places)
Another automation monitors the wallbox energy_added sensor and pauses charging once the target amount has been added.
One last little detail is that the wallbox energy_added sensor resets to zero when each time the car is plugged in. So I account for that.
Here’s the automations:
Save the SoC
alias: Update SoC
description: ""
trigger:
- platform: state
entity_id:
- sensor.nissan_leaf_state_of_charge
condition:
- condition: template
value_template: >
{% set state = states('sensor.nissan_leaf_state_of_charge') %}
{{state.isdigit() or state.replace('.', '', 1).isdigit() }}
alias: Check that the SoC is a valid number
action:
- metadata: {}
data:
value: "{{ states('sensor.nissan_leaf_state_of_charge') | float }}"
target:
entity_id: input_number.car_state_of_charge
action: input_number.set_value
mode: single
Calculate charge limit:
alias: Car SoC to kWh charge limit
description: ""
trigger:
- platform: state
entity_id:
- input_number.car_state_of_charge
condition:
- condition: template
value_template: >
{% set state = states('sensor.car_charger_added_energy') %}
{% if not state.isnumeric() and not state|float(false) %}
{{ false }}
{% endif %}
{{ true }}
action:
- if:
- condition: or
conditions:
- condition: state
entity_id: sensor.car_charger_status_description
state: Paused
- condition: state
entity_id: sensor.car_charger_status_description
state: Scheduled
- condition: state
entity_id: sensor.car_charger_status_description
state: Charging
alias: If the car is plugged in
then:
- metadata: {}
data:
value: >-
{% set SoC = (states('input_number.car_state_of_charge') | float) %}
{% set added_energy = (states('sensor.car_charger_added_energy') | float) %}
{% set target_percent = 80 %} {% set scale_factor = 68.7 %}
{% set remaining_energy = (target_percent - SoC) / 100 * scale_factor %}
{% set energy_limit = remaining_energy + added_energy %}
{{ [0, [scale_factor, energy_limit] | min] | max }}
target:
entity_id: input_number.car_charger_kwh_limit
alias: >-
Estimate the kWh limit based on current SoC and the amount already added
action: input_number.set_value
else:
- metadata: {}
data:
value: >-
{% set SoC = (states('input_number.car_state_of_charge') | float) %}
{% set target_percent = 80 %} {% set scale_factor = 68.7 %}
{% set target_energy = (target_percent - SoC) / 100 * scale_factor %}
{{ [0, [scale_factor, target_energy] | min] | max }}
target:
entity_id: input_number.car_charger_kwh_limit
alias: Estimate the kWh limit based on current SoC
action: input_number.set_value
mode: single
Cut off the charging:
alias: "Car charger: Charging cutoff"
description: ""
trigger:
- platform: numeric_state
entity_id:
- sensor.car_charger_added_energy
above: input_number.car_charger_kwh_limit
condition:
- condition: state
entity_id: sensor.car_charger_status_description
state: Charging
action:
- type: turn_off
device_id: 1643276e5d516342711e6a4ca97e725a
entity_id: fedb6af0f6fd631045aa53c65bd92cc4
domain: switch
mode: single
This is awesome, thanks for sharing! What ODB dongle did you buy?
Love the progress you’ve made and promise of this integration.
Think I’m missing something very basic about the setup to get info flowing from OBD to HA. Appreciate if anyone can give me a steer.
Progress
- I have LeLink OBD connected via LeafSpy for last 2 years.
- I just received M5Stack Atom Lite and flashed it as a Bluetooth Proxy
- This seems to be detected in HA automatically (pic).
But…
- I’m getting this error with the integration.
I assume I prob need to configure the Bluetooth Proxy to talk to my specific OBD? But where would I do that?
Appreciate this is probably a dumb question! I’ve been using HA ~9 months now but this will be the first BLE device I’m trying to integrate.
Thanks for all your efforts.
First of all - thank you very much for your work.
I have a 2016 Leaf AZE0 with 24kWh battery and I ordered Vgate iCar Pro BT4.0 dongle. It has separate UUID for read and write, but that was quite an easy fix in the code.
What is not so easy is that CAN messages are a bit different for ZE0/AZE0 (which was already prompted here). What works for LBC decode for my Leaf is:
"state_of_charge": int.from_bytes(d[30:34]) / 10000,
"hv_battery_health": int.from_bytes(d[28:30]) / 102.4,
"hv_battery_Ah": int.from_bytes(d[34:38]) / 10000,
"hv_battery_current_1": hv_battery_current_1 / 1024,
"hv_battery_current_2": hv_battery_current_2 / 1024,
"hv_battery_voltage": int.from_bytes(d[20:22]) / 100,
The odometer, remaining range and tire pressures sensor seem not to work, but I was testing with car plugged in and charging. I’ll check tommorow with just the igniton on
2024-09-19 23:04:54.815 DEBUG (MainThread) [custom_components.nissan_leaf_obd_ble.OBDCommand] Message was shorter than expected (3<6). Padded message: bytearray(b'\x7f"\x11\x00\x00\x00')
2024-09-19 23:04:54.815 INFO (MainThread) [custom_components.nissan_leaf_obd_ble.obd] Sending command: b'74303220e25': Tyre pressure front right
2024-09-19 23:04:55.009 DEBUG (MainThread) [custom_components.nissan_leaf_obd_ble.obd] Received frame: 763037F2211FFFFFFFF
2024-09-19 23:04:55.009 DEBUG (MainThread) [custom_components.nissan_leaf_obd_ble.OBDCommand] Message was shorter than expected (3<4). Padded message: bytearray(b'\x7f"\x11\x00')
2024-09-19 23:04:55.009 INFO (MainThread) [custom_components.nissan_leaf_obd_ble.obd] Sending command: b'74303220e26': Tyre pressure front left
2024-09-19 23:04:55.223 DEBUG (MainThread) [custom_components.nissan_leaf_obd_ble.obd] Received frame: 763037F2211FFFFFFFF
2024-09-19 23:04:55.223 DEBUG (MainThread) [custom_components.nissan_leaf_obd_ble.OBDCommand] Message was shorter than expected (3<4). Padded message: bytearray(b'\x7f"\x11\x00')
2024-09-19 23:04:55.223 INFO (MainThread) [custom_components.nissan_leaf_obd_ble.obd] Sending command: b'74303220e27': Tyre pressure rear right
2024-09-19 23:04:55.435 DEBUG (MainThread) [custom_components.nissan_leaf_obd_ble.obd] Received frame: 763037F2211FFFFFFFF
2024-09-19 23:04:55.436 DEBUG (MainThread) [custom_components.nissan_leaf_obd_ble.OBDCommand] Message was shorter than expected (3<4). Padded message: bytearray(b'\x7f"\x11\x00')
2024-09-19 23:04:55.436 INFO (MainThread) [custom_components.nissan_leaf_obd_ble.obd] Sending command: b'74303220e28': Tyre pressure rear left
2024-09-19 23:04:55.635 DEBUG (MainThread) [custom_components.nissan_leaf_obd_ble.obd] Received frame: 763037F2211FFFFFFFF
2024-09-19 23:04:55.635 DEBUG (MainThread) [custom_components.nissan_leaf_obd_ble.OBDCommand] Message was shorter than expected (3<4). Padded message: bytearray(b'\x7f"\x11\x00')
2024-09-19 23:04:55.635 INFO (MainThread) [custom_components.nissan_leaf_obd_ble.obd] Sending command: b'74303220e24': Remaining range (km)
2024-09-19 23:04:55.839 DEBUG (MainThread) [custom_components.nissan_leaf_obd_ble.obd] Received frame: 763037F2211FFFFFFFF
2024-09-19 23:04:55.839 DEBUG (MainThread) [custom_components.nissan_leaf_obd_ble.OBDCommand] Message was shorter than expected (3<13). Padded message: bytearray(b'\x7f"\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
Unfortunately the SoC parameter only updates when the car is on and does not update while charging. I did some investigation hoping I could add support of CAN monitoring via ELM327 for older Leafs that do not require CAN-polling, but it seems that the pyOBD library does not support that and I’m not sure I’m up to the task of doing it on my own. But who knows…
This is where the bt proxy yaml lives:
why not using a carwings integration? I have to admit it doesn’t provide as much data as I see the dongle does. But for charging purposes you can poll every n-minutes and retrieve the battery state.
No carwings here in New Zealand
check, I didn’t check your info, would have seen than you’re in New Zealand. A shame Nissan hasn’t made it possible to use this in New Zealand. Nice to see there are possibilities. Better than nothing.
Just wanted to say I really appreciate @pbutterworth 's work on this integration.
After a bit of playing around with the BLE proxy location and configuring some helpers to help convert and persist some of the data attributes I have this up and running in my dashboard.
A few limitations but really not a big deal for my use case:
- The data is only updated when car is powered on, usually briefly pulling in and out of the drive. Practically it means charging status and SOC is not updated when charging.
- I’m using helpers to persist data and when HA reboots, they loose their values. Will report ‘unavailable’ until the car again talks to the proxy.
Fun bonus:
I’ve setup a helper to remind me to regularly rotate my tires based on the car’s odometer reading and a “last rotated” helper.
Sharing YAML card config below if interested
- type: grid
cards:
- type: conditional
conditions:
- condition: numeric_state
entity: sensor.leaf_miles_to_tire_rotation
below: -499
card:
type: markdown
content: >-
<ha-alert alert-type="error"><ha-icon icon="mdi:tire"
style="width:3vw;height:3vw;"></ha-icon> **Nissan Leaf** Tire
Rotation is **OVERDUE**!</ha-alert>
- type: conditional
conditions:
- condition: numeric_state
entity: sensor.leaf_miles_to_tire_rotation
below: 0
above: -500
card:
type: markdown
content: >-
<ha-alert alert-type="warning"><ha-icon icon="mdi:tire"
style="width:3vw;height:3vw;"></ha-icon> **Nissan Leaf** Tire
Rotation is Due!</ha-alert>
- type: picture-elements
elements:
- type: state-icon
style:
bottom: "-25%"
left: 34%
entity: sensor.leaf_calculated_range
tap_action:
action: more-info
- type: state-label
style:
left: 34%
bottom: "-35%"
entity: sensor.leaf_calculated_range
tap_action:
action: more-info
- type: state-icon
style:
bottom: "-25%"
left: 50%
entity: sensor.nissan_leaf_obd_ble_state_of_charge
- type: state-label
style:
bottom: "-35%"
left: 50%
entity: sensor.nissan_leaf_obd_ble_state_of_charge
- type: state-icon
style:
left: 66%
bottom: "-25%"
entity: sensor.nissan_leaf_obd_ble_charging_mode
icon: mdi:ev-plug-type1
- type: state-label
style:
left: 66%
bottom: "-35%"
entity: sensor.nissan_leaf_obd_ble_charging_mode
layout_options:
grid_columns: full
grid_rows: 6
title: Leafy
image: /api/image/serve/852a9ce7c8a9080d38ac7dff3ba94e7f/512x512
dark_mode_image: /api/image/serve/be73511477a0cc17fac05546566c5d41/512x512
- type: tile
tap_action:
action: none
icon_tap_action:
action: none
name: Last Updated
hide_state: false
show_entity_picture: false
state_content: last_updated
vertical: false
color: blue-grey
icon: mdi:update
entity: sensor.nissan_leaf_obd_ble_state_of_charge
- type: tile
entity: sensor.leaf_calculated_odometer
name: Odometer
icon: mdi:speedometer
color: blue-grey
- type: custom:vertical-stack-in-card
cards:
- square: false
type: grid
columns: 4
cards:
- type: gauge
entity: sensor.leaf_fl_tire
name: Front Left
needle: false
min: 26
max: 50
segments:
- from: 0
color: "#db4437"
- from: 34
color: "#ffa600"
- from: 36
color: "#43a047"
- from: 40
color: "#ffa600"
- from: 42
color: "#db4437"
card_mod:
style: |
ha-card {
border: none;
box-shadow: 0px 0px;
}
- type: gauge
entity: sensor.leaf_fr_tire
name: Front Right
needle: false
min: 26
max: 50
segments:
- from: 0
color: "#db4437"
- from: 34
color: "#ffa600"
- from: 36
color: "#43a047"
- from: 40
color: "#ffa600"
- from: 42
color: "#db4437"
card_mod:
style: |
ha-card {
border: none;
box-shadow: 0px 0px;
}
- type: gauge
entity: sensor.leaf_bl_tire
name: Rear Left
needle: false
min: 26
max: 50
segments:
- from: 0
color: "#db4437"
- from: 34
color: "#ffa600"
- from: 36
color: "#43a047"
- from: 40
color: "#ffa600"
- from: 42
color: "#db4437"
card_mod:
style: |
ha-card {
border: none;
box-shadow: 0px 0px;
}
- type: gauge
entity: sensor.leaf_br_tire
name: Rear Right
needle: false
min: 26
max: 50
segments:
- from: 0
color: "#db4437"
- from: 34
color: "#ffa600"
- from: 36
color: "#43a047"
- from: 40
color: "#ffa600"
- from: 42
color: "#db4437"
card_mod:
style: |
ha-card {
border: none;
box-shadow: 0px 0px;
}
I’ve been keeping an eye on the work here as I am NZ based and I’m thinking it would bug me too much that I cannot read the SOC while the car is charging
Although getting odometer reading would allow for a reminder to renew road user charges which would be very useful!
One idea I’ve seen (possibly in this thread) is to setup a helper that estimates SOC while charging.
If your charger is integrated with HA you could take the SOC at start, kW rate, time, and battery size to get a pretty good estimate.
Yep, here: Custom component Nissan Leaf via LeLink 2 (ELM327) BLE - #43 by pbutterworth
Also worth noting that if the car is charging, and you turn it on, it stays on the whole time while charging (rather than switching off after 15 mins). So if you want to monitor SoC through a whole charge, there is a (not very satisfactory) way.
I also have a recharge reminder:
alias: Car low battery warning
description: ""
mode: single
triggers:
- entity_id:
- sensor.nissan_leaf_state_of_charge
below: 30
for:
hours: 0
minutes: 5
seconds: 0
trigger: numeric_state
conditions:
- condition: state
entity_id: sensor.car_charger_status_description
state: Ready
alias: Check that the car isn't plugged in already
actions:
- metadata: {}
data:
title: Nissan Leaf
message: My battery is quite low, did you mean to plug me in?
action: notify.notify
And can also plot a nice statistics graph using the odometer reading:
RUC reminder:
alias: RUC warning
description: Post a persistent notification when there is less than 500 km left on the RUC
mode: single
triggers:
- entity_id:
- sensor.nissan_leaf_odometer
value_template: "{{ states('input_number.leaf_ruc') | float - state.state | float }}"
below: 500
trigger: numeric_state
conditions: []
actions:
- metadata: {}
data:
title: Nissan Leaf
message: Road User Charges will expire in less than 500 km.
action: notify.persistent_notification
My charge rate varies depending on the amount of available solar sometimes so I’m sure the calcs would be possible but could become quite hairy
Does your charger report the amount of energy added in the current charging session? This is much more reliable if you have a varying charge rate.
This is what I’m using to decide when to cut off charging.
So you know what the car SoC was when it was last turned on.
And (if) you know how much energy has been added in the current charging session,
Then you can estimate the current SoC