Skip to content

Home Assistant Custom integration to find and compare public EV charging stations. Get notified when nearest public charging station is available, etc.

License

Notifications You must be signed in to change notification settings

myTselection/EVChargingStations

Repository files navigation

HACS Default GitHub release GitHub repo size

GitHub issues GitHub last commit GitHub commit activity

Public EV Charging Stations Home Assistant integration

Home Assistant custom component to create sensors with information on the available EV Charging Station in a chosen area. This custom component has been built from the ground up to bring public site data to compare and save on your EV prices and integrate this information into Home Assistant. This integration is built against the public websites provided by Eneco.com and other similar sites. Sensors will be created for nearest stations of different speeds and availability.

Currently supporting charging stations in EU from Eneco and Shell.

This integration is in no way affiliated with Eneco.com. This integration is based on my other Carbu.com custom integration, which brings similar functionality for fuel/gas stations.

Large parts of the code base has been based on the Shell Recharge custom integration. The same functionality is available, but has been extended to support Eneco charging stations and to automatically find the stations that matches criteria.

⚠️ Please don't report issues with this integration to other platforms, they will not be able to support you.

For electricity price expectations this Entso-E HACS integration can be used.

With this integration it will be possible to:

  • subscribe to specific charging point, to make it possible to get notified once available
  • get sensors (can be shown on map) with:
    • charging station nearest to location (straight line distance)
    • available charging station nearest to location
    • high speed charging station nearest to location
    • high speed available charging station nearest to location
    • super high speed charging station nearest to location
    • super high speed available charging station nearest to

TODO : find cheapest charging station:

  • cheapest charging stations and nearest to location
  • available cheapest charging stations and nearest to location
  • high speed charging station cheapest and nearest to location
  • high speed available cheapest charging stations and nearest to location
  • super high speed cheapest charging station and nearest to location
  • super high speed available cheapest charging station and nearest to location

Installation

  • HACS: search for Carbu in the default HACS repo list or use below button to navigate directly to it on your local system and install via HACS.
    • Open your Home Assistant instance and open the repository inside the Home Assistant Community Store.
  • Restart Home Assistant
  • Add 'EV Charging Stations' integration via HA Settings > 'Devices and Services' > 'Integrations'
  • Choose the type of charging station to setup: nearest public station, specific station or Shell station with credentials.
  • For 'Public nearest station':
    • Provide any 'origin': this can be a coordinate eg: "51.330436, 3.802043" or "street, city, country" or any sensor name which has latitude and longitutde coordinate attributes eg "person.fred" or "device_tracker.car_position"
  • For 'Public single Shell charge station':
    • Provide the unique serial number of the charging station: the serial number can be found in the details of a charging station on https://ui-map.shellrecharge.com
  • For 'Private Shell charge station':
    • Provide Shell credentials username and password

Setup screenshot

  • setup config

Integration

Sensors

  • sensor.nearest_station_[origin]: sensor with info of nearest charging station

  • sensor.nearest_available_station_[origin]: sensor with info of nearest available charging station

  • sensor.nearest_highspeed_station_[origin]: sensor with info of nearest highspeed charging station (+50kWh)

  • sensor.nearest_available_highspeed_station_[origin]: sensor with info of nearest available highspeed charging station (+50kWh)

  • sensor.nearest_available_superhighspeed_station_[origin]: sensor with info of nearest superhighspeed charging station (+100kWh)

  • sensor.nearest_available_superhighspeed_station_[origin]: sensor with info of nearest available superhighspeed charging station (+100kWh)

  • Sensor attributes
    Attribute Description
    State Status
    name Name of the charging station, ofter referring to the location
    type Type of the charging station, eg nearest_available_superhighspeed_station
    origin Original origin provided during setup of the sensor to find nearest station
    address Address of the charging station
    postal_code Postal code of the charging station
    city City of the charging station
    country Country of the charging station
    latitude Latitude of the charging station
    longitude Longitude of the charging station
    straight_line_distance Approximate straight_line_distance between charging station and set origin, used for selecting nearest station
    route_distance Approximate Waze distance in km between charging station and set origin, NOT used for selecting nearest station, only calculated for selected stations
    route_duration Approximate Waze duration in minutes between charging station and set origin, NOT used for selecting nearest station, only calculated for selected stations
    route_name Approximate straight_line_distance between charging station and set origin
    operator_name Name of the operator of the charging station
    url Direct URL to the Eneco chargemap with details of the charging station
    facilities Facilities available close to the charging station
    avaialbe_connectors Total number of connectors available at the charging station
    number_of_connectors Total number of connectors at the charging station
    max_speed_kWh Max speed connector at the charging station
    min_speed_kWh Min speed connector at the charging station
    is_unlimited Indication if any limitation applies at the charging station
    is_limited Indication if any limitation applies at the charging station
    is_unkown Indication if the charging station is unknown
    allowed Indication if the charging station is allowed for Eneco charging card holders
    external_id External unique technical id of the charging station
    evse_id Functional id of the charging station
    status Status indication of the charging station, any of "AVAILABLE", "CHARGING", "OUTOFORDER", "UNAVAILABLE", "UNKNOWN", "BLOCKED"
    last update Timestamp of latest status info of charging station
    physical_reference Physical reference id of the charging station
    connector_standard Connector standard info of the charging station, eg IEC_62196_T2
    connector_type Connector power type info of the charging station, eg AC_3_PHASE
    connector_format Connector info of the charging station
    connector_max_power Connector info max power in kWh of the charging station, eg 17kWh
    opentwentyfourseven Indication if the charging station is open 24/7, true or false
    charging_costs Price charging cost info of the charging station per Watt of charging or false
    charging_time_costs Price charging cost info of the charging station per minute of charging or false
    start_tariff Price charging cost info of the charging station to start charging session or false
    parking_time_costs Price charging cost info of the charging station for parking during charging or false
    price_description Price charging cost info of the charging station
    map_label Attribute that can be used to show on map, currently showning <available connectors>/<total connectors <max power>kWh

Services / Actions

  • Find the EV Charging Station nearest to a given location and meeting specific criteria.
    • Service find nearest

    • It will return a JSON such as example below:
      
      nearest_station:
        id: 7e71a916-d614-11f0-a74f-42010aa400b8
        name: TNLP030017
        address:
          streetAndHouseNumber: De Ruijterkade 46
          postcode: 1012 AB
          city: Amsterdam
          country: NL
        ownerName: TotalEnergies
        isAllowed: true
        accessType: Public
        isTwentyFourSeven: true
        coordinates:
          lat: 52.38066774
          lng: 4.89748098
        evseSummary:
          total: 5
          available: 4
          maxSpeed: 120000
          minSpeed: 43000
          isUnlimited: true
          isLimited: false
          isUnknown: false
        owner:
          name: TotalEnergies
          website: https://ubitricity.com/nl/bestuurder/
        source: Eneco
        evses:
          - uid: NL-GFX-ETNLP030017-1
            status: AVAILABLE
            evseId: NL*GFX*ETNLP030017*1
            lastUpdated: "2026-01-03T02:52:42+00:00"
            physicalReference: TNLP030017
            connectors:
              - id: "1"
                standard: IEC_62196_T2
                format: SOCKET
                powerType: AC_3_PHASE
                maxPower: 43000
            prices:
              startTariff: 0.39
              chargingCosts: 0.58
              chargingTimeCosts: false
              parkingTimeCosts: false
              description: null
          - uid: NL-GFX-ETNLP030017-2
            status: AVAILABLE
            evseId: NL*GFX*ETNLP030017*2
            lastUpdated: "2026-01-03T20:10:11+00:00"
            physicalReference: TNLP030017
            connectors:
              - id: "2"
                standard: IEC_62196_T2_COMBO
                format: CABLE
                powerType: DC
                maxPower: 50000
            prices:
              startTariff: 0.39
              chargingCosts: 0.8
              chargingTimeCosts: false
              parkingTimeCosts: false
              description: null
          - uid: NL-GFX-ETNLP030017-3
            status: AVAILABLE
            evseId: NL*GFX*ETNLP030017*3
            lastUpdated: "2026-01-03T11:03:27+00:00"
            physicalReference: TNLP030017
            connectors:
              - id: "3"
                standard: CHADEMO
                format: CABLE
                powerType: DC
                maxPower: 50000
            prices:
              startTariff: 0.39
              chargingCosts: 0.8
              chargingTimeCosts: false
              parkingTimeCosts: false
              description: null
          - uid: NL-GFX-ETNLP030018-1
            status: CHARGING
            evseId: NL*GFX*ETNLP030018*1
            lastUpdated: "2026-01-03T20:59:06+00:00"
            physicalReference: TNLP030018
            connectors:
              - id: "1"
                standard: IEC_62196_T2_COMBO
                format: CABLE
                powerType: DC
                maxPower: 120000
            prices:
              startTariff: 0.39
              chargingCosts: 0.8
              chargingTimeCosts: false
              parkingTimeCosts: false
              description: null
          - uid: NL-GFX-ETNLP030018-2
            status: AVAILABLE
            evseId: NL*GFX*ETNLP030018*2
            lastUpdated: "2026-01-03T20:32:52+00:00"
            physicalReference: TNLP030018
            connectors:
              - id: "2"
                standard: IEC_62196_T2_COMBO
                format: CABLE
                powerType: DC
                maxPower: 120000
            prices:
              startTariff: 0.39
              chargingCosts: 0.8
              chargingTimeCosts: false
              parkingTimeCosts: false
              description: null
        facilities:
          - 14a (Public transport)
          - 13a (Public transport)
          - 11a (Public transport)
          - 10a (Public transport)
          - 8a (Public transport)
        straight_line_distance: 0.97
        url: >-
          https://www.eneco-emobility.com/be-nl/chargemap#loc=52.38066774%2C4.89748098%2C17&selected=7e71a916-d614-11f0-a74f-42010aa400b8
        route_distance: 1.29
        route_duration: 4.28
        route_name: Singel Amsterdam
      

Status

Proof of concept status, still validating and extending functionalities. Issues section in GitHub.

Technical pointers

The main logic and API connection related code can be found within source code Carbu.com/custom_components/Carbu.com:

All other files just contain boilerplat code for the integration to work wtihin HA or to have some constants/strings/translations.

If you would encounter some issues with this custom component, you can enable extra debug logging by adding below into your configuration.yaml:

logger:
  default: info
  logs:
     custom_components.EVChargingStations: debug

Example usage: Show map

Nearest map

To show a map in Home Assistant with all nearest charging stations you can use a setup such as shown below. It will show the max kWh charging power on map.

type: map
entities:
  - entity: sensor.nearest_station_device_tracker_car_position
    label_mode: attribute
    attribute: map_label
    focus: false
  - entity: >-
      sensor.nearest_available_station_device_tracker_car_position
    label_mode: attribute
    attribute: map_label
    focus: true
  - entity: >-
      sensor.nearest_highspeed_station_device_tracker_car_position
    label_mode: attribute
    attribute: map_label
    focus: false
  - entity: >-
      sensor.nearest_available_highspeed_station_device_tracker_car_position
    label_mode: attribute
    attribute: map_label
    focus: true
  - entity: >-
      sensor.nearest_superhighspeed_station_device_tracker_car_position
    label_mode: attribute
    attribute: map_label
    focus: false
  - entity: >-
      sensor.nearest_available_superhighspeed_station_device_tracker_car_position
    label_mode: attribute
    attribute: map_label
    focus: true
  - entity: device_tracker.car_position
theme_mode: auto

Eneco map

To show the Eneco charging map for a specific location linked to some sensor in Home Assistant IFrame you can:

  • install Config Template Card HACS

  • define a template sensor to dynamically build the website url based on sensor coordinates

    • in configuration.yaml
    template:
      - sensor:
       - name: "Car Eneco Charging Station URL"
         state: >
           https://www.eneco-emobility.com/be-nl/chargemap#loc={{ state_attr('device_tracker.car_position', 'latitude') }}%2C{{ state_attr('device_tracker.car_position', 'longitude') }}%2C16
    
    
  • create a new card in frontend with config such as shown below:

    type: custom:config-template-card
    entities:
      - sensor.car_eneco_charging_station_url
    variables:
      - states
    card:
      type: iframe
      aspect_ratio: 185%
      url: ${states['sensor.car_eneco_charging_station_url'].state}
    
    

Example info markdown card

Below markdown will only show unique charging stations, so if nearest and nearest available are the same, it will only be shown once.

A link towards Eneco chargemap is available on the name of the charging stations

A link to Google maps directions from car to charging station is available on the address of the charging station

An indication of exepcted speed of charging (km/min and km/hour of charging)

To re-use, replace

  • device_tracker_car_position with origin used during setup of EVChargingStation
  • device_tracker.car_position with entity id or sensor name of your car (or similar)
  • sensor.car_soc with entity id of car battery charge status % SoC
  • person.jef with entity id of person

type: markdown
content: >-
  {% set soc = states('sensor.car_soc') | float(0) %}   
  {% set capacity = states('sensor.car_battery_kwh') | float(83) %}   
  {% set now_ts = now().timestamp() %}  
  {% set consumption = 19 | float %}   
  {% if soc < 10 %}  {% set factor = 0.7 %} 
  {% elif soc < 40 %} {% set factor = 1.0 %}
  {% elif soc < 60 %} {% set factor = 0.8 %}
  {% elif soc < 80 %} {% set factor = 0.5 %}
  {% else %} {% set factor = 0.2 %}
  {% endif %} 

  {% macro calcTime(target, max_power_kw) %} 
  {% set taper_factor = 0.6 %} 
  {% if max_power_kw < 50 %} 
  {% set effective_power = 11.0 %} 
  {% else %} 
  {% set effective_power = max_power_kw %} 
  {% endif %} 
  {% if soc >= target %} Reeds ≥ {{ target }}% 
  {% else %} 
  {# Part 1: from current SOC to min(target,80) at full speed #} 
  {%- set first_limit = [target, 80] | min -%} 
  {%- set pct1 = (first_limit - soc) / 100 if soc < first_limit else 0 -%} 
  {%- set energy1 = capacity * pct1 -%} 
  {%- set time1 = energy1 / effective_power if effective_power > 0 else 0 -%}

  {# Part 2: above 80% at reduced speed #} 
  {%- if target > 80 and soc < target -%} 
  {%- set pct2 = (target - 80) / 100 if soc < 80 else (target - soc) / 100 -%} 
  {%- set energy2 = capacity * pct2 -%} 
  {%- set time2 = energy2 / (effective_power * taper_factor) -%} 
  {%- else -%} {%- set time2 = 0 -%} 
  {%- endif -%}

  {%- set total_h = time1 + time2 -%} 
  {%- set hours = total_h | int -%} 
  {%- set minutes = ((total_h - hours) * 60) | round(0) -%} 
  {%- if minutes >= 60 -%} 
  {%- set hours = hours + (minutes // 60) -%} 
  {%- set minutes = minutes % 60 -%} 
  {%- endif -%} 
  {%- set completion_ts = (now_ts + total_h * 3600) | int -%} till {{target}}%: {{ hours }}h {{ '%02d' % minutes }}m → {{ completion_ts | timestamp_custom('%a %H:%M', true) }}, auto currently at {{soc}}% till max {{capacity}}kWh at {{effective_power}}kWh 
  {% endif %} 
  {% endmacro %}

  {% macro calcSpeed(target, max_power_kw) %} 
  {% if consumption > 0 %} 
  {{(((max_power_kw * factor) / 60) * (100 / consumption))| round(1)}}km/min, {{(((max_power_kw * factor)) * (100 / consumption))| round(0)}}km/h
  {% endif %} 
  {% endmacro %}

  {% macro generateOverview(sensor) %} 
  {% set max_power_kw = state_attr(sensor,'connector_max_power') | float %}
  ({{state_attr(sensor,'route_distance')}}km,
  {{state_attr(sensor,'route_duration')}}min):

  [{{state_attr(sensor,'name')}}]({{state_attr(sensor,'url')}})

  > 🗺️[{{state_attr(sensor,'address')}}, {{state_attr(sensor,'postal_code')}}
  {{state_attr(sensor,'city')}}](https://www.google.com/maps/dir/?api=1&origin={{state_attr('person.jef','latitude')}},{{state_attr('person.jef','longitude')}}&destination={{state_attr(sensor,'latitude')}},{{state_attr(sensor,'longitude')}}&travelmode=driving)

  {{state_attr(sensor,'connector_max_power')}}kWh,
  {{state_attr(sensor,'available_connectors')}}/{{state_attr(sensor,'number_of_connectors')}}
  available 

  {{ calcSpeed(80, max_power_kw) }} 

  {{ calcTime(80, max_power_kw) }} 

  {{ calcTime(100, max_power_kw) }}

  {{state_attr(sensor,'facilities')}} 
  {% endmacro %}

  # Charging stations around person.jef


  ### Nearest available      
  {{ generateOverview('sensor.nearest_available_station_person_jef') }}


  {% if state_attr('sensor.nearest_station_person_jef','external_id') !=
  state_attr('sensor.nearest_available_station_person_jef','external_id') %}

  ### Nearest  
  {{ generateOverview('sensor.nearest_station_person_jef') }}

  {% endif %}



  {% if state_attr('sensor.nearest_available_station_person_jef','external_id') != state_attr('sensor.nearest_available_highspeed_station_person_jef','external_id') %}

  ### Highspeed nearest available  {{
  generateOverview('sensor.nearest_available_highspeed_station_person_jef') }}

  {% endif %}

  {% if state_attr('sensor.nearest_highspeed_station_person_jef','external_id') != state_attr('sensor.nearest_available_highspeed_station_person_jef','external_id') %}

  ### Highspeed
  {{ generateOverview('sensor.nearest_highspeed_station_person_jef')}} 
  {% endif %}



  {% if state_attr('sensor.nearest_available_superhighspeed_station_person_jef','external_id') != state_attr('sensor.nearest_available_highspeed_station_person_jef','external_id')
  and state_attr('sensor.nearest_available_station_person_jef','external_id') !=
  state_attr('sensor.nearest_available_superhighspeed_station_person_jef','external_id')%}

  ### Super highspeed available  
  {{ generateOverview('sensor.nearest_available_superhighspeed_station_person_jef') }}

  {% endif %}

  {% if state_attr('sensor.nearest_superhighspeed_station_person_jef','external_id') !=
  state_attr('sensor.nearest_available_superhighspeed_station_person_jef','external_id')
  and
  state_attr('sensor.nearest_available_superhighspeed_station_person_jef','external_id')!=
  state_attr('sensor.nearest_available_highspeed_station_person_jef','external_id')
  %}

  ### Super highspeed
  {{ generateOverview('sensor.nearest_superhighspeed_station_person_jef') }}

  {% endif %}
grid_options:
  columns: full




About

Home Assistant Custom integration to find and compare public EV charging stations. Get notified when nearest public charging station is available, etc.

Topics

Resources

License

Stars

Watchers

Forks

Languages