Advice on Tracking EV Charging Sessions in Home Assistant

Hello,
I’m new to Home Assistant (HA) and would like some advice. My goal is to track my car’s charging sessions, including the following details:

Date and duration
Odometer reading
Battery level at the start and end of charging
Energy used
Ultimately, I want to list these sessions and generate statistics (e.g., consumption per week, day of the week, month, year, etc.).
So far, I’ve created automations to trigger when charging starts and stops, and I’m successfully capturing the relevant data. However, I have a few questions about the next steps:

  1. Storing Initial Data: How can I store the initial battery level and the start of a charging session and retrieve it when the session ends?
  2. Storing Session Data: Where and how should I store the final state of each charging session ?
  3. Viewing Historical Data: How can I visualize charging sessions over time?
  4. Manual Entry: Is it possible to manually add charging sessions (e.g., when charging outside my home)?
  5. Statistics and Graphs: What’s the best way to generate statistics and graphs? This could be done outside HA (e.g., in Excel) if needed.
    Thank you for your advice!

I guess that depends a bit on how you integrated your car (if your car can be integrated at all :thinking:)

I am currently in the process on setting up my own charging station, but that is the other side of what you want.
The history of my car is already available in mySkoda integration:

I use the hyundai/kia integration, and huawei fusion solar for the wallbox and they both work well, I can also display such graph. What I still need is a way to correlate this with the odometer and perform a consumption calculation and display them. I would also like to correlate my wall box energy usage to estimate loss.

What I have done so far:

##############################
# AUTOMATION DEBUT DE CHARGE
##############################

automation:
  - alias: EV1 - Début de charge
    mode: single
    trigger:
      - platform: numeric_state
        entity_id: sensor.fsp_ne_237114670_output_power
        above: 1
    condition:
      - condition: state
        entity_id: input_boolean.my_ev1_is_charging
        state: "off"
    action:
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean.my_ev1_is_charging

      - service: input_datetime.set_datetime
        target:
          entity_id: input_datetime.my_ev1_charge_start
        data:
          datetime: "{{ now().isoformat() }}"

      - service: input_number.set_value
        target:
          entity_id: input_number.my_ev1_soc_start
        data:
          value: "{{ states('sensor.inster_ev_battery_level') | float(0) }}"

      - service: input_number.set_value
        target:
          entity_id: input_number.my_ev1_km_start
        data:
          value: "{{ states('sensor.inster_odometer') | float(0) }}"

      - service: input_number.set_value
        target:
          entity_id: input_number.my_ev1_energy_start
        data:
          value: "{{ states('sensor.fsp_ne_237114670_total_energy') | float(0) }}"

      - service: input_number.set_value
        target:
          entity_id: input_number.my_ev1_grid_import_start
        data:
          value: "{{ states('sensor.fsp_ne_237114626_imported_grid_energy') | float(0) }}"

      - service: input_number.set_value
        target:
          entity_id: input_number.my_ev1_battery_discharge_start
        data:
          value: "{{ states('sensor.fsp_ne_237114728_energy_discharged_today') | float(0) }}"

      - service: input_number.set_value
        target:
          entity_id: input_number.my_ev1_pv_energy_start
        data:
          value: "{{ states('sensor.fsp_ne_237114626_today_energy') | float(0) }}"

##############################
# AUTOMATION FIN DE CHARGE
##############################

  - alias: EV1 - Fin de charge
    mode: single
    trigger:
      - platform: numeric_state
        entity_id: sensor.fsp_ne_237114670_output_power
        below: 1
        for:
          minutes: 1
    condition:
      - condition: state
        entity_id: input_boolean.my_ev1_is_charging
        state: "on"
    action:
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.my_ev1_is_charging    
      - variables:
          energy_end: "{{ states('sensor.wallbox_energy_total') | float(0) }}"
          energy_start: "{{ states('input_number.my_ev1_energy_start') | float(0) }}"
          total_charge: "{{ (energy_end - energy_start) | round(2) }}"

          duration_min: >
            {{ ((as_timestamp(now())
               - as_timestamp(states('input_datetime.my_ev1_charge_start'))) / 60) | round(0) }}

      - service: input_number.set_value
        target:
          entity_id: input_number.my_ev1_soc_end
        data:
          value: "{{ states('sensor.kia_ev_battery_level') | float(0) }}"


I had a similar idea this month and wanted to track my EV charging sessions. Unfortunately, BMW doesn’t currently allow integration with Home Assistant. So, I’ve only integrated the monitoring of my wallboxes into Home Assistant. I’m using Shelly power meters.

You can indeed get data from your BMW, please take a look at this repository, myself and many others have been using it for some time.

Do you have sensors and entities for all the items you wish HomeAssistant to store in the database for future recollection?
For instance: Does your vehicle integration expose odometer values, or are you going to add that manually?
Does your animation reflect the start and end of a charging session? Battery level?
There are many ways of displaying your data once it is recorded, some on dashboards (they got a major revamp this month), some of graphing packages and integrations such as Graphana, and you shouldn’t need to export data to Excel just to get pretty pictures.

Yes have all needed data. Just need to know what to do with them and all to see them all at once.

That is most of your challenge met.

The rest is up to you - your preferences and whims. There are many methods of viewing the data you have collected. Two approaches: first is to experiment following the documentation bit by bit, and the second is to have a goal usially based on something you have seen, and then work toward it. Both are valid. If you share what you have done when reaching an impasse, others can offer hints and suggestions.

Hi there,

Here's is what I'm using to record data into a input_text, but now, I'm trying to figure out how to display it in a way that it's tidy, visual and accesible.

To gather all data, I used, because I wanted to keep a record of how many kWh has used from the grid or solar power, so I can know exactly how much is the cost for that precise charging session.

It records:

  • Date and time of charging session
  • How many kWh has the EV consumed.
  • How many of those are from solar power.
  • How many from the Grid.
  • Starting and ending % of battery.
  • Session duration.
  • Cost (only grid kWh consumed)

``` - alias: "Register EV charging session"
description: "Get data at start and end of charging session, 5 session history."

trigger:

  • platform: state
    entity_id: binary_sensor.v2c_trydan_charging
    to: "on"
    id: inicio_carga
  • platform: state
    entity_id: binary_sensor.v2c_trydan_charging
    from: "on"
    to: "off"
    id: fin_carga

action:

  • choose:

    ─── START OF CHARGING SESSION ─────────────────────────────────

    • conditions:
      • condition: trigger
        id: inicio_carga
        sequence:

      • action: input_number.set_value
        target:
        entity_id: input_number.carga_red_inicio
        data:
        value: "{{ states('sensor.power_meter_consumption') | float(0) }}"

      • action: input_number.set_value
        target:
        entity_id: input_number.carga_bateria_inicio
        data:
        value: "{{ states('sensor.ev3_car_battery_level') | float(0) | round(0) }}"

    ─── END OF CHARGING SESSION ────────────────────────────────────

    • conditions:
      • condition: trigger
        id: fin_carga
        sequence:

      • variables:
        nueva_sesion: >
        {% set kwh_total = states('sensor.v2c_trydan_charge_energy') | float(0) | round(3) %}
        {% set red_fin = states('sensor.power_meter_consumption') | float(0) %}
        {% set red_inicio = states('input_number.carga_red_inicio') | float(0) %}
        {% set kwh_red = [0, (red_fin - red_inicio)] | max | round(3) %}
        {% set kwh_solar = [0, (kwh_total - kwh_red)] | max | round(3) %}
        {% set precio = 0.11 %}
        {% set coste = (kwh_red * precio) | round(2) %}
        {% set duracion_seg = states('sensor.v2c_trydan_charge_time') | int(0) %}
        {% set horas = (duracion_seg // 3600) %}
        {% set minutos = ((duracion_seg % 3600) // 60) %}
        {{
        {
        "fecha": now().strftime('%d/%m/%Y %H:%M'),
        "kwh_total": kwh_total,
        "kwh_red": kwh_red,
        "kwh_solar": kwh_solar,
        "pct_solar": ((kwh_solar / kwh_total * 100) | round(0) | int) if kwh_total > 0 else 0,
        "duracion": horas ~ "h " ~ minutos ~ "min",
        "bateria_inicio": states('input_number.carga_bateria_inicio') | int(0),
        "bateria_fin": states('sensor.ev3_car_battery_level') | int(0),
        "coste": coste
        } | tojson
        }}

      • action: input_text.set_value
        target:
        entity_id: input_text.sesion_carga_5
        data:
        value: "{{ states('input_text.sesion_carga_4') }}"

      • action: input_text.set_value
        target:
        entity_id: input_text.sesion_carga_4
        data:
        value: "{{ states('input_text.sesion_carga_3') }}"

      • action: input_text.set_value
        target:
        entity_id: input_text.sesion_carga_3
        data:
        value: "{{ states('input_text.sesion_carga_2') }}"

      • action: input_text.set_value
        target:
        entity_id: input_text.sesion_carga_2
        data:
        value: "{{ states('input_text.sesion_carga_1') }}"

      • action: input_text.set_value
        target:
        entity_id: input_text.sesion_carga_1
        data:
        value: "{{ nueva_sesion }}" ```

Now I’m struggling to find a way to display it nicely… But, the data is there.