Status of EnBW charging stations

I have an electric car and configured it within Home Assistant.
For Hyundai and Kia you can use the ‘Hyundai-Kia-Connect’ :

https://github.com/Hyundai-Kia-Connect/hyundai_kia_connect_api

With the above sensors it’s possible to create automations like :

When car battery is under 41% and you enter your zone (like home address) notify which of your added charge stations are available. Offcourse from favorite to least favorite.

alias: Availability My Charging Stations
description: ""
trigger:
  - platform: device
    device_id: **mycar**
    domain: device_tracker
    entity_id: **mycar**
    type: enters
    zone: zone.**myzone**
condition:
  - type: is_battery_level
    condition: device
    device_id: **mycar**
    entity_id: **mycar**
    domain: sensor
    below: 41
  - type: is_not_plugged_in
    condition: device
    device_id: **mycar**
    entity_id: **mycar**
    domain: binary_sensor
action:
  - if:
      - condition: numeric_state
        entity_id: sensor.oplaadstation_**address1**_vrije_laadpalen
        above: 0
    then:
      - device_id: **mymobile**
        domain: mobile_app
        type: notify
        message: Oplaadstation **address1** beschikbaar.
        title: Oplaadstation **address1** beschikbaar!
    else:
      - if:
          - condition: numeric_state
            entity_id: sensor.oplaadstation_**address2**_vrije_laadpalen
            above: 0
        then:
          - device_id: **mymobile**
            domain: mobile_app
            type: notify
            message: >-
              Oplaadstation **address2** beschikbaar. Oplaadstation **address1** bezet.
            title: **address2** beschikbaar!
        else:
          - if:
              - condition: numeric_state
                entity_id: sensor.oplaadstation_**address3**_vrije_laadpalen
                above: 0
            then:
              - device_id: **mymobile**
                domain: mobile_app
                type: notify
                message: >-
                  Oplaadstation **address3** beschikbaar. Oplaadstations **address1** en **address2** bezet.
                title: Oplaadstation **address3** beschikbaar!
            else:
              - device_id: **mymobile**
                domain: mobile_app
                type: notify
                message: >-
                  Oplaadstations **address1**, **address2** en
                  **address3** bezet.
                title: Oplaadstations niet beschikbaar!
mode: single
1 Like

How do you deal with the fact that the URL (the last two characters) changes every day?

Hey aschrand,

The last 2 digits do not change, I have set this up months ago and it’s still working.

Why do you think the last 2 digits change each time?

Gr.

NB.

I have tested the new Google Places v2 API and it shows the status of the charge station but not per charge point.

I have created a script to gather API keys from the internet and test the API codes if the API is working. There is no API found that has the Placesv2 enabled, or has valid permissions. If you create an account at ‘https://console.cloud.google.com/’ and enable the Placesv2 API then you have your own API key. Remember to set permissions!

PowerShell code for this is :

Function GetPlacesv2SearchNearBy ($Location,$Radius,$IncludedTypes,$MaxResults,$MapsAPIKey){
  $Error.Clear()
    Try{
      $Uri='https://maps.googleapis.com/maps/api/geocode/json?key='+$MapsAPIKey;$Json=Invoke-WebRequest $Uri -Body @{address=$Location} -UseBasicParsing|ConvertFrom-Json|Select -ExpandProperty results
      $Body='{
        "includedTypes": ["'+$IncludedTypes+'"],
        "maxResultCount":'+$MaxResults+',
        "locationRestriction": {
          "circle": {
            "center": {
              "latitude":'+$Json.geometry.location.lat+',
              "longitude":'+$Json.geometry.location.lng+'
            },
            "radius":'+$Radius+'
          }
        }
      }'
      $XGoogFieldMask="places.evChargeOptions"
      $Uri="https://places.googleapis.com/v1/places:searchNearby"
      Invoke-WebRequest $Uri -Method POST -Body $Body -Headers @{"X-Goog-FieldMask"=$XGoogFieldMask;"X-Goog-Api-Key"=$MapsAPIKey;"Content-Type"="application/json"}|ConvertFrom-Json|Select -ExpandProperty places|Select -ExpandProperty evChargeOptions|Select -ExpandProperty connectorAggregation
    }Catch{}
}

$Location='YOUR ADDRESS'
$Radius='500' #meters
$InludedTypes='electric_vehicle_charging_station'
$MaxResults='5'
$MapsAPIKey='YOUR MAPS API KEY'
GetPlacesv2SearchNearby $Location $Radius $IncludedTypes $MaxResults $MapsAPIKey

If the key is changing each day then I would scriptmatic gather the key online each time that the script executes. But there is no need because the key doesn’t change.

And for the lovers my whole script :

For scriptmatic Google Search there is an expensive API needed. I have a workaround to get the keys from the browser cache. Script is not perfect, but works great. Save it as a PowerShell script (scriptname.ps1).

It assumes you have Edge installed and get the cache from each profile.
Download this: ChromeCacheView - Cache viewer for Google Chrome Web browser
Rename the executable as ‘EdgeCacheView.exe’ and place it in the same folder where the script is. Success.


Screenshot 2024-01-13 183813

# Documentation : https://developers.google.com/maps/documentation/directions
Function GetDistance($Start,$End,$MapsAPIKey){
  Try{
      $Uri='https://maps.googleapis.com/maps/api/directions/json?&key='+$MapsAPIKey
      $Body=@{'origin'=$Start;'destination'=$End}
      $Json=Invoke-WebRequest $Uri -UseBasicParsing -Body $Body | ConvertFrom-Json
      $Json.routes.legs.duration.text
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/geocoding/start
Function GetGeoLocation ($Location,$MapsAPIKey){
  $Error.Clear()
    Try{
      $Uri='https://maps.googleapis.com/maps/api/geocode/json?key='+$MapsAPIKey
      Invoke-WebRequest $Uri -Body @{address=$Location} -UseBasicParsing|ConvertFrom-Json|Select -ExpandProperty results
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/places/web-service/search-nearby
Function GetNearbyPlacesFromCoordinates ($Lat,$Lng,$MapsAPIKey){
  $Error.Clear()
    Try{
      $Uri='https://maps.googleapis.com/maps/api/place/nearbysearch/json?location='+$Lat+','+$Lng+'&radius=500&keyword=electric_vehicle_charging_station&key='+$MapsAPIKey
      Invoke-WebRequest $Uri -UseBasicParsing| ConvertFrom-Json|Select -ExpandProperty results|Select -ExpandProperty vicinity
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/timezone/overview
Function GetTimeZone ($Location,$MapsAPIKey) {
  $Error.Clear()
    Try{
      $Json=GetGeoLocation $Location $MapsAPIKey
      $Coordinates=($Json.geometry.location.lat,$Json.geometry.location.lng) -Join(',')
      $TimeStamp=[int]((Get-Date)-(Get-Date "January 1, 1970")).TotalSeconds
      $Uri='https://maps.googleapis.com/maps/api/timezone/json?location='+$Coordinates+'&timestamp='+$TimeStamp+'&key='+$MapsAPIKey
      (Invoke-WebRequest $Uri -UseBasicParsing|ConvertFrom-Json).timeZoneName
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/distance-matrix/distance-matrix
Function GetNearbyPlacesFromLocation ($Location,$Radius,$Keyword,$MapsAPIKey) {
  $Error.Clear()
    Try{
      $Json=GetGeoLocation $Location $MapsAPIKey
      $Coordinates=($Json.geometry.location.lat,$Json.geometry.location.lng) -Join(',')
      $Uri='https://maps.googleapis.com/maps/api/place/nearbysearch/json?location='+$Coordinates+'&radius='+$Radius+'&keyword='+$Keyword+'&key='+$MapsAPIKey
      Invoke-WebRequest $Uri -UseBasicParsing|ConvertFrom-Json|Select -ExpandProperty results|Select -ExpandProperty vicinity
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/places/web-service/search-text
Function GetNearbyPlacesFromText ($Location,$Radius,$Query,$MapsAPIKey) {
  $Error.Clear()
    Try{
      $Json=GetGeoLocation $Location $MapsAPIKey
      $Coordinates=($Json.geometry.location.lat,$Json.geometry.location.lng) -Join(',')
      $Uri='https://maps.googleapis.com/maps/api/place/textsearch/json?location='+$Coordinates+'&radius='+$Radius+'&query='+$Query+'&key='+$MapsAPIKey
      Invoke-WebRequest $Uri -UseBasicParsing|ConvertFrom-Json|Select -ExpandProperty results|Select -ExpandProperty name
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/distance-matrix
Function GetDistanceMatrix ($Location,$Destination,$TravelType,$MapsAPIKey) {
  $Error.Clear()
    Try{
      $Uri='https://maps.googleapis.com/maps/api/distancematrix/json?origins='+$Location+'&destinations='+$Destination+'&mode='+$TravelType.ToLower()+'&key='+$MapsAPIKey
      $Json=Invoke-WebRequest $Uri -UseBasicParsing|ConvertFrom-Json
      $DistanceMatrix=($Json.Rows.elements.distance.text,$Json.Rows.elements.duration.text) -Join(', ')
      $DistanceMatrix+" "+$TravelType
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/geolocation/overview
Function GetMyLocation ($MapsAPIKey) {
  $Error.Clear()
    Try{
      $MacAddress=netsh wlan show networks mode=Bssid | Where-Object{$_ -like "*BSSID*"} | %{($_.split(" ")[-1]).toupper()}
      If(!($MacAddress)){Write-Host "Niet verbonden met Wi-Fi";Break}
      $Uri='https://www.googleapis.com/geolocation/v1/geolocate?key='+$MapsAPIKey
      $Body=@{wifiAccessPoints=@{macAddress=$($MacAddress[0])},@{macAddress = $($MacAddress[1])}}|ConvertTo-Json
      $Json=Invoke-WebRequest $Uri -Method POST -Body $Body -UseBasicParsing|ConvertFrom-Json
      $Coordinates=($Json.location.lat,$Json.location.lng) -Join(',')
      ((GetGeoLocation $Coordinates $MapsAPIKey).formatted_address)[1..3] -Join('; ')
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/directions
#                 https://developers.google.com/maps/documentation/directions/get-directions
Function GetChargeStationsSortByDuration ($Location,$Radius,$TravelType,$MaxResults,$MapsAPIKey) {
  $Error.Clear()
    Try{
    $Destinations=GetNearbyPlacesFromLocation $Location $Radius "Charge" $MapsAPIKey
    $ChargePoints=[System.Collections.Generic.List[pscustomobject]]::new()
      ForEach($Destination in $Destinations){
        $GeoDirectionsAPI='https://maps.googleapis.com/maps/api/directions/json?origin='+$Location+'&destination='+$Destination+'&mode='+$TravelType.ToLower()+'&key='+$MapsAPIKey
        $JsonGeoDirectionsAPI=invoke-webrequest $GeoDirectionsAPI -Method Get|Select -ExpandProperty Content|ConvertFrom-Json
          ForEach($D in $JsonGeoDirectionsAPI){
            $duration_in_seconds=[int]$D.routes.legs.duration.value
            $duration_text=$D.routes.legs.duration.text
            $distance_in_meters=[int]$D.routes.legs.distance.value
            $distance_text=$D.routes.legs.distance.text
            $address=$D.routes.legs.end_address
            $ChargePoints.Add([pscustomobject]@{
              'address'=$address
              'duration_in_seconds'=$duration_in_seconds
              'duration_displayname'=$duration_text
              'distance_in_meters'=$distance_in_meters
              'distance_displayname'=$distance_text
            })
          }
      }
      $ChargePoints|sort duration_in_seconds|Select * -First $MaxResults -ExpandProperty address
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/solar
Function GetSolar ($lat,$Lng,$Quality,$MapsAPIKey) {
  $Error.Clear()
    Try{
      $Uri='https://solar.googleapis.com/v1/buildingInsights:findClosest?location.latitude='+$Lat+'&location.longitude='+$Lng+'&requiredQuality='+$Quality.ToUpper()+'&key='+$MapsAPIKey
      Invoke-WebRequest $Uri -UseBasicParsing|ConvertFrom-Json
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/address-validation
Function ValidateAddress ($MapsAPIKey) {
  $Error.Clear()
    Try{
      $Headers=@{'Content-Type'='application/json'}
      $Body=@{'address'= @{'regioCode'='US';'addressLines'='1600 Amphitheatre Pkwy','Mountain view, CA, 94043'}}|ConvertTo-JSon
      $Uri='https://addressvalidation.googleapis.com/v1:validateAddress?key='+$MapsAPIKey
      Invoke-WebRequest $Uri -Method POST -Body $Body -Headers $Headers|ConvertFrom-Json
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/streetview
#                 https://developers.google.com/maps/documentation/streetview/request-streetview
Function StreetView ($Location, $MapsAPIKey){
  $Error.Clear()
    Try{
      $Size='3840x2160'
      If($Location-match', '){
        $Location=$Location -Split(', ')
        $Location[0]=$Location[0] -Replace(' ','+')
        $Location[1]=$Location[1] -Replace(' ','+')
        $Location=$Location[0]+','+$Location[1]
      }Else{$Location -Replace(' ','+')}
      $Uri='https://maps.googleapis.com/maps/api/streetview/metadata?location='+$Location+'&key='+$MapsAPIKey
      $PanoId=(Invoke-WebRequest $Uri -UseBasicParsing|ConvertFrom-Json).pano_id
      $PanoIdLat=(Invoke-WebRequest $Uri -UseBasicParsing|ConvertFrom-Json).location.lat
      $PanoIdLng=(Invoke-WebRequest $Uri -UseBasicParsing|ConvertFrom-Json).location.lng
      If($PanoId){
        $Uri='https://maps.googleapis.com/maps/api/streetview?size='+$Size+'&location='+$PanoIdLat+','+$PanoIdLng+'&key='+$MapsAPIKey
      }Else{
        $Uri='https://maps.googleapis.com/maps/api/streetview?size='+$Size+'&location='+$Location+'&key='+$MapsAPIKey
      }
      Invoke-WebRequest $Uri -UseBasicParsing
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/tile/2d-tiles-overview
Function GetStreetView2DTiles ($Lat,$Lng,$Radius,$MapsAPIKey) {
  $Error.Clear()
    Try{
      $Uri='https://tile.googleapis.com/v1/3dtiles/root.json?key='+$MapsAPIKey
      Invoke-WebRequest $Uri -UseBasicParsing
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/tile/3d-tiles-overview
Function GetStreetView3DTiles ($MapsAPIKey) {
  $Error.Clear()
    Try{
      $Uri='https://tile.googleapis.com/v1/3dtiles/root.json?key='+$MapsAPIKey
      Invoke-WebRequest $Uri -UseBasicParsing
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/pollen
Function GetPollen ($Lat,$Lng,$Days,$MapsAPIKey) {
  $Error.Clear()
    Try{
      $Uri='https://pollen.googleapis.com/v1/forecast:lookup?key='+$MapsAPIKey+'&location.longitude='+$Lng+'&location.latitude='+$Lat+'&days='+$Days
      Invoke-WebRequest $Uri -UseBasicParsing
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/air-quality/heatmaps
Function GetAirQualityHeatMapTiles ($MapsAPIKey) {
  $Error.Clear()
    Try{
      $Uri='https://airquality.googleapis.com/v1/mapTypes/UAQI_INDIGO_PERSIAN/heatmapTiles/0/0/0?key='+$MapsAPIKey
      Invoke-WebRequest $Uri -ContentType 'application/json' -UseBasicParsing
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/air-quality/history
Function GetAirQualityHistory ($MapsAPIKey) {
  $Error.Clear()
    Try{
      $Uri='https://maps.googleapis.com/maps/api/geocode/json?key='+$MapsAPIKey;$Json=Invoke-WebRequest $Uri -Body @{address=$Location} -UseBasicParsing|ConvertFrom-Json|Select -ExpandProperty results
      $Body='{
        "hours": 4,
        "pageSize": 2,
        "pageToken":"",
          "location": {
            "latitude":'+$Json.geometry.location.lat+',
            "longitude":'+$Json.geometry.location.lng+'
        }
      }'
      $Uri='https://airquality.googleapis.com/v1/history:lookup?key='+$MapsAPIKey
      Invoke-WebRequest $Uri -Body $Body -Method POST -ContentType 'application/json' -UseBasicParsing|ConvertFrom-Json
    }Catch{}
}

Function GoogleSearch ($Keyword,$EndCount){
$Error.Clear()
    Try{
      $Pages=1
      $Count=1
        Do {
            Write-Host "Pagina : "$Count"/"$EndCount
            $Keyword=$Keyword -Replace(' ','+')
            $Uri='https://www.google.nl/search?q='+$Keyword+'&start='+$Pages
            Start-Process $Uri -Wait
            $Count++
            $Pages=$Pages+10
        } While ($Count-le$EndCount)
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/elevation/overview
Function GetElevation ($Lat,$Lng,$MapsAPIKey) {
  $Error.Clear()
    Try{
      $Uri='https://maps.googleapis.com/maps/api/elevation/json?locations='+$Lat+'%2C'+$Lng+'&key='+$MapsAPIKey
      Invoke-WebRequest $Uri -UseBasicParsing|ConvertFrom-Json|Select -ExpandProperty results
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/aerial-view
Function GetAerialView ($Location,$MapsAPIKey) {
  $Error.Clear()
    Try{
      $Location="500 W 2nd St, Austin, TX 78701"
        $Body='{
          "address":"'+$Location+'"
        }'
      $Uri="https://aerialview.googleapis.com/v1/videos:renderVideo?key="+$MapsAPIKey
      Invoke-WebRequest $Uri -UseBasicParsing -Method POST -Body $Body -ContentType 'application/json'|ConvertFrom-Json
    }Catch{}
}

# Documentation : https://developers.google.com/maps/documentation/tile/session_tokens
Function GetTileCreateSession ($MapsAPIKey) {
  $Error.Clear()
    Try{
      $Body=@{
        'mapType'='streetview'
        'language'='en-US'
        'region'='US'
      }|ConvertTo-Json
      $Headers=@{
        'Content-Type'='application/json'
      }
      $Uri='https://tile.googleapis.com/v1/createSession?key='+$MapsAPIKey
      Invoke-WebRequest $Uri -Body $Body -Headers $Headers -Method POST
    }Catch{}
}

Function GetPlacesv2SearchNearBy ($Location,$Radius,$IncludedTypes,$MaxResults,$MapsAPIKey){
  $Error.Clear()
    Try{
      $Uri='https://maps.googleapis.com/maps/api/geocode/json?key='+$MapsAPIKey;$Json=Invoke-WebRequest $Uri -Body @{address=$Location} -UseBasicParsing|ConvertFrom-Json|Select -ExpandProperty results
      $Body='{
        "includedTypes": ["'+$IncludedTypes+'"],
        "maxResultCount":'+$MaxResults+',
        "locationRestriction": {
          "circle": {
            "center": {
              "latitude":'+$Json.geometry.location.lat+',
              "longitude":'+$Json.geometry.location.lng+'
            },
            "radius":'+$Radius+'
          }
        }
      }'
      $Headers=@{"X-Goog-FieldMask"="*";"X-Goog-Api-Key"=$MapsAPIKey;"Content-Type"="application/json"}
      $Uri="https://places.googleapis.com/v1/places:searchNearby"
      Invoke-WebRequest $Uri -Method POST -Body $Body -Headers $Headers|ConvertFrom-Json|Select -ExpandProperty places
    }Catch{}
}

$NewLine=[Environment]::NewLine;Clear-Host;Add-Type -AssemblyName PresentationCore,PresentationFramework;$ButtonType=[System.Windows.MessageBoxButton]::YesNo;$MessageIcon=[System.Windows.MessageBoxImage]::Error;$MessageBody="Wil je zoeken in Google?";$MessageTitle="GoogleSearch"
$Result=[System.Windows.MessageBox]::Show($MessageBody,$MessageTitle,$ButtonType,$MessageIcon);If($Result-eq'Yes'){[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic');$Title='GoogleSearch';$Msg="Voer zoekterm(en) in :`n`nVoorbeeld zoektermen : `nStreetView`nAirQuality`nAerialView`nSolar`nPollen`nDistanceMatrix`nTimeZone`nGeoLocation`nPlaces`nElevation";$Keyword=[Microsoft.VisualBasic.Interaction]::InputBox($Msg,$Title);$Title='GoogleSearch';$Msg="Hoeveel webpagina's moeten weergeven worden?`n`nWebpagina bevat 10 website resultaten.`nBij geen opgegeven waarde is default 1.";$Count=[Microsoft.VisualBasic.Interaction]::InputBox($Msg,$Title);If($Count-eq""){$Count=1};GoogleSearch $Keyword $Count}
$ScriptPath=(Split-Path ($MyInvocation.MyCommand.Path) -Parent)+'\';$Executable="EdgeCacheView.exe";If(!($Executable)){Write-host "Executable "+$Executable+" not found!";Break};$EdgeProfileFolder=$Env:LOCALAPPDATA+"\Microsoft\Edge\User Data\";If(!($EdgeProfileFolder)){Write-Host "Edge profile base folder not found!";Break};$EdgeProfileFolderNames=(Get-Item "HKCU:\Software\Microsoft\Edge\Profiles\*").PSChildName;If(!($EdgeProfileFolderNames)){Write-Host "Edge Profiles not found";Break}
$ExportRAW=$ScriptPath+$Executable.Replace(".exe",".txt");Remove-Item $ExportRAW -Force -ErrorAction SilentlyContinue;ForEach($EdgeProfileFolderName in $EdgeProfileFolderNames){$EdgeProfile=$EdgeProfileFolder+$EdgeProfileFolderName+'/Cache/Cache_Data/';$Arguments="-folder ""$EdgeProfile"" /sText ""$ExportRaw""";Start-Process -FilePath "$ScriptPath$Executable" -ArgumentList $Arguments -Wait}
Clear-Host;$MapsAPIKeys=$(ForEach($Line in Get-Content $ExportRaw){$Begin='AIzaSy';$APILength="39";If($Line-match$Begin){$Length=($line.SubString($Line.IndexOf($Begin))).Length;If($Length-ge$APILength){$Line.SubString(($Line.IndexOf($Begin)),$APILength)}}})|Sort-Object|Get-Unique
$Temp=New-TemporaryFile;$ExportToCSV=$ScriptPath+($Executable -Replace('exe','csv'));$OldKeyCount=0;If(Test-Path $ExportToCSV){$ExportToCSVContent=Get-Content $ExportToCSV|ConvertFrom-CSV;$OldKeys=$ExportToCSVContent|Select -Exp APIKey;$OldKeysCount=($ExportToCSVContent|Select -Exp APIKey).Count}
$OldKeys|Out-File $Temp;$MapsAPIKeys|Out-File $Temp -Ap;$AllKeys=Get-Content $Temp|Sort|Get-Unique;$TotalKeys=$AllKeys.Count;$NewKeys=@();ForEach($Key in $MapsAPIKeys){If(!($OldKeys-contains$Key)){$NewKeys+=$Key}};$Count=0;$Enum=@()

    $DumpCount=0
    ForEach($MapsAPIKey in $NewKeys){

      $Count++;Write-Host $Count "/" $NewKeys.count " - total: " $TotalKeys
      $Location='YOUR ADDRESS'
      $Destination='DESTINATION ADDRESS'
      $Radius='500'
      $KeyWordChargeStation='charge station'
      $TravelType='Walking'
      $MaxResults='1'
      $Query='Restaurant'
      $Days='5'
      $Lat='LATITUDE OF YOUR LOCATION'
      $Lng='LONGITUDE OF YOUR LOCATION'
      $Quality='HIGH'
      $IncludedTypes="electric_vehicle_charging_station"
      $LatforSolar='52.0590358' # Bogus, doesn't work with latitude of my location
      $LngforSolar='4.2716786' # Bogus, doesn't work with longitude of my location

      $GetGeoLocation=GetGeoLocation $Location $MapsAPIKey|Select -ExpandProperty formatted_address
      $Error.Clear();Try{$GetNearbyPlacesFromLocation=(GetNearbyPlacesFromLocation $Location $Radius $KeywordChargetation $MAPSAPIKey)[0]}Catch{}
      $GetTimeZone=GetTimeZone $Location $MapsAPIKey
      $GetDistanceMatrix=GetDistanceMatrix $Location $Destination $TravelType $MapsAPIKey
      $GetMyLocation=GetMyLocation $MapsAPIKey
      $GetChargeStationsSortByDuration=GetChargeStationsSortByDuration $Location $Radius $TravelType $MaxResults $MapsAPIKey
      $Error.Clear();Try{$GetNearByPlacesFromText=(GetNearByPlacesFromText $Location $Radius $QUery $MapsAPIKey)[0]}Catch{}
      $GetPollen=GetPollen $Lat $Lng $Days $MapsAPIKey
      $GetAirQualityHistory=GetAirQualityHistory $MapsAPIKey 
      $GetAirQualityHeatMapTiles=GetAirQualityHeatMapTiles $MapsAPIKey
      $GetSolar=GetSolar $LatforSolar $LngforSolar $Quality $MapsAPIKey
      $GetElevation=GetElevation $Lat $Lng $MapsAPIKey
      $GetAerialView=GetAerialView $Location $MapsAPIKey
      $GetTileCreateSession=GetTileCreateSession $MapsAPIKey
      $GetStreetView2DTiles=GetStreetView2DTiles $Lat $Lng $Radius $MapsAPIKey
      $GetStreetView3DTiles=GetStreetView3DTiles $MapsAPIKey
      $StreetView=StreetView $Location $MapsAPIKey
      $GetPlacesv2SearchNearBy=GetPlacesv2SearchNearBy $Location $Radius $IncludedTypes $MaxResults $MapsAPIKey

      $A=New-Object PSObject
      $A|Add-Member NoteProperty "APIKey" $MapsAPIKey
      If($GetChargeStationsSortByDuration){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Directions,ChargeStationsByDuration' $B
      If($GetGeoLocation){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Geolocation' $B
      If($GetNearbyPlacesFromLocation){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Placesv1,SearchFromLocation' $B 
      If($GetTimeZone){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Timezone' $B 
      If($GetDistanceMatrix-ne', Walking'){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'DistanceMatrix' $B 
      If($GetMyLocation){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'My Location' $B 
      If($GetNearByPlacesFromText){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Placesv1,NearbyFromText' $B
      If($GetElevation){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Elevation' $B
      If($GetPlacesv2SearchNearBy){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Placesv2,SearchNearby' $B 
      If($GetPollen){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Pollen' $B 
      If($GetAirQualityHistory){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'AirQualityHistory' $B 
      If($GetAirQualityHeatMapTiles){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'AirQualityHeatMapTiles' $B 
      If($GetSolar){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Solar' $B 
      If($GetAerialView){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'AerialView' $B 
      If($GetTileCreateSession){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Tile,CreateSession' $B 
      If($GetStreetView2DTiles){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Streetview,2DTiles' $B
      If($GetStreetView3DTiles){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Streetview,3DTiles' $B
      If($StreetView){$B="Yes"}Else{$B=" "};$A|Add-Member NoteProperty 'Streetview' $B

      $Enum+=$A
      $DumpCount++
      If($DumpCount-eq10){
        $Enum|Export-CSV $ExportToCSV -NoTypeInformation -Ap
        $Enum=@();$DumpCount=0
        Write-Host "`n Dump naar "$ExportToCSV "`n"
      }

    }
  Write-Host "Total keys " $TotalKeys
  $Enum|Export-CSV $ExportToCSV -NoTypeInformation -Ap
  Remove-Item $ExportRAW -Fo -ErrorA SilentlyContinue;Remove-Item $Temp -Fo -ErrorA SilentlyContinue

I used @MaxW 's post as an example for my own closeby charge points. I used the
Ocp-Apim-Subscription-Key from that charging point, but everything is offline and not available. What is going wrong? This is very helpful in my battle to get a free charging point after work :wink:

thank you for the extensive guide. yet it fails me to integrate it correctly in my HA instance.

WORKING >

sensor:
  - platform: rest
    name: "Laadpaal XXX Links"
    unique_id: sensor.laadpaal_XXX_links
    resource: https://enbw-emp.azure-api.net/emobility-public-api/api/v1/chargestations/XXXXXX
    headers:
      User-Agent: "Home Assistant"
      Ocp-Apim-Subscription-Key: XXXX
      Referer: 'https://www.enbw.com/'
      Origin: 'https://www.enbw.com'
    value_template: >-
      {% set LP = value_json.chargePoints | selectattr('evseId','eq','NL*GFX*ETNLP00XXXX*1') | map(attribute='status') | first  %}
      {% if LP == "OCCUPIED" %} Bezet
      {% elif LP == "AVAILABLE" %} 🅿
      {% elif LP == "OUT_OF_SERVICE" %} ❌
      {% else %} "{{ LP }}"
      {% endif %} 

I have the connectivity with EnBW working when configured from the configuration.yaml itself. However now I also want to seperate it into yaml files in the REST folder. What is wrong with my setup? Could you provide some feedback?

NOT WORKING >
Configuration yaml file

rest: !include_dir_merge_list REST/

REST folder / yaml file

- scan_interval: 60
  resource: !secret enwb_api_uri_XXX
  headers:
    User-Agent: "Home Assistant"
    Ocp-Apim-Subscription-Key: !secret enwb_subscription_key
    Origin: !secret enwb_origin
    Referer: !secret enwb_referer
  sensor:
    - name: "Laadpaal XXX ALTERNATIEF L"
      unique_id: "sensor.laadpaal_alternatief_l"
      value_template: "{{ (value_json.chargePoints | selectattr('evseId','eq','NL*GFX*ETNLP00XXXX*1') | first).status|replace('_',' ')|lower|replace('occupied','❌')|replace('available','🅿️')|replace('out of service','❌')|capitalize }}"
    - name: "Laadpaal XXX ALTERNATIEF R"
      unique_id: "sensor.laadpaal_alternatief_R"
      value_template: "{{ (value_json.chargePoints | selectattr('evseId','eq','NL*GFX*ETNLP00XXXX*2') | first).status|replace('_',' ')|lower|replace('occupied','❌')|replace('available','🅿️')|replace('out of service','❌')|capitalize }}"

somehow i have the feeling i miss a line with ‘platform’ category…

Thank you

cause of 2nd config : secrets do not get populated correctly somehow.

Hi,

I used the code from MaxW to set everything up. It is working fine so far.
Now I would also like to change the color of the icon depending on the state of the sensor.

I‘m using a Mushroom-Entity card and tried to implement this according to following code:

             - type: custom:mushroom-entity-card
                entity: sensor.industriestrasse_ladepunkt_2
                name: '2'
                icon: phu:charging-station
                card_mod:
                  style: |-
                    ha-state-icon {

                      color:

                      {% if is_state('sensor.industriestrasse_ladepunkt_2', 'AVAILABLE') %}
                        green
                      {% elif is_state('sensor.industriestrasse_ladepunkt_2', '🚘')
                      %}
                        orange
                      {% elif is_state('sensor.industriestrasse_ladepunkt_2', '❌')
                      %}
                        red
                      {% else %}
                        blue
                      {% endif %}                 

                     }             

… but somehow color is not changing. Can anyone help to implement this? Thanks in advance!

Edit: icons as status seemed to be problematic. I now took (copied) them directly from each single entity and now it works

Great stuff!

Just decided to create an integration for it. Let me know what you think!
https://github.com/mKenfenheuer/enbw_chargestations

1 Like

Hi,

great idea and work! I assume I have to first remove the senors entry from the configuration.yaml before trying your ingegration, correct?

cheers!

How do I aquire the Enbw API key?

Content-Length: 152
Content-Type: application/json
Date: Sun, 01 Dec 2024 20:56:13 GMT
Request-Context: appId=cid-v1:a29f0fa5-36d1-4c05-9ca1-2314217687aa
WWW-Authenticate: AzureApiManagementKey realm="https://enbw-emp.azure-api.net/emobility-public-api",name="Ocp-Apim-Subscription-Key",type="header"

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
DNT: 1
Host: enbw-emp.azure-api.net
Priority: u=0, i
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: cross-site
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0

I see the message:

Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API

Did you read the first post?

I did. Sorry if my issue description was not detailed enough. As you can see in the development tools, I searched for the term
https://enbw-emp.azure-api.net/emobility-public-api/api/v1/chargestations/
and it gives me two requests. When I click them, I get the message:
"

Ok interestingly it worked on Chromium. Sorry for the trouble.