Car Dashboard - Volkswagen ID3 2021

I would like to share my current dashboard setup for a 2021 Volkswagen ID3.

I have used these integrations and lovelace plugins:

This setup features a lot of information at a first glance such as:

  • Current Range left in the battery
  • State of Charge (with a progress bar)
  • State of Home Socket
  • Power Consumption of Home Socket
  • Information about charge given by the car
    • Speed of Charge in km/h
    • Power of Charge in kW
    • Minutes until target SoC is reached

Even more details can be seen when clicking on different things:

  • Clicking on the picture of the car opens a more-info popup, showing a graph of the last 24hrs and a tooltip of the place where you’re hovering the mouse:
    image

  • Clicking & Holding on the picture of the car opens a more-info popup of a graph of the last 24hrs tooltip of the place where you’re hovering the mouse:
    image

  • Clicking on the speedometer icon opens a custom popup with some information as text and controls for the AC Charge Speed:
    image

  • Clicking on the target icon opens a custom popup with some information as text and controls for the Target SoC:
    image

It also allows a few controls:

  • Toggle Home Socket
  • Change speed of Charge
  • Change Target SoC

A small detail that I added is in the button of the home socket.
In its on state it shows its state “on” and the power draw “(2176.3W)” in this case:
image

I didn’t like the fact, that when the socket was off it was showing “Off (0.0W)”, so I changed it to just “Off”, like this:
image

This is what the interaction looks like:
screen_recording_vw_id3_panel

If you want to replicate this, be warned! The code is not very clean yet and there are a lot of templates and such.

I want to see the code, even if it's not clean

Code of the card

type: vertical-stack
cards:
  - type: custom:button-card
    show_name: true
    show_icon: true
    show_state: true
    triggers_update:
      - sensor.denim_flash_state_of_charge
      - sensor.denim_flash_max_charge_current_ac
      - sensor.denim_flash_range_in_kilometers
      - sensor.denim_flash_target_state_of_charge
    custom_fields:
      range: |
        [[[
          return states['sensor.denim_flash_range_in_kilometers'].state+" "+states['sensor.denim_flash_range_in_kilometers'].attributes.unit_of_measurement
        ]]]
      progress_bar_soc: P
      progress_bar_soc_bg: P
      progress_bar_red: P
      target_soc:
        card:
          type: custom:button-card
          color: var(--secondary-text-color)
          show_name: false
          styles:
            card:
              - box-shadow: none
          icon: mdi:target
          size: 26px
          tap_action:
            action: fire-dom-event
            browser_mod:
              service: browser_mod.popup
              data:
                title: Target State of Charge
                style: >
                  --popup-min-width: 400px;

                  --popup-max-width: 600px;

                  --popup-border-width: var(--ha-card-border-width, 2px);

                  --popup-border-color: var(--ha-card-border-color,
                  var(--divider-color, #eee));

                  --popup-border-radius: var(--ha-card-border-radius);

                  --popup-background-color: var(--ha-card-background,
                  var(--card-background-color, white));

                  --popup-padding-x: 1vw;

                  --popup-padding-y: 20px;
                content:
                  type: vertical-stack
                  cards:
                    - type: markdown
                      card_mod:
                        style: |
                          ha-card {
                            margin-top: -30px;
                          }
                          ha-markdown.no-header {
                            padding-left: 0;
                            padding-right: 0;
                          }
                      content: >-
                        For best battery life, please select a target SoC of 80%
                        or lower.

                        After selecting your target SoC, it can take up to 1
                        minute for it to update.
                    - type: horizontal-stack
                      cards:
                        - type: custom:button-card
                          template: soc_target
                          variables:
                            target: 50
                        - type: custom:button-card
                          template: soc_target
                          variables:
                            target: 60
                        - type: custom:button-card
                          template: soc_target
                          variables:
                            target: 70
                        - type: custom:button-card
                          template: soc_target
                          variables:
                            target: 80
                        - type: custom:button-card
                          template: soc_target
                          variables:
                            target: 90
                            text_color: var(--label-badge-red)
                        - type: custom:button-card
                          template: soc_target
                          variables:
                            target: 100
                            text_color: var(--label-badge-red)
      ac_charge_speed:
        card:
          type: custom:button-card
          color: var(--secondary-text-color)
          show_name: false
          entity: sensor.denim_flash_max_charge_current_ac
          styles:
            card:
              - box-shadow: none
          icon: mdi:speedometer-medium
          state:
            - value: unavailable
              icon: mdi:speedometer-medium
            - value: maximum
              icon: mdi:speedometer
            - value: reduced
              icon: mdi:speedometer-slow
          size: 26px
          tap_action:
            action: fire-dom-event
            browser_mod:
              service: browser_mod.popup
              data:
                title: AC Charge speed
                style: >
                  --popup-min-width: 400px;

                  --popup-max-width: 600px;

                  --popup-border-width: var(--ha-card-border-width, 2px);

                  --popup-border-color: var(--ha-card-border-color,
                  var(--divider-color, #eee));

                  --popup-border-radius: var(--ha-card-border-radius);

                  --popup-background-color: var(--ha-card-background,
                  var(--card-background-color, white));

                  --popup-padding-x: 1vw;

                  --popup-padding-y: 20px;
                content:
                  type: vertical-stack
                  cards:
                    - type: markdown
                      content: >-
                        Allows you to select the speed of charge on AC Chargers
                        only.

                        After selecting your AC Charge speed, it can take up to
                        1 minute for it to update.
                      card_mod:
                        style: |
                          ha-card {
                            margin-top: -30px;
                          }
                          ha-markdown.no-header {
                            padding-left: 0;
                            padding-right: 0;
                          }
                    - type: horizontal-stack
                      cards:
                        - type: custom:button-card
                          template: ac_charge_speed
                          variables:
                            speed: reduced
                        - type: custom:button-card
                          template: ac_charge_speed
                          variables:
                            speed: maximum
    hold_action:
      action: fire-dom-event
      browser_mod:
        service: browser_mod.popup
        data:
          title: Range History
          style: >
            --popup-min-width: 400px;

            --popup-max-width: 600px;

            --popup-border-width: var(--ha-card-border-width, 2px);

            --popup-border-color: var(--ha-card-border-color,
            var(--divider-color, #eee));

            --popup-border-radius: var(--ha-card-border-radius);

            --popup-background-color: var(--ha-card-background,
            var(--card-background-color, white));

            --popup-padding-x: 1vw;

            --popup-padding-y: 20px;
          content:
            type: custom:apexcharts-card
            apex_config:
              tooltip:
                x:
                  show: true
                  format: HH:mm dd/MM/yyyy
              xaxis:
                tooltip:
                  enabled: false
            series:
              - entity: sensor.denim_flash_range_in_kilometers
                curve: stepline
                stroke_width: 2
                name: Range
                unit: km
    tap_action:
      action: fire-dom-event
      browser_mod:
        service: browser_mod.popup
        data:
          title: State of Charge History
          style: >
            --popup-min-width: 400px;

            --popup-max-width: 600px;

            --popup-border-width: var(--ha-card-border-width, 2px);

            --popup-border-color: var(--ha-card-border-color,
            var(--divider-color, #eee));

            --popup-border-radius: var(--ha-card-border-radius);

            --popup-background-color: var(--ha-card-background,
            var(--card-background-color, white));

            --popup-padding-x: 1vw;

            --popup-padding-y: 20px;
          content:
            type: custom:apexcharts-card
            apex_config:
              tooltip:
                x:
                  show: true
                  format: HH:mm dd/MM/yyyy
              xaxis:
                tooltip:
                  enabled: false
            series:
              - entity: sensor.denim_flash_state_of_charge
                curve: stepline
                stroke_width: 2
                name: State of Charge
                unit: '%'
    layout: icon_name_state2nd
    entity: sensor.denim_flash_range_in_kilometers
    name: State of Charge
    state_display: |
      [[[
        return states['sensor.denim_flash_state_of_charge'].state+" "+states['sensor.denim_flash_state_of_charge'].attributes.unit_of_measurement;
      ]]]
    styles:
      card:
        - pointer-events: inherit
      custom_fields:
        target_soc:
          - position: absolute
          - bottom: 34px
          - right: 12px
          - box-shadow: none
        ac_charge_speed:
          - position: absolute
          - bottom: 70px
          - right: 12px
          - box-shadow: none
        range:
          - font-size: 3rem
          - font-weight: 200
          - padding-top: 20px
        progress_bar_soc:
          - position: absolute
          - bottom: 20px
          - box-sizing: content-box
          - background-color: var(--label-badge-blue)
          - color: blue
          - font-size: 0px
          - height: 2px
          - width: >-
              [[[return
              "calc("+states['sensor.denim_flash_state_of_charge'].state+"%"+" -
              ("+ states['sensor.denim_flash_state_of_charge'].state /100+"
              *3rem)"]]]
          - z-index: 1
          - margin: 0 1.5rem
          - justify-self: start
        progress_bar_soc_bg:
          - position: absolute
          - bottom: 20px
          - box-sizing: content-box
          - background-color: var(--label-badge-blue)
          - color: blue
          - opacity: 30%
          - font-size: 0px
          - height: 2px
          - width: calc(80% - ( 0.8 * 3rem))
          - margin: 0 1.5rem
          - justify-self: start
        progress_bar_red:
          - position: absolute
          - bottom: 20px
          - box-sizing: content-box
          - background-color: var(--label-badge-red)
          - color: blue
          - opacity: 50%
          - font-size: 0px
          - height: 2px
          - width: calc(20% - ( 0.2 * 3rem))
          - margin: 0 1.5rem
          - justify-self: right
      name:
        - font-size: 0.9em
        - justify-self: start
        - padding-left: 1.5rem
        - margin-top: 0.5rem
      state:
        - font-weight: bold
        - font-size: 1.5rem
        - justify-self: start
        - padding-left: 1.5rem
      entity_picture:
        - width: 90%
        - transform: scaleX(-1)
      grid:
        - grid-template-areas: >-
            "range range range" "i i i" "n n n" "s s s" "progress_bar_soc
            progress_bar_soc_bg progress_bar_soc_bg" "l l l"
        - grid-template-columns: 1fr
        - grid-template-rows: 1fr
        - gap: 10px
    entity_picture: /local/vw_id3.png
    show_entity_picture: true
  - type: vertical-stack
    cards:
      - type: custom:button-card
        tap_action:
          action: toggle
        hold_action:
          action: more-info
        entity: switch.grid
        layout: icon_name_state2nd
        show_state: true
        name: Home Socket
        triggers_update:
          - sensor.denim_flash_plug_power
          - switch.grid
        icon: |
          [[[
            if (entity.state === "on")
              return "mdi:flash";
            else
              return "mdi:flash-off";
          ]]]
        state_display: |
          [[[
            if (entity.state === "on")
              if (states['sensor.denim_flash_plug_power'].state > 0)
                return "On (" + states['sensor.denim_flash_plug_power'].state + " W)";
              else
                return "On";
            else
              return "Off";
          ]]]
        styles:
          name:
            - font-size: 0.9em
          state:
            - font-weight: bold
            - font-size: 1.1em
          icon:
            - width: 20%
          grid:
            - gap: 10px
      - type: conditional
        conditions:
          - entity: sensor.denim_flash_charging_state
            state: charging
        card:
          show_name: true
          show_icon: false
          type: custom:button-card
          custom_fields:
            charge_rate: |
              [[[
                return states['sensor.denim_flash_charge_rate'].state+" "+states['sensor.denim_flash_charge_rate'].attributes.unit_of_measurement
              ]]]
            charge_power: |
              [[[
                return states['sensor.denim_flash_charge_power'].state+" "+states['sensor.denim_flash_charge_power'].attributes.unit_of_measurement
              ]]]
            charge_eta: |
              [[[
                return states['sensor.denim_flash_remaining_charging_time'].state+" "+states['sensor.denim_flash_remaining_charging_time'].attributes.unit_of_measurement
              ]]]
          tap_action:
            action: none
          layout: icon_name_state2nd
          name: Charging
          styles:
            card:
              - pointer-events: inherit
            name:
              - font-size: 0.9em
              - justify-self: center
              - align-self: center
              - text-align: center
              - font-weight: 500
              - font-size: 1.5rem
            grid:
              - grid-template-areas: >-
                  "n n n" "range range range" "i i i" "charge_rate charge_power
                  charge_eta"
              - grid-template-columns: repeat(3, 1fr)
              - grid-template-rows: 1fr
              - gap: 10px
view_layout:
  grid-area: car
card_mod:
  style: |
    hui-vertical-stack-card {
      max-width: 500px;
    }

Button Card Templates

button_card_templates:
  ac_charge_speed:
    variables:
      speed: maximum
      entity: sensor.denim_flash_max_charge_current_ac
      vin: YOUR_VIN
      text_color: var(--primary-text-color)
    name: >-
      [[[ return variables.speed.charAt(0).toUpperCase() +
      variables.speed.slice(1)]]]
    show_name: true
    show_icon: false
    entity: sensor.denim_flash_max_charge_current_ac
    tap_action:
      action: call-service
      service: volkswagen_we_connect_id.volkswagen_id_set_ac_charge_speed
      service_data:
        vin: '[[[ return variables.vin ]]]'
        maximum_reduced: '[[[ return variables.speed ]]]'
    hold_action:
      action: more-info
    state:
      - value: '[[[ return variables.speed ]]]'
        styles:
          name:
            - color: var(--primary-background-color)
          card:
            - background-color: var(--paper-item-icon-active-color)
    styles:
      card:
        - box-shadow: 1px 1px 5px 0px var(--secondary-background-color)
        - padding: 0
        - height: auto
        - padding: 0.85rem 0
      name:
        - color: '[[[ return variables.text_color ]]]'
        - font-weight: bold
        - font-size: 1rem
  soc_target:
    variables:
      target: 50
      text_color: var(--primary-text-color)
    name: '[[[ return variables.target + "%" ]]]'
    show_name: true
    show_icon: false
    entity: number.denim_flash_target_state_of_charge
    tap_action:
      action: call-service
      service: number.set_value
      service_data:
        value: '[[[ return variables.target ]]]'
        entity_id: number.denim_flash_target_state_of_charge
    hold_action:
      action: more-info
    state:
      - value: '[[[ return variables.target ]]]'
        styles:
          name:
            - color: var(--primary-background-color)
          card:
            - background-color: var(--paper-item-icon-active-color)
    styles:
      card:
        - box-shadow: 1px 1px 5px 0px var(--secondary-background-color)
        - height: auto
        - padding: 0.85rem 0
      name:
        - color: '[[[ return variables.text_color ]]]'
        - font-weight: bold
        - font-size: 1rem

To-do:

  • Code cleanup
  • Add AC controls

If you have any feedback or ideas on what I should add, it would be greatly appreciated :slightly_smiling_face:

8 Likes

Hi,

I really like your dashboard, i have an ID.4 myself and started with your dashboard.
One thing i can’t get working and with internet i dont find the solution.

image

Everything works fine, only when i pressing the buttons i get that the template is missing.

I have placed the templates in ui-lovelace.yaml.

Hope you could help me out.

Hey, I’m glad you like the design of the card and I’m sorry it doesn’t work for you yet.
Your could should now look something like this:

button_card_templates:
  ac_charge_speed:
    [...]
  soc_target:
    [...]
views:
  [...]

Does it look like this?

also, did you change these two properties that are in the “tap_action” of ac_charge_speedand soc_target to your own?

Thanks!
Works well now. point was that i did in in the ui-lovelace.yaml, but instead of that in needed to configure it in the raw configuration editor in my dashboard.

Next step is to show the charging card like you have.

1 Like

I have tried to follow the installation procedure for this custom component. This add-on is not recognized by HASS. What goes wrong?

I put the files in the following path:
/usr/share/hassio/homeassistant/custom_components/volkswagen_we_connect_id
whereby configuration.yaml is located in /usr/share/hassio/homeassistant.

I am using HASS supervised system on Raspberry Pi4. Add-on path is /usr/share/hassio/addons

When using HACS, I can not find any repository related to this volkswagen we connect id. What should I do?

Hi Luca, I’m a novice at adding custom cards. I have installed the VW Custom Integration, Button Card and Browser Mod - all seemed successful. I copied your code and pasted it into ui-lovelace.yaml - is that the right place to put it? I also changed YOUR-VIN to the one specific to our car. However, when I try to add a card to the UI I can’t see anything that looks like your card. What might I be doing wrong? Thanks in advance.

Is it possible to automate the “start charging” button to mitigate the infamous bug in the ID software?

thanks

Also having trouble adding this setup to my dashboard.

If anybody can step in and share a few simple instructions I (as well as any other novices that come here) would greatly appreciate it I’m sure.

Thanks in advance!